def testWithAlternatePort(self):
    self.make_requests.side_effect = iter([
        [INSTANCE_WITH_EXTERNAL_ADDRESS],
        [self.project_resource],
    ])
    self.mock_http_request.request.return_value = PUBLIC_KEY_RESPONSE

    self.Run("""
        compute connect-to-serial-port instance-1 --zone zone-1 --port 3
        """)

    self.CheckRequests(
        [(self.GetCompute().instances,
          'Get',
          self.GetMessages().ComputeInstancesGetRequest(
              instance='instance-1',
              project='my-project',
              zone='zone-1'))],
        [(self.GetCompute().projects,
          'Get',
          self.GetMessages().ComputeProjectsGetRequest(
              project='my-project'))],
    )
    # SSH Command
    self.ssh_init.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        ssh.Remote(self.gateway, user='******'),
        identity_file=self.private_key_file,
        options=self.options,
        port='9600')

    self.ssh_run.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        self.env, force_connect=True)
示例#2
0
    def testWithAlternateUser(self):
        project_resource = self.messages.Project(name='my-project', )
        self.make_requests.side_effect = iter([
            [self.instance],
            [project_resource],
            [],
        ])

        self.Run("""\
        compute scp
          hapoo@instance-1:~/remote-file
          ~/local-dir --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
            [(self.compute.projects, 'SetCommonInstanceMetadata',
              self.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
                  metadata=self.messages.Metadata(items=[
                      self.messages.Metadata.ItemsValueListEntry(
                          key='ssh-keys',
                          value='hapoo:' + self.public_key_material),
                  ]),
                  project='my-project'))],
        )

        remote = ssh.Remote(self.remote.host, user='******')
        remote_file = ssh.FileReference('~/remote-file', remote=remote)
        # Polling
        self.poller_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHPoller),
            remote=remote,
            identity_file=self.private_key_file,
            max_wait_ms=ssh_utils.SSH_KEY_PROPAGATION_TIMEOUT_MS,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            extra_flags=None,
            iap_tunnel_args=None)
        self.poller_poll.assert_called_once()

        # SCP Command
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [remote_file],
            self.local_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)
  def testWithAbsoluteExpiration(self):
    self.make_requests.side_effect = iter([
        [INSTANCE_WITH_EXTERNAL_ADDRESS],
        [self.project_resource_without_metadata],
        [],
    ])
    self.mock_http_request.request.return_value = PUBLIC_KEY_RESPONSE

    self.Run("""
        compute connect-to-serial-port instance-1 --zone zone-1
        --ssh-key-expiration 2015-01-23T12:34:56+0000
        """)

    self.CheckRequests(
        [(self.GetCompute().instances,
          'Get',
          self.GetMessages().ComputeInstancesGetRequest(
              instance='instance-1',
              project='my-project',
              zone='zone-1'))],
        [(self.GetCompute().projects,
          'Get',
          self.GetMessages().ComputeProjectsGetRequest(
              project='my-project'))],
        [(self.GetCompute().projects,
          'SetCommonInstanceMetadata',
          self.GetMessages().ComputeProjectsSetCommonInstanceMetadataRequest(
              metadata=self.GetMessages().Metadata(
                  items=[
                      self.GetMessages().Metadata.ItemsValueListEntry(
                          key='ssh-keys',
                          value=('me:{0} google-ssh {{"userName":"******",'
                                 '"expireOn":'
                                 '"2015-01-23T12:34:56+0000"}}').format(
                                     self.pubkey.ToEntry())),
                  ]),

              project='my-project'))],
    )
    # SSH Command
    self.ssh_init.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        ssh.Remote(self.gateway,
                   user='******'),
        identity_file=self.private_key_file,
        options=self.options,
        port='9600')

    self.ssh_run.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        self.env, force_connect=True)

    # Known Hosts
    self.known_hosts_add.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.KnownHosts),
        '[ssh-serialport.googleapis.com]:9600', PUBLIC_KEY, overwrite=True)
    self.known_hosts_write.assert_called_once()
    self.AssertErrContains('Updating project ssh metadata')
示例#4
0
    def testSimpleCase(self, test_instance_key, explicit_flag):
        test_instance = self.instances[test_instance_key]
        self.make_requests.side_effect = iter([
            [test_instance],
            [self.project_resource],
        ])

        self.Run(
            'compute scp {}:~/remote-file ~/local-dir --zone zone-1{}'.format(
                test_instance.name,
                ' --tunnel-through-iap' if explicit_flag else ''))

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(
                  instance=test_instance.name,
                  project='my-project',
                  zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        expected_tunnel_args = iap_tunnel.SshTunnelArgs()
        expected_tunnel_args.track = self.track.prefix
        expected_tunnel_args.project = 'my-project'
        expected_tunnel_args.zone = 'zone-1'
        expected_tunnel_args.instance = test_instance.name

        # SCP Command
        remote_file = ssh.FileReference(
            '~/remote-file',
            remote=ssh.Remote.FromArg('me@compute.%s' % test_instance.id))
        local_dir = ssh.FileReference('~/local-dir')
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [remote_file],
            local_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options,
                         HostKeyAlias='compute.%s' % test_instance.id),
            iap_tunnel_args=expected_tunnel_args)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)
示例#5
0
    def testOsloginEnabledOnProjectButDisabledOnInstance(self, oslogin_mock):
        # Should fall through to alternate authentication.
        properties.VALUES.core.account.Set('*****@*****.**')
        self.remote = ssh.Remote('23.251.133.75', user='******')
        oslogin_mock.return_value = test_resources.MakeOsloginClient('v1')

        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_OSLOGIN_DISABLED],
            [self.project_resource_with_oslogin_enabled],
            [],
        ])

        self.Run("""
        compute ssh instance-1 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
            [(self.compute.projects, 'SetCommonInstanceMetadata',
              self.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
                  metadata=self.messages.Metadata(items=[
                      self.messages.Metadata.ItemsValueListEntry(
                          key='enable-oslogin', value='true'),
                      self.messages.Metadata.ItemsValueListEntry(
                          key='ssh-keys',
                          value='me:' + self.public_key_material),
                  ]),
                  project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options, HostKeyAlias='compute.55555'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
示例#6
0
    def testOverrideUsername(self, oslogin_mock):
        properties.VALUES.core.account.Set('*****@*****.**')
        self.remote = ssh.Remote.FromArg('[email protected]')
        self.remote_file = ssh.FileReference('~/remote-file',
                                             remote=self.remote)
        self.local_dir = ssh.FileReference('~/local-dir')
        oslogin_mock.return_value = test_resources.MakeOsloginClient('v1beta')

        self.make_requests.side_effect = iter([
            [self.instance_with_oslogin_enabled],
            [self.project_resource],
        ])

        self.Run("""\
        compute scp
          someotheruser@instance-1:~/remote-file
          ~/local-dir --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SCP Command
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [self.remote_file],
            self.local_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.44444'),
            iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)

        self.AssertErrContains('Using OS Login user [user_google_com] instead '
                               'of requested user [someotheruser]')
    def testInvalidHostKeyType(self):
        # No valid keys are returned, so nothing is written to known hosts and
        # StrictHostKeyChecking stays set to the default value.
        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_GUEST_ATTRIBUTES_ENABLED],
            [self.project_resource],
            [GUEST_ATTRIBUTES_CONTENTS_INVALID_KEY_TYPE],
        ])

        self.Run("""
        compute ssh instance-6 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute_v1.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-6',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute_v1.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
            [(self.compute.instances, 'GetGuestAttributes',
              self.messages.ComputeInstancesGetGuestAttributesRequest(
                  instance='instance-6',
                  project='my-project',
                  queryPath='hostkeys/',
                  zone='zone-1'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # No host keys to add since it is an invalid type
        self.known_hosts_addmultiple.assert_not_called()

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options, HostKeyAlias='compute.66666'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
    def testEnabledAtProjectLevel(self):
        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_EXTERNAL_ADDRESS],
            [self.project_resource_with_guest_attr_enabled],
            [GUEST_ATTRIBUTES_CONTENTS],
        ])

        self.Run("""
        compute ssh instance-1 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute_v1.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute_v1.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
            [(self.compute.instances, 'GetGuestAttributes',
              self.messages.ComputeInstancesGetGuestAttributesRequest(
                  instance='instance-1',
                  project='my-project',
                  queryPath='hostkeys/',
                  zone='zone-1'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options,
                         StrictHostKeyChecking='yes',
                         HostKeyAlias='compute.11111'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
示例#9
0
    def testSimpleCase(self):
        """Base case that makes sure SCPCommand is constructed.

    Note that the only difference against `compute scp` is that this command
    adds the `-r` recursive flag by default.
    """
        self.make_requests.side_effect = iter([
            [self.instance],
            [self.project_resource],
        ])

        self.Run("""\
        compute copy-files
          instance-1:~/remote-file
          ~/local-dir --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SCP Command
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [self.remote_file],
            self.local_dir,
            identity_file=self.private_key_file,
            extra_flags=None,
            port=None,
            recursive=True,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)

        self.AssertErrContains('deprecated')
  def testInstanceWithOsloginEnabled(self, oslogin_mock):
    properties.VALUES.core.account.Set('*****@*****.**')
    oslogin_mock.return_value = test_resources.MakeOsloginClient('v1')
    self.mock_http_request.request.return_value = PUBLIC_KEY_RESPONSE
    self.make_requests.side_effect = iter([
        [INSTANCE_WITH_OSLOGIN_ENABLED],
        [self.project_resource],
    ])

    self.Run("""
        compute connect-to-serial-port instance-4 --zone zone-1
        """)
    self.CheckRequests(
        [(self.GetCompute().instances,
          'Get',
          self.GetMessages().ComputeInstancesGetRequest(
              instance='instance-4',
              project='my-project',
              zone='zone-1'))],
        [(self.GetCompute().projects,
          'Get',
          self.GetMessages().ComputeProjectsGetRequest(
              project='my-project'))],
    )

    # Require SSH keys
    self.ensure_keys.assert_called_once_with(
        self.keys, None, allow_passphrase=True)

    # No polling
    self.poller_poll.assert_not_called()

    # SSH Command
    self.ssh_init.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        ssh.Remote(self.gateway,
                   user='******'),
        identity_file=self.private_key_file,
        options=self.options,
        port='9600')

    self.ssh_run.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        self.env, force_connect=True)

    # Known Hosts
    self.known_hosts_add.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.KnownHosts),
        '[ssh-serialport.googleapis.com]:9600', PUBLIC_KEY, overwrite=True)
    self.known_hosts_write.assert_called_once()
    self.make_requests.assert_not_called()
示例#11
0
    def testRequestNonOsloginUser(self, oslogin_mock):
        properties.VALUES.core.account.Set('*****@*****.**')
        self.remote = ssh.Remote('23.251.133.75', user='******')
        oslogin_mock.return_value = test_resources.MakeOsloginClient('v1')

        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_OSLOGIN_ENABLED],
            [self.project_resource],
        ])

        self.Run("""
        compute ssh someotheruser@instance-1 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options, HostKeyAlias='compute.44444'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)

        self.AssertErrContains('Using OS Login user [user_google_com] instead '
                               'of requested user [someotheruser]')
示例#12
0
    def testWithInternalIPAddress(self, track, api_version):
        self._SetUpForTrack(track, api_version)
        self.make_requests.side_effect = iter([
            [self.instance_with_internal_ip_address],
            [self.project_resource],
        ])

        self.Run("""
      compute scp
      ~/local-file-1 instance-3:~/remote-dir
      --zone zone-1 --internal-ip
      """)
        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-3',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )
        self.remote = ssh.Remote.FromArg('[email protected]')
        self.remote_dir = ssh.FileReference('~/remote-dir', self.remote)
        self.local_file = ssh.FileReference('~/local-file-1')

        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [self.local_file],
            self.remote_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.33333'),
            iap_tunnel_args=None)

        self.ssh_init.assert_has_calls([
            mock.call(
                mock_matchers.TypeMatcher(ssh.SSHCommand),
                remote=self.remote,
                identity_file=self.private_key_file,
                options=dict(self.options, HostKeyAlias='compute.33333'),
                remote_command=[
                    '[ `curl "http://metadata.google.internal/'
                    'computeMetadata/v1/instance/id" -H "Metadata-Flavor: '
                    'Google" -q` = 33333 ] || exit 23'
                ]),
        ],
                                       any_order=True)
  def testInstanceWithNoExternalIp(self):
    self.make_requests.side_effect = iter([
        [INSTANCE_WITH_NO_EXTERNAL_ADDRESS],
        [self.project_resource],
    ])
    self.mock_http_request.request.return_value = PUBLIC_KEY_RESPONSE

    self.Run("""
        compute connect-to-serial-port instance-2 --zone zone-1
        """)

    self.CheckRequests(
        [(self.GetCompute().instances,
          'Get',
          self.GetMessages().ComputeInstancesGetRequest(
              instance='instance-2',
              project='my-project',
              zone='zone-1'))],
        [(self.GetCompute().projects,
          'Get',
          self.GetMessages().ComputeProjectsGetRequest(
              project='my-project'))],
    )
    # Require SSH keys
    self.ensure_keys.assert_called_once_with(
        self.keys, None, allow_passphrase=True)

    # No polling
    self.poller_poll.assert_not_called()

    # SSH Command
    self.ssh_init.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        ssh.Remote(self.gateway, user='******'),
        identity_file=self.private_key_file,
        options=self.options,
        port='9600')

    self.ssh_run.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.SSHCommand),
        self.env, force_connect=True)

    # Known Hosts
    self.known_hosts_add.assert_called_once_with(
        mock_matchers.TypeMatcher(ssh.KnownHosts),
        '[ssh-serialport.googleapis.com]:9600', PUBLIC_KEY, overwrite=True)
    self.known_hosts_write.assert_called_once()
    self.make_requests.assert_not_called()
示例#14
0
    def testSSHWithCommand(self):
        """Execute a remote command."""
        self.Run(
            'app instances ssh --service default --version v1 i2 -- echo hi')
        self._AssertPopulateCalled()

        self.ssh_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                              self.remote,
                                              identity_file=self.key_file,
                                              tty=None,
                                              options=self.options,
                                              remote_command='echo hi'.split())

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand), self.ssh_env)
    def testEnabledAtProjectDisabledAtInstance(self):
        # Instance value overrides project value, so Guest Attributes won't
        # be retrieved and StrictHostKeyChecking should be set to 'no'.
        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_GUEST_ATTRIBUTES_DISABLED],
            [self.project_resource_with_guest_attr_enabled],
        ])

        self.Run("""
        compute ssh instance-7 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute_v1.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-7',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute_v1.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options,
                         StrictHostKeyChecking='no',
                         HostKeyAlias='compute.77777'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
示例#16
0
    def testZonePrompting(self):
        self.StartPatch('googlecloudsdk.core.console.console_io.CanPrompt',
                        return_value=True)

        self.make_requests.side_effect = iter([
            [
                self.messages.Instance(name='instance-1', zone='zone-1'),
            ],
            [self.instance],
            [self.project_resource],
        ])

        self.Run("""\
        compute scp
          instance-1:~/remote-file
          ~/local-dir
        """)

        self.CheckRequests(
            self.FilteredInstanceAggregateListRequest('instance-1'),
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )
        self.AssertErrContains(
            'No zone specified. Using zone [zone-1] for instance: [instance-1].'
        )

        # SCP Command
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [self.remote_file],
            self.local_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)
示例#17
0
    def testWithManyRemoteFilesToLocalDestination(self):
        self.make_requests.side_effect = iter([
            [self.instance],
            [self.project_resource],
        ])

        self.Run(r"""
        compute scp
          instance-1:~/remote-file-1
          instance-1:~/remote-file-2
          instance-1:~/remote-file-3
          ~/local-dir
          --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        remote = ssh.Remote('23.251.133.1', user='******')

        # SCP Command
        self.scp_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), [
                ssh.FileReference('~/remote-file-1', remote=remote),
                ssh.FileReference('~/remote-file-2', remote=remote),
                ssh.FileReference('~/remote-file-3', remote=remote),
            ],
            self.local_dir,
            identity_file=self.private_key_file,
            extra_flags=[],
            port=None,
            recursive=False,
            compress=False,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)
示例#18
0
    def testUnknownOsloginApiVarsion(self, oslogin_mock):
        # Should fall through to alternate authentication.
        properties.VALUES.core.account.Set('*****@*****.**')
        self.remote = ssh.Remote('23.251.133.75', user='******')
        oslogin_mock.side_effect = apis_util.UnknownVersionError(
            'oslogin', 'v1')

        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_OSLOGIN_ENABLED],
            [self.project_resource],
        ])

        self.Run("""
        compute ssh instance-1 --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options, HostKeyAlias='compute.44444'),
            remote_command=None,
            iap_tunnel_args=None,
            remainder=[])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
示例#19
0
    def testSSHWithContainer(self):
        """Go straight to the app container."""
        self.Run(
            'app instances ssh --service default --version v1 i2 --container '
            'gaeapp')
        self._AssertPopulateCalled()

        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            self.remote,
            identity_file=self.key_file,
            tty=True,
            options=self.options,
            remote_command='sudo docker exec -it gaeapp /bin/sh'.split())

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand), self.ssh_env)
示例#20
0
    def testSSH(self):
        """Base case of unlocked instance."""
        self.Run('app instances ssh --service default --version v1 i2')
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()

        self.ssh_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                              self.remote,
                                              identity_file=self.key_file,
                                              tty=None,
                                              options=self.options,
                                              remote_command=None)

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand), self.ssh_env)
示例#21
0
    def testWithURI(self):
        """SSH using URI instead of specifying service and version."""
        self.Run('app instances ssh https://appengine.googleapis.com/v1/apps/'
                 'fakeproject/services/default/versions/v1/instances/i2')
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()
        self.ssh_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                              self.remote,
                                              identity_file=self.key_file,
                                              tty=None,
                                              options=self.options,
                                              remote_command=None)

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand), self.ssh_env)
示例#22
0
    def testFlags(self):
        """Remote to local, but with all flags here."""
        self._RunScp('--recurse --compress i2:rem_1 local_1')
        self.require_ssh.assert_called_once()
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()

        self.scp_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand), [self.remote_file_1],
                                              self.local_file_1,
                                              identity_file=self.key_file,
                                              recursive=True,
                                              compress=True,
                                              options=self.options)

        self.scp_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), self.ssh_env)
示例#23
0
    def testMultiRemoteToLocal(self):
        """Multiple remote files (same instance) to local."""
        self._RunScp('i2:rem_1 i2:rem_2 local_1')
        self.require_ssh.assert_called_once()
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()

        self.scp_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand), [self.remote_file_1, self.remote_file_2],
                                              self.local_file_1,
                                              identity_file=self.key_file,
                                              recursive=False,
                                              compress=False,
                                              options=self.options)

        self.scp_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), self.ssh_env)
示例#24
0
    def testSingleLocalToRemote(self):
        """Simple case with remote to local."""
        self._RunScp('local_1 i2:rem_1')
        self.require_ssh.assert_called_once()
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()

        self.scp_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand), [self.local_file_1],
                                              self.remote_file_1,
                                              identity_file=self.key_file,
                                              recursive=False,
                                              compress=False,
                                              options=self.options)

        self.scp_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SCPCommand), self.ssh_env)
示例#25
0
    def _assertSSHCalled(self):
        self.ensure_keys.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.Keys),
                                                 None,
                                                 allow_passphrase=True)

        self.poller_poll.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHPoller),
            mock_matchers.TypeMatcher(ssh.Environment),
            force_connect=True)

        # SSH Command
        self.ssh_init.assert_called_once()

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            mock_matchers.TypeMatcher(ssh.Environment),
            force_connect=True)
示例#26
0
    def testSSHShortFlagsInBeta(self):
        """Test that short flags work in the beta version."""
        self.track = calliope_base.ReleaseTrack.BETA
        self.Run('app instances ssh -s default -v v1 i2')
        self.ensure_keys_exist.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.Keys), overwrite=False)
        self._AssertPopulateCalled()

        self.ssh_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                              self.remote,
                                              identity_file=self.key_file,
                                              tty=None,
                                              options=self.options,
                                              remote_command=None)

        self.ssh_run.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand), self.ssh_env)
        self.AssertErrContains('the short flags `-s` and `-v` are deprecated')
示例#27
0
    def testPlain(self):
        self.make_requests.side_effect = iter([
            [self.instance],
            [self.project_resource],
        ])

        self.Run("""\
        compute scp --plain
          instance-1:~/remote-file
          ~/local-dir --zone zone-1
        """)

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )

        # Don't require SSH keys
        self.ensure_keys.assert_not_called()

        # No polling
        self.poller_poll.assert_not_called()

        # SCP Command without options and identity_file
        self.scp_init.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand), [self.remote_file],
                                              self.local_dir,
                                              identity_file=None,
                                              extra_flags=[],
                                              port=None,
                                              recursive=False,
                                              compress=False,
                                              options=None,
                                              iap_tunnel_args=None)

        self.scp_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SCPCommand),
                                             self.env,
                                             force_connect=True)
示例#28
0
    def testWithCommandAndImplementationArgs(self):
        self.make_requests.side_effect = iter([
            [INSTANCE_WITH_EXTERNAL_ADDRESS],
            [self.project_resource],
        ])

        self.Run([
            'compute', 'ssh', 'instance-1', '--zone', 'zone-1', '--command',
            '"/bin/sh"', '--', '-v', '1 2 3', 'a | b', 'b\'y'
        ])

        self.CheckRequests(
            [(self.compute_v1.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(instance='instance-1',
                                                       project='my-project',
                                                       zone='zone-1'))],
            [(self.compute_v1.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
        )
        # Require SSH keys
        self.ensure_keys.assert_called_once_with(self.keys,
                                                 None,
                                                 allow_passphrase=True)

        # No polling
        self.poller_poll.assert_not_called()

        # SSH Command
        self.ssh_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHCommand),
            remote=self.remote,
            identity_file=self.private_key_file,
            extra_flags=[],
            tty=None,
            options=dict(self.options, HostKeyAlias='compute.11111'),
            remote_command=['"/bin/sh"'],
            iap_tunnel_args=None,
            remainder=['-v', '1 2 3', 'a | b', 'b\'y'])

        self.ssh_run.assert_called_once_with(mock_matchers.TypeMatcher(
            ssh.SSHCommand),
                                             self.env,
                                             force_connect=True)
示例#29
0
    def testWithPollingTimeout(self, test_instance_key):
        self.poller_poll.side_effect = retry.WaitException(
            'msg', 'result', 'state')
        project_resource = self.messages.Project(name='my-project', )
        test_instance = self.instances[test_instance_key]
        self.make_requests.side_effect = iter([
            [test_instance],
            [project_resource],
            [],
        ])

        with self.AssertRaisesExceptionMatches(
                ssh_utils.NetworkError, 'Could not SSH into the instance'):
            self.Run('compute scp hapoo@{}:~/remote-file ~/local-dir '
                     '--zone zone-1 --tunnel-through-iap'.format(
                         test_instance.name))

        self.CheckRequests(
            [(self.compute.instances, 'Get',
              self.messages.ComputeInstancesGetRequest(
                  instance=test_instance.name,
                  project='my-project',
                  zone='zone-1'))],
            [(self.compute.projects, 'Get',
              self.messages.ComputeProjectsGetRequest(project='my-project'))],
            [(self.compute.projects, 'SetCommonInstanceMetadata',
              self.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
                  metadata=self.messages.Metadata(items=[
                      self.messages.Metadata.ItemsValueListEntry(
                          key='ssh-keys',
                          value='hapoo:' + self.public_key_material),
                  ]),
                  project='my-project'))],
        )

        expected_tunnel_args = iap_tunnel.SshTunnelArgs()
        expected_tunnel_args.track = self.track.prefix
        expected_tunnel_args.project = 'my-project'
        expected_tunnel_args.zone = 'zone-1'
        expected_tunnel_args.instance = test_instance.name

        # Polling
        remote = ssh.Remote.FromArg('hapoo@compute.%s' % test_instance.id)
        self.poller_init.assert_called_once_with(
            mock_matchers.TypeMatcher(ssh.SSHPoller),
            remote=remote,
            identity_file=self.private_key_file,
            max_wait_ms=ssh_utils.SSH_KEY_PROPAGATION_TIMEOUT_MS,
            options=dict(self.options,
                         HostKeyAlias='compute.%s' % test_instance.id),
            extra_flags=None,
            iap_tunnel_args=expected_tunnel_args)
        self.poller_poll.assert_called_once()

        self.scp_run.assert_not_called()
示例#30
0
    def testTimeout(self):
        disk_ref = self._GetDiskRef('disk-1')
        snapshot_ref = self._GetSnapshotRef('random-name-0')
        operation_ref = self._GetOperationRef('operation-1')

        self.api_mock.batch_responder.ExpectBatch([
            (self._GetCreateSnapshotRequest(disk_ref, snapshot_ref),
             self._GetOperationMessage(operation_ref,
                                       self.status_enum.PENDING)),
        ])

        waiter_mock = self.StartPatch(
            'googlecloudsdk.api_lib.util.waiter.WaitFor', autospec=True)

        self.Run('compute disks snapshot disk-1 --zone central2-a')

        waiter_mock.assert_called_once_with(
            mock_matchers.TypeMatcher(poller.BatchPoller),
            mock_matchers.TypeMatcher(poller.OperationBatch),
            'Creating snapshot(s) random-name-0',
            max_wait_ms=None)