def Run(self, args): """Connect to a running flex instance. Args: args: argparse.Namespace, the args the command was invoked with. Raises: InvalidInstanceTypeError: The instance is not supported for SSH. MissingVersionError: The version specified does not exist. MissingInstanceError: The instance specified does not exist. UnattendedPromptError: Not running in a tty. OperationCancelledError: User cancelled the operation. ssh.CommandError: The SSH command exited with SSH exit code, which usually implies that a connection problem occurred. Returns: int, The exit code of the SSH command. """ api_client = appengine_api_client.GetApiClientForTrack(self.ReleaseTrack()) env = ssh.Environment.Current() env.RequireSSH() keys = ssh.Keys.FromFilename() keys.EnsureKeysExist(overwrite=False) connection_details = ssh_common.PopulatePublicKey( api_client, args.service, args.version, args.instance, keys.GetPublicKey()) remote_command = containers.GetRemoteCommand(args.container, args.command) tty = containers.GetTty(args.container, args.command) cmd = ssh.SSHCommand( connection_details.remote, identity_file=keys.key_file, tty=tty, remote_command=remote_command, options=connection_details.options) return cmd.Run(env)
def testPopulateKeyDebugOffUnattended(self): """Test without input, make sure we fail.""" self._ExpectGetVersionCall('default', 'v1') self._ExpectGetInstanceCall('default', 'v1', 'i2', debug_enabled=False) with self.assertRaises(console_io.UnattendedPromptError): ssh_common.PopulatePublicKey(self.api_client, 'default', 'v1', 'i2', self.public_key, self.track)
def testPopulateKey(self): """Base case of unlocked instance.""" self._ExpectGetVersionCall('default', 'v1') self._ExpectGetInstanceCall('default', 'v1', 'i2', debug_enabled=True) self._ExpectDebugInstanceCall('default', 'v1', 'i2', ssh_key=self.key_field) connection_details = ssh_common.PopulatePublicKey( self.api_client, 'default', 'v1', 'i2', self.public_key, self.track) self.assertEqual(connection_details, self.connection_details)
def testPopulateKeyStandard(self): """Fail while trying standard instance.""" self._ExpectGetVersionCall('default', 'v1', environment=env.STANDARD) with self.AssertRaisesExceptionMatches( command_exceptions.InvalidInstanceTypeError, 'Standard instances do not support this operation'): ssh_common.PopulatePublicKey(self.api_client, 'default', 'v1', 'i2', self.public_key, self.track)
def testPopulateKeyMissingVersion(self): """The version doesn't exist.""" self._ExpectGetVersionCall( 'default', 'v1', exception=http_error.MakeHttpError(404)) with self.AssertRaisesExceptionMatches( command_exceptions.MissingVersionError, 'Version [default/v1] does not exist.'): ssh_common.PopulatePublicKey(self.api_client, 'default', 'v1', 'i2', self.public_key, self.track)
def testPopulateKeyDebugOff(self): """Debug not enabled on the instance.""" self._ExpectGetVersionCall('default', 'v1') self._ExpectGetInstanceCall('default', 'v1', 'i2', debug_enabled=False) self._ExpectDebugInstanceCall('default', 'v1', 'i2', ssh_key=self.key_field) self.WriteInput('y') connection_details = ssh_common.PopulatePublicKey( self.api_client, 'default', 'v1', 'i2', self.public_key, self.track) self.assertEqual(connection_details, self.connection_details) self.AssertErrContains( 'This instance is serving live application traffic.')
def testPopulateKeyWithOsLoginUser(self): """OS Login is enabled, so different username and no key tranferred.""" self.StartObjectPatch(ssh, 'CheckForOsloginAndGetUser', autospec=True, return_value=('me_oslogin', 'True')) connection_details_expected = ssh_common.ConnectionDetails( ssh.Remote('127.0.0.1', user='******'), self.options) self._ExpectGetVersionCall('default', 'v1') self._ExpectGetInstanceCall('default', 'v1', 'i2', debug_enabled=True) connection_details = ssh_common.PopulatePublicKey( self.api_client, 'default', 'v1', 'i2', self.public_key, self.track) self.assertEqual(connection_details, connection_details_expected)
def Run(self, args): """Securily copy files from/to a running flex instance. Args: args: argparse.Namespace, the args the command was invoked with. Raises: InvalidInstanceTypeError: The instance is not supported for SSH. MissingVersionError: The version specified does not exist. MissingInstanceError: The instance specified does not exist. UnattendedPromptError: Not running in a tty. OperationCancelledError: User cancelled the operation. ssh.CommandError: The SCP command exited with SCP exit code, which usually implies that a connection problem occurred. Returns: int, The exit code of the SCP command. """ api_client = appengine_api_client.GetApiClientForTrack( self.ReleaseTrack()) env = ssh.Environment.Current() env.RequireSSH() keys = ssh.Keys.FromFilename() keys.EnsureKeysExist(overwrite=False) # Make sure we have a unique remote dst = ssh.FileReference.FromPath(args.destination) srcs = [ssh.FileReference.FromPath(source) for source in args.sources] ssh.SCPCommand.Verify(srcs, dst, single_remote=True) remote = dst.remote or srcs[0].remote if not dst.remote: # Make sure all remotes point to the same ref for src in srcs: src.remote = remote connection_details = ssh_common.PopulatePublicKey( api_client, args.service, args.version, remote.host, keys.GetPublicKey(), self.ReleaseTrack()) # Update all remote references remote.host = connection_details.remote.host remote.user = connection_details.remote.user cmd = ssh.SCPCommand(srcs, dst, identity_file=keys.key_file, compress=args.compress, recursive=args.recurse, options=connection_details.options) return cmd.Run(env)
def testPopulateKeyMissingInstance(self): """The instance doesn't exist.""" self._ExpectGetVersionCall('default', 'v1') req = self.messages.AppengineAppsServicesVersionsInstancesGetRequest( name=self._FormatInstance('default', 'v1', 'i2')) self.mocked_client.apps_services_versions_instances.Get.Expect( request=req, exception=http_error.MakeHttpError(404)) with self.AssertRaisesExceptionRegexp( command_exceptions.MissingInstanceError, r'Instance \[.*i2\] does not exist.'): ssh_common.PopulatePublicKey(self.api_client, 'default', 'v1', 'i2', self.public_key, self.track)