Ejemplo n.º 1
0
class TestStreamingOutput(BaseAWSCommandParamsTest):

    def setUp(self):
        super(TestStreamingOutput, self).setUp()
        self.files = FileCreator()

    def tearDown(self):
        super(TestStreamingOutput, self).tearDown()
        self.files.remove_all()

    def test_get_media_streaming_output(self):
        cmdline = (
            'kinesis-video-media get-media --stream-name test-stream '
            '--start-selector StartSelectorType=EARLIEST %s'
        )
        self.parsed_response = {
            'ContentType': 'video/webm',
            'Payload': six.BytesIO(b'testbody')
        }
        outpath = self.files.full_path('outfile')
        params = {
            'StartSelector': {'StartSelectorType': 'EARLIEST'},
            'StreamName': 'test-stream'
        }
        self.assert_params_for_cmd(cmdline % outpath, params)
        with open(outpath, 'rb') as outfile:
            self.assertEqual(outfile.read(), b'testbody')
Ejemplo n.º 2
0
class BaseSSOTest(BaseAWSCommandParamsTest):
    def setUp(self):
        super(BaseSSOTest, self).setUp()
        self.files = FileCreator()
        self.start_url = 'https://mysigin.com'
        self.sso_region = 'us-west-2'
        self.account = '012345678912'
        self.role_name = 'SSORole'
        self.config_file = self.files.full_path('config')
        self.environ['AWS_CONFIG_FILE'] = self.config_file
        self.set_config_file_content()
        self.access_token = 'foo.token.string'

    def tearDown(self):
        super(BaseSSOTest, self).tearDown()
        self.files.remove_all()

    def set_config_file_content(self, content=None):
        if content is None:
            content = ('[default]\n'
                       'sso_start_url=%s\n'
                       'sso_region=%s\n'
                       'sso_role_name=%s\n'
                       'sso_account_id=%s\n' %
                       (self.start_url, self.sso_region, self.role_name,
                        self.account))
        self.files.create_file(self.config_file, content)
        # We need to recreate the driver (which includes its session) in order
        # for the config changes to be pulled in by the session.
        self.driver = create_clidriver()
Ejemplo n.º 3
0
class TestStreamingOutput(BaseAWSCommandParamsTest):
    def setUp(self):
        super(TestStreamingOutput, self).setUp()
        self.files = FileCreator()

    def tearDown(self):
        super(TestStreamingOutput, self).tearDown()
        self.files.remove_all()

    def test_get_media_streaming_output(self):
        cmdline = ('kinesis-video-media get-media --stream-name test-stream '
                   '--start-selector StartSelectorType=EARLIEST %s')
        self.parsed_response = {
            'ContentType': 'video/webm',
            'Payload': six.BytesIO(b'testbody')
        }
        outpath = self.files.full_path('outfile')
        params = {
            'StartSelector': {
                'StartSelectorType': 'EARLIEST'
            },
            'StreamName': 'test-stream'
        }
        self.assert_params_for_cmd(cmdline % outpath, params)
        with open(outpath, 'rb') as outfile:
            self.assertEqual(outfile.read(), b'testbody')
Ejemplo n.º 4
0
class TestZipDirectory(unittest.TestCase):
    def setUp(self):
        self.file_creator = FileCreator()
        self.zip_file = self.file_creator.create_file('build.zip', '')
        self._dir_root = 'mybuild'

    def tearDown(self):
        self.file_creator.remove_all()

    @property
    def dir_root(self):
        return self.file_creator.full_path(self._dir_root)

    def add_to_directory(self, filename):
        self.file_creator.create_file(
            os.path.join(self._dir_root, filename), 'Some contents')

    def assert_contents_of_zip_file(self, filenames):
        zip_file_object = zipfile.ZipFile(
            self.zip_file, 'r', zipfile.ZIP_DEFLATED)
        with contextlib.closing(zip_file_object) as zf:
            ref_zipfiles = []
            zipfile_contents = zf.namelist()
            for ref_zipfile in zipfile_contents:
                if os.sep == '\\':
                    # Internally namelist() represent directories with
                    # forward slashes so we need to account for that if
                    # the separator is a backslash depending on the operating
                    # system.
                    ref_zipfile = ref_zipfile.replace('/', '\\')
                ref_zipfiles.append(ref_zipfile)
            self.assertEqual(sorted(ref_zipfiles), filenames)

    def test_single_file(self):
        self.add_to_directory('foo')
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file(['foo'])

    def test_multiple_files(self):
        self.add_to_directory('foo')
        self.add_to_directory('bar')
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file(['bar', 'foo'])

    def test_nested_file(self):
        filename = os.path.join('mydir', 'foo')
        self.add_to_directory(filename)
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file([filename])
Ejemplo n.º 5
0
class TestZipDirectory(unittest.TestCase):
    def setUp(self):
        self.file_creator = FileCreator()
        self.zip_file = self.file_creator.create_file('build.zip', '')
        self._dir_root = 'mybuild'

    def tearDown(self):
        self.file_creator.remove_all()

    @property
    def dir_root(self):
        return self.file_creator.full_path(self._dir_root)

    def add_to_directory(self, filename):
        self.file_creator.create_file(
            os.path.join(self._dir_root, filename), 'Some contents')

    def assert_contents_of_zip_file(self, filenames):
        zip_file_object = zipfile.ZipFile(
            self.zip_file, 'r', zipfile.ZIP_DEFLATED)
        with contextlib.closing(zip_file_object) as zf:
            ref_zipfiles = []
            zipfile_contents = zf.namelist()
            for ref_zipfile in zipfile_contents:
                if os.sep == '\\':
                    # Internally namelist() represent directories with
                    # forward slashes so we need to account for that if
                    # the separator is a backslash depending on the operating
                    # system.
                    ref_zipfile = ref_zipfile.replace('/', '\\')
                ref_zipfiles.append(ref_zipfile)
            self.assertEqual(sorted(ref_zipfiles), filenames)

    def test_single_file(self):
        self.add_to_directory('foo')
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file(['foo'])

    def test_multiple_files(self):
        self.add_to_directory('foo')
        self.add_to_directory('bar')
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file(['bar', 'foo'])

    def test_nested_file(self):
        filename = os.path.join('mydir', 'foo')
        self.add_to_directory(filename)
        zip_directory(self.zip_file, self.dir_root)
        self.assert_contents_of_zip_file([filename])
Ejemplo n.º 6
0
class TestTwineLogin(unittest.TestCase):

    DEFAULT_PYPI_RC_FMT = TwineLogin.DEFAULT_PYPI_RC_FMT

    def setUp(self):
        self.file_creator = FileCreator()
        self.domain = 'domain'
        self.domain_owner = 'domain-owner'
        self.package_format = 'pip'
        self.repository = 'repository'
        self.auth_token = 'auth-token'
        self.expiration = (datetime.now(tzlocal()) + relativedelta(years=1) +
                           relativedelta(months=9)).replace(microsecond=0)
        self.endpoint = 'https://{domain}-{domainOwner}.codeartifact.aws.' \
            'a2z.com/{format}/{repository}/'.format(
                domain=self.domain,
                domainOwner=self.domain_owner,
                format=self.package_format,
                repository=self.repository
            )
        self.default_pypi_rc = self.DEFAULT_PYPI_RC_FMT.format(
            repository_endpoint=self.endpoint, auth_token=self.auth_token)
        self.subprocess_utils = mock.Mock()
        self.test_pypi_rc_path = self.file_creator.full_path('pypirc')
        if not os.path.isdir(os.path.dirname(self.test_pypi_rc_path)):
            os.makedirs(os.path.dirname(self.test_pypi_rc_path))

        self.test_subject = TwineLogin(self.auth_token, self.expiration,
                                       self.endpoint, self.subprocess_utils,
                                       self.test_pypi_rc_path)

    def tearDown(self):
        self.file_creator.remove_all()

    def _assert_pypi_rc_has_expected_content(self,
                                             pypi_rc_str,
                                             server,
                                             repo_url=None,
                                             username=None,
                                             password=None):
        pypi_rc = RawConfigParser()
        pypi_rc.readfp(StringIO(pypi_rc_str))

        self.assertIn('distutils', pypi_rc.sections())
        self.assertIn('index-servers', pypi_rc.options('distutils'))
        index_servers = pypi_rc.get('distutils', 'index-servers')
        index_servers = [
            index_server.strip() for index_server in index_servers.split('\n')
            if index_server.strip() != ''
        ]
        self.assertIn(server, index_servers)

        if repo_url or username or password:
            self.assertIn(server, pypi_rc.sections())

        if repo_url:
            self.assertIn('repository', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'repository'), repo_url)

        if username:
            self.assertIn('username', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'username'), username)

        if password:
            self.assertIn('password', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'password'), password)

    def test_get_pypi_rc_path(self):
        self.assertEqual(TwineLogin.get_pypi_rc_path(),
                         os.path.join(os.path.expanduser("~"), ".pypirc"))

    def test_login_pypi_rc_not_found_defaults_set(self):
        self.test_subject.login()

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_login_dry_run(self):
        self.test_subject.login(dry_run=True)
        self.subprocess_utils.check_call.assert_not_called()
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))

    def test_login_existing_pypi_rc_not_clobbered(self):
        existing_pypi_rc = '''\
[distutils]
index-servers=
    pypi
    test

[pypi]
repository: http://www.python.org/pypi/
username: monty
password: JgCXIr5xGG

[test]
repository: http://example.com/test/
username: testusername
password: testpassword
'''

        with open(self.test_pypi_rc_path, 'w+') as f:
            f.write(existing_pypi_rc)

        self.test_subject.login()

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=test_pypi_rc_str,
            server='pypi',
            repo_url='http://www.python.org/pypi/',
            username='******',
            password='******')

        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=test_pypi_rc_str,
            server='test',
            repo_url='http://example.com/test/',
            username='******',
            password='******')

    def test_login_existing_pypi_rc_with_codeartifact_not_clobbered(self):
        existing_pypi_rc = '''\
[distutils]
index-servers=
    pypi
    codeartifact

[pypi]
repository: http://www.python.org/pypi/
username: monty
password: JgCXIr5xGG

[codeartifact]
repository: https://test-testOwner.codeartifact.aws.a2z.com/pypi/testRepo/
username: aws
password: expired_token
'''

        with open(self.test_pypi_rc_path, 'w+') as f:
            f.write(existing_pypi_rc)

        self.test_subject.login()

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=test_pypi_rc_str,
            server='pypi',
            repo_url='http://www.python.org/pypi/',
            username='******',
            password='******')

    def test_login_existing_invalid_pypi_rc_error(self):
        # This is an invalid pypirc as the list of servers are expected under
        # an 'index-servers' option instead of 'servers'.
        existing_pypi_rc = '''\
[distutils]
servers=
    pypi

[pypi]
repository: http://www.python.org/pypi/
username: monty
password: JgCXIr5xGG
'''

        with open(self.test_pypi_rc_path, 'w+') as f:
            f.write(existing_pypi_rc)

        with open(self.test_pypi_rc_path) as f:
            original_content = f.read()

        with self.assertRaises(Exception):
            self.test_subject.login()

        # We should just leave the pypirc untouched when it's invalid.
        with open(self.test_pypi_rc_path) as f:
            self.assertEqual(f.read(), original_content)
Ejemplo n.º 7
0
class TestOutFileQueryArguments(BaseAWSCommandParamsTest):
    def setUp(self):
        self.files = FileCreator()
        super(TestOutFileQueryArguments, self).setUp()

    def tearDown(self):
        self.files.remove_all()
        super(TestOutFileQueryArguments, self).tearDown()

    def test_saves_cert_to_file_for_create_certificate_from_csr(self):
        self.parsed_response = {
            'certificatePem': 'cert...',
            'ResponseMetadata': {
                'HTTPStatusCode': 200,
                'RequestId': 'request-id'
            }
        }
        outfile = self.files.full_path('cert.pem')
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        self.run_cmd(cmdline, 0)
        self.assertTrue(os.path.exists(outfile))
        with open(outfile) as fp:
            self.assertEquals('cert...', fp.read())

    def test_saves_files_for_create_keys_and_cert(self):
        self.parsed_response = {
            'certificatePem': 'cert...',
            'keyPair': {
                'PublicKey': 'public',
                'PrivateKey': 'private'
            },
            'ResponseMetadata': {
                'HTTPStatusCode': 200,
                'RequestId': 'request-id'
            }
        }
        out_cert = self.files.full_path('cert.pem')
        out_pub = self.files.full_path('key_rsa.pub')
        out_priv = self.files.full_path('key_rsa')
        cmdline = 'iot create-keys-and-certificate'
        cmdline += ' --certificate-pem-outfile ' + out_cert
        cmdline += ' --public-key-outfile ' + out_pub
        cmdline += ' --private-key-outfile ' + out_priv
        self.run_cmd(cmdline, 0)
        self.assertTrue(os.path.exists(out_cert))
        self.assertTrue(os.path.exists(out_pub))
        self.assertTrue(os.path.exists(out_priv))
        with open(out_cert) as fp:
            self.assertEquals('cert...', fp.read())
        with open(out_pub) as fp:
            self.assertEquals('public', fp.read())
        with open(out_priv) as fp:
            self.assertEquals('private', fp.read())

    def test_bad_response(self):
        outfile = self.files.full_path('cert.pem')
        self.parsed_response = {
            'Error': {'Code': 'v1', 'Message': 'v2', 'Type': 'v3'},
            'ResponseMetadata': {
                'HTTPStatusCode': 403,
                'RequestId': 'request-id'
            }
        }
        self.http_response.status_code = 403
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        # The error message should be in the stderr.
        self.assert_params_for_cmd(
            cmdline,
            stderr_contains=self.parsed_response['Error']['Message'],
            expected_rc=255)

    def test_ensures_file_is_writable_before_sending(self):
        outfile = os.sep.join(['', 'does', 'not', 'exist_', 'file.txt'])
        self.parsed_response = {}
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        self.assert_params_for_cmd(
            cmdline,
            stderr_contains='Unable to write to file: ',
            expected_rc=255)
Ejemplo n.º 8
0
class TestConfigureCommand(BaseAWSCommandParamsTest):
    def setUp(self):
        super().setUp()
        self.files = FileCreator()
        self.config_filename = self.files.full_path("configure")
        self.environ["AWS_CONFIG_FILE"] = self.config_filename
        self.environ["AWS_SHARED_CREDENTIALS_FILE"] = "asdf-does-not-exist"

    def tearDown(self):
        super().tearDown()
        self.files.remove_all()

    def set_config_file_contents(self, contents):
        self.files.create_file(self.config_filename, contents)
        # Reset the session to pick up the new config file.
        self.driver = create_clidriver()

    def get_config_file_contents(self):
        with open(self.config_filename, "r") as f:
            return f.read()

    def test_list_command(self):
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=12345\n"
            "aws_secret_access_key=12345\n"
            "region=us-west-2\n"
        )
        self.environ.pop("AWS_DEFAULT_REGION", None)
        self.environ.pop("AWS_ACCESS_KEY_ID", None)
        self.environ.pop("AWS_SECRET_ACCESS_KEY", None)
        stdout, _, _ = self.run_cmd("configure list")
        self.assertRegex(stdout, r"access_key.+config-file")
        self.assertRegex(stdout, r"secret_key.+config-file")
        self.assertRegex(stdout, r"region\s+us-west-2\s+config-file")

    def test_get_command(self):
        self.driver = create_clidriver()
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=access_key\n"
            "aws_secret_access_key=secret_key\n"
            "region=us-west-2\n"
        )
        stdout, _, _ = self.run_cmd("configure get aws_access_key_id")
        self.assertEqual(stdout.strip(), "access_key")

    def test_get_command_with_profile_set(self):
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=default_access_key\n"
            "\n"
            "[profile testing]\n"
            "aws_access_key_id=testing_access_key\n"
        )
        stdout, _, _ = self.run_cmd(
            "configure get aws_access_key_id --profile testing",
        )
        self.assertEqual(stdout.strip(), "testing_access_key")

    def test_get_with_fq_name(self):
        # test get configs with fully qualified name.
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=default_access_key\n"
            "\n"
            "[profile testing]\n"
            "aws_access_key_id=testing_access_key\n"
        )
        stdout, _, _ = self.run_cmd(
            "configure get default.aws_access_key_id --profile testing",
        )
        self.assertEqual(stdout.strip(), "default_access_key")

    def test_get_with_fq_profile_name(self):
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=default_access_key\n"
            "\n"
            "[profile testing]\n"
            "aws_access_key_id=testing_access_key\n"
        )
        stdout, _, _ = self.run_cmd(
            "configure get profile.testing.aws_access_key_id "
            "--profile default",
        )
        self.assertEqual(stdout.strip(), "testing_access_key")

    def test_get_fq_with_quoted_profile_name(self):
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=default_access_key\n"
            "\n"
            '[profile "testing"]\n'
            "aws_access_key_id=testing_access_key\n"
        )
        stdout, _, _ = self.run_cmd(
            "configure get profile.testing.aws_access_key_id "
            "--profile default",
        )
        self.assertEqual(stdout.strip(), "testing_access_key")

    def test_get_fq_for_non_profile_configs(self):
        self.set_config_file_contents(
            "\n"
            "[default]\n"
            "aws_access_key_id=default_access_key\n"
            "\n"
            "[profile testing]\n"
            "aws_access_key_id=testing_access_key\n"
            "[preview]\n"
            "emr=true"
        )
        stdout, _, _ = self.run_cmd(
            "configure get preview.emr --profile default",
        )
        self.assertEqual(stdout.strip(), "true")

    def test_set_with_config_file_no_exist(self):
        self.run_cmd("configure set region us-west-1")
        self.assertEqual(
            "[default]\n"
            "region = us-west-1\n",
            self.get_config_file_contents()
        )

    def test_set_with_a_url(self):
        self.run_cmd(
            "configure set endpoint http://www.example.com",
        )
        self.assertEqual(
            "[default]\n"
            "endpoint = http://www.example.com\n",
            self.get_config_file_contents(),
        )

    def test_set_with_empty_config_file(self):
        with open(self.config_filename, "w"):
            pass

        self.run_cmd("configure set region us-west-1")
        self.assertEqual(
            "[default]\n"
            "region = us-west-1\n",
            self.get_config_file_contents()
        )

    def test_set_with_updating_value(self):
        self.set_config_file_contents(
            "[default]\n"
            "region = us-west-2\n"
        )
        self.run_cmd("configure set region us-west-1")
        self.assertEqual(
            "[default]\n"
            "region = us-west-1\n",
            self.get_config_file_contents()
        )

    def test_set_with_profile_spaces(self):
        self.run_cmd(
            [
                "configure",
                "set",
                "region",
                "us-west-1",
                "--profile",
                "test with spaces",
            ]
        )
        self.assertEqual(
            "[profile 'test with spaces']\n"
            "region = us-west-1\n",
            self.get_config_file_contents(),
        )

    def test_set_with_profile_unknown_nested_key(self):
        self.run_cmd(
            [
                "configure",
                "set",
                "un.known",
                "us-west-1",
                "--profile",
                "space test",
            ]
        )
        self.assertEqual(
            "[profile 'space test']\n"
            "un =\n"
            "    known = us-west-1\n",
            self.get_config_file_contents(),
        )

    def test_set_with_profile_spaces_scoped(self):
        self.run_cmd(
            [
                "configure",
                "set",
                "profile.test with spaces.region",
                "us-west-1",
            ]
        )
        self.assertEqual(
            "[profile 'test with spaces']\n"
            "region = us-west-1\n",
            self.get_config_file_contents(),
        )

    def test_set_with_profile(self):
        self.run_cmd(
            "configure set region us-west-1 --profile testing",
        )
        self.assertEqual(
            "[profile testing]\n"
            "region = us-west-1\n",
            self.get_config_file_contents(),
        )

    def test_set_with_fq_single_dot(self):
        self.run_cmd("configure set preview.cloudsearch true")
        self.assertEqual(
            "[preview]\n"
            "cloudsearch = true\n",
            self.get_config_file_contents()
        )

    def test_set_with_fq_double_dot(self):
        self.run_cmd(
            "configure set profile.testing.region us-west-2",
        )
        self.assertEqual(
            "[profile testing]\n"
            "region = us-west-2\n",
            self.get_config_file_contents(),
        )

    def test_set_with_commented_out_field(self):
        self.set_config_file_contents(
            "#[preview]\n"
            ";cloudsearch = true\n"
        )
        self.run_cmd("configure set preview.cloudsearch true")
        self.assertEqual(
            "#[preview]\n"
            ";cloudsearch = true\n"
            "[preview]\n"
            "cloudsearch = true\n",
            self.get_config_file_contents(),
        )

    def test_set_with_triple_nesting(self):
        self.run_cmd(
            "configure set default.s3.signature_version s3v4",
        )
        self.assertEqual(
            "[default]\n"
            "s3 =\n"
            "    signature_version = s3v4\n",
            self.get_config_file_contents(),
        )

    def test_set_with_existing_config(self):
        self.set_config_file_contents(
            "[default]\n"
            "region = us-west-2\n"
            "ec2 =\n"
            "    signature_version = v4\n"
        )
        self.run_cmd(
            "configure set default.s3.signature_version s3v4",
        )
        self.assertEqual(
            "[default]\n"
            "region = us-west-2\n"
            "ec2 =\n"
            "    signature_version = v4\n"
            "s3 =\n"
            "    signature_version = s3v4\n",
            self.get_config_file_contents(),
        )

    def test_set_with_new_profile(self):
        self.set_config_file_contents(
            "[default]\n"
            "s3 =\n"
            "    signature_version = s3v4\n"
        )
        self.run_cmd(
            "configure set profile.dev.s3.signature_version s3v4",
        )
        self.assertEqual(
            "[default]\n"
            "s3 =\n"
            "    signature_version = s3v4\n"
            "[profile dev]\n"
            "s3 =\n"
            "    signature_version = s3v4\n",
            self.get_config_file_contents(),
        )

    def test_override_existing_value(self):
        self.set_config_file_contents(
            "[default]\n" "s3 =\n"
            "    signature_version = v4\n"
        )
        self.run_cmd(
            "configure set default.s3.signature_version NEWVALUE",
        )
        self.assertEqual(
            "[default]\n"
            "s3 =\n"
            "    signature_version = NEWVALUE\n",
            self.get_config_file_contents(),
        )

    def test_get_nested_attribute(self):
        self.set_config_file_contents(
            "[default]\n"
            "s3 =\n"
            "    signature_version = v4\n"
        )
        stdout, _, _ = self.run_cmd(
            "configure get default.s3.signature_version"
        )

        self.assertEqual(stdout.strip(), "v4")
        stdout, _, _ = self.run_cmd(
            "configure get default.bad.doesnotexist", expected_rc=1
        )
        self.assertEqual(stdout, "")

    def test_can_handle_empty_section(self):
        self.set_config_file_contents("[default]\n")
        self.run_cmd(
            "configure set preview.cloudfront true",
        )
        self.run_cmd(
            "configure set region us-west-2",
        )
        self.assertEqual(
            "[default]\n"
            "region = us-west-2\n"
            "[preview]\n"
            "cloudfront = true\n",
            self.get_config_file_contents(),
        )
Ejemplo n.º 9
0
class TestOutFileQueryArguments(BaseAWSCommandParamsTest):
    def setUp(self):
        self.files = FileCreator()
        super(TestOutFileQueryArguments, self).setUp()

    def tearDown(self):
        self.files.remove_all()
        super(TestOutFileQueryArguments, self).tearDown()

    def test_saves_cert_to_file_for_create_certificate_from_csr(self):
        self.parsed_response = {
            'certificatePem': 'cert...',
            'ResponseMetadata': {
                'HTTPStatusCode': 200,
                'RequestId': 'request-id'
            }
        }
        outfile = self.files.full_path('cert.pem')
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        self.run_cmd(cmdline, 0)
        self.assertTrue(os.path.exists(outfile))
        with open(outfile) as fp:
            self.assertEqual('cert...', fp.read())

    def test_saves_files_for_create_keys_and_cert(self):
        self.parsed_response = {
            'certificatePem': 'cert...',
            'keyPair': {
                'PublicKey': 'public',
                'PrivateKey': 'private'
            },
            'ResponseMetadata': {
                'HTTPStatusCode': 200,
                'RequestId': 'request-id'
            }
        }
        out_cert = self.files.full_path('cert.pem')
        out_pub = self.files.full_path('key_rsa.pub')
        out_priv = self.files.full_path('key_rsa')
        cmdline = 'iot create-keys-and-certificate'
        cmdline += ' --certificate-pem-outfile ' + out_cert
        cmdline += ' --public-key-outfile ' + out_pub
        cmdline += ' --private-key-outfile ' + out_priv
        self.run_cmd(cmdline, 0)
        self.assertTrue(os.path.exists(out_cert))
        self.assertTrue(os.path.exists(out_pub))
        self.assertTrue(os.path.exists(out_priv))
        with open(out_cert) as fp:
            self.assertEqual('cert...', fp.read())
        with open(out_pub) as fp:
            self.assertEqual('public', fp.read())
        with open(out_priv) as fp:
            self.assertEqual('private', fp.read())

    def test_bad_response(self):
        outfile = self.files.full_path('cert.pem')
        self.parsed_response = {
            'Error': {
                'Code': 'v1',
                'Message': 'v2',
                'Type': 'v3'
            },
            'ResponseMetadata': {
                'HTTPStatusCode': 403,
                'RequestId': 'request-id'
            }
        }
        self.http_response.status_code = 403
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        # The error message should be in the stderr.
        self.assert_params_for_cmd(
            cmdline,
            stderr_contains=self.parsed_response['Error']['Message'],
            expected_rc=255)

    def test_ensures_file_is_writable_before_sending(self):
        outfile = os.sep.join(['', 'does', 'not', 'exist_', 'file.txt'])
        self.parsed_response = {}
        cmdline = 'iot create-certificate-from-csr'
        cmdline += ' --certificate-signing-request "abc"'
        cmdline += ' --certificate-pem-outfile ' + outfile
        self.assert_params_for_cmd(cmdline,
                                   stderr_contains='Unable to write to file: ',
                                   expected_rc=255)
Ejemplo n.º 10
0
class TestCodeArtifactLogin(unittest.TestCase):

    prefix = ['codeartifact', 'login']

    def setUp(self):
        self.file_creator = FileCreator()
        self.test_pypi_rc_path = self.file_creator.full_path('pypirc')
        if not os.path.isdir(os.path.dirname(self.test_pypi_rc_path)):
            os.makedirs(os.path.dirname(self.test_pypi_rc_path))

        self.domain = 'domain'
        self.domain_owner = 'domain-owner'
        self.repository = 'repository'
        self.auth_token = 'auth-token'
        self.namespace = 'namespace'
        self.nuget_index_url_fmt = '{endpoint}v3/index.json'
        self.nuget_source_name = self.domain + '/' + self.repository
        self.duration = 3600
        self.expiration = time.time() + self.duration
        self.expiration_as_datetime = parse_timestamp(self.expiration)

        self.pypi_rc_path_patch = mock.patch(
            'awscli.customizations.codeartifact.login.TwineLogin'
            '.get_pypi_rc_path')
        self.pypi_rc_path_mock = self.pypi_rc_path_patch.start()
        self.pypi_rc_path_mock.return_value = self.test_pypi_rc_path

        self.subprocess_patch = mock.patch('subprocess.check_call')
        self.subprocess_mock = self.subprocess_patch.start()
        self.subprocess_check_output_patch = mock.patch(
            'subprocess.check_output')
        self.subprocess_check_out_mock = \
            self.subprocess_check_output_patch.start()
        self.cli_runner = CLIRunner()

    def tearDown(self):
        self.pypi_rc_path_patch.stop()
        self.subprocess_patch.stop()
        self.file_creator.remove_all()

    def _setup_cmd(self,
                   tool,
                   include_domain_owner=False,
                   dry_run=False,
                   include_duration_seconds=False,
                   include_namespace=False):
        package_format = CodeArtifactLogin.TOOL_MAP[tool]['package_format']
        self.endpoint = 'https://{domain}-{domainOwner}.codeartifact.aws.' \
            'a2z.com/{format}/{repository}/'.format(
                domain=self.domain,
                domainOwner=self.domain_owner,
                format=package_format,
                repository=self.repository
            )

        cmdline = copy.copy(self.prefix)
        cmdline.extend([
            '--domain',
            self.domain,
            '--repository',
            self.repository,
            '--tool',
            tool,
        ])

        if include_domain_owner:
            cmdline.extend(['--domain-owner', self.domain_owner])

        if dry_run:
            cmdline.append('--dry-run')

        if include_duration_seconds:
            cmdline.extend(['--duration-seconds', str(self.duration)])

        if include_namespace:
            cmdline.extend(['--namespace', self.namespace])

        self.cli_runner.add_response(
            AWSResponse(service_name='codeartifact',
                        operation_name='GetAuthorizationToken',
                        parsed_response={
                            "authorizationToken": self.auth_token,
                            "expiration": self.expiration_as_datetime
                        }))
        self.cli_runner.add_response(
            AWSResponse(service_name='codeartifact',
                        operation_name='GetRepositoryEndpoint',
                        parsed_response={"repositoryEndpoint": self.endpoint}))

        return cmdline

    def _get_nuget_commands(self):
        nuget_index_url = self.nuget_index_url_fmt.format(
            endpoint=self.endpoint)

        commands = []
        commands.append([
            'nuget', 'sources', 'add', '-name', self.nuget_source_name,
            '-source', nuget_index_url, '-username', 'aws', '-password',
            self.auth_token
        ])
        return commands

    def _get_dotnet_commands(self):
        nuget_index_url = self.nuget_index_url_fmt.format(
            endpoint=self.endpoint)

        commands = []
        commands.append([
            'dotnet', 'nuget', 'add', 'source', nuget_index_url, '--name',
            self.nuget_source_name, '--username', 'aws', '--password',
            self.auth_token
        ])
        return commands

    def _get_npm_commands(self, **kwargs):
        npm_cmd = 'npm.cmd' \
            if platform.system().lower() == 'windows' else 'npm'

        repo_uri = urlparse.urlsplit(self.endpoint)
        always_auth_config = '//{}{}:always-auth'.format(
            repo_uri.netloc, repo_uri.path)
        auth_token_config = '//{}{}:_authToken'.format(repo_uri.netloc,
                                                       repo_uri.path)

        scope = kwargs.get('scope')
        registry = '{}:registry'.format(scope) if scope else 'registry'

        commands = []
        commands.append([npm_cmd, 'config', 'set', registry, self.endpoint])
        commands.append([npm_cmd, 'config', 'set', always_auth_config, 'true'])
        commands.append(
            [npm_cmd, 'config', 'set', auth_token_config, self.auth_token])

        return commands

    def _get_pip_commands(self):
        pip_index_url_fmt = '{scheme}://aws:{auth_token}@{netloc}{path}simple/'
        repo_uri = urlparse.urlsplit(self.endpoint)
        pip_index_url = pip_index_url_fmt.format(scheme=repo_uri.scheme,
                                                 auth_token=self.auth_token,
                                                 netloc=repo_uri.netloc,
                                                 path=repo_uri.path)

        return [['pip', 'config', 'set', 'global.index-url', pip_index_url]]

    def _get_twine_commands(self):
        default_pypi_rc_fmt = '''\
[distutils]
index-servers=
    pypi
    codeartifact

[codeartifact]
repository: {repository_endpoint}
username: aws
password: {auth_token}'''
        default_pypi_rc = default_pypi_rc_fmt.format(
            repository_endpoint=self.endpoint, auth_token=self.auth_token)

        pypi_rc = RawConfigParser()
        if os.path.exists(self.test_pypi_rc_path):
            pypi_rc.read(self.test_pypi_rc_path)
            index_servers = pypi_rc.get('distutils', 'index-servers')
            servers = [
                server.strip() for server in index_servers.split('\n')
                if server.strip() != ''
            ]

            if 'codeartifact' not in servers:
                servers.append('codeartifact')
                pypi_rc.set('distutils', 'index-servers',
                            '\n' + '\n'.join(servers))

            if 'codeartifact' not in pypi_rc.sections():
                pypi_rc.add_section('codeartifact')

            pypi_rc.set('codeartifact', 'repository', self.endpoint)
            pypi_rc.set('codeartifact', 'username', 'aws')
            pypi_rc.set('codeartifact', 'password', self.auth_token)
        else:
            pypi_rc.readfp(StringIO(default_pypi_rc))

        pypi_rc_stream = StringIO()
        pypi_rc.write(pypi_rc_stream)
        pypi_rc_str = pypi_rc_stream.getvalue()
        pypi_rc_stream.close()

        return pypi_rc_str

    def _assert_expiration_printed_to_stdout(self, stdout):
        self.assertEqual(
            self.expiration_as_datetime.strftime("%Y-%m-%d %H:%M:%S"),
            stdout.split("at ")[1][0:19])

    def _assert_operations_called(self,
                                  package_format,
                                  result,
                                  include_domain_owner=False,
                                  include_duration_seconds=False):

        get_auth_token_kwargs = {'domain': self.domain}
        get_repo_endpoint_kwargs = {
            'domain': self.domain,
            'repository': self.repository,
            'format': package_format
        }

        if include_domain_owner:
            get_auth_token_kwargs['domainOwner'] = self.domain_owner
            get_repo_endpoint_kwargs['domainOwner'] = self.domain_owner

        if include_duration_seconds:
            get_auth_token_kwargs['durationSeconds'] = self.duration

        self.assertEqual(result.aws_requests, [
            AWSRequest(
                service_name='codeartifact',
                operation_name='GetAuthorizationToken',
                params=get_auth_token_kwargs,
            ),
            AWSRequest(
                service_name='codeartifact',
                operation_name='GetRepositoryEndpoint',
                params=get_repo_endpoint_kwargs,
            )
        ])

    def _assert_subprocess_execution(self, commands):
        expected_calls = [
            mock.call(
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            ) for command in commands
        ]
        self.subprocess_mock.assert_has_calls(expected_calls, any_order=True)

    def _assert_subprocess_check_output_execution(self, commands):
        expected_calls = [
            mock.call(
                command,
                stderr=subprocess.PIPE,
            ) for command in commands
        ]
        self.subprocess_check_out_mock.assert_has_calls(expected_calls,
                                                        any_order=True)

    def _assert_dry_run_execution(self, commands, stdout):
        self.subprocess_mock.assert_not_called()
        for command in commands:
            self.assertIn(' '.join(command), stdout)

    def _assert_pypi_rc_has_expected_content(self,
                                             pypi_rc_str,
                                             server,
                                             repo_url=None,
                                             username=None,
                                             password=None):
        pypi_rc = RawConfigParser()
        pypi_rc.readfp(StringIO(pypi_rc_str))

        self.assertIn('distutils', pypi_rc.sections())
        self.assertIn('index-servers', pypi_rc.options('distutils'))
        index_servers = pypi_rc.get('distutils', 'index-servers')
        index_servers = [
            index_server.strip() for index_server in index_servers.split('\n')
            if index_server.strip() != ''
        ]
        self.assertIn(server, index_servers)

        if repo_url or username or password:
            self.assertIn(server, pypi_rc.sections())

        if repo_url:
            self.assertIn('repository', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'repository'), repo_url)

        if username:
            self.assertIn('username', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'username'), username)

        if password:
            self.assertIn('password', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'password'), password)

    def test_nuget_login_without_domain_owner_without_duration_seconds(self):
        cmdline = self._setup_cmd(tool='nuget')
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_nuget_commands())

    def test_nuget_login_with_domain_owner_without_duration_seconds(self):
        cmdline = self._setup_cmd(tool='nuget', include_domain_owner=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_nuget_commands())

    def test_nuget_login_without_domain_owner_with_duration_seconds(self):
        cmdline = self._setup_cmd(tool='nuget', include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_nuget_commands())

    def test_nuget_login_with_domain_owner_duration_sections(self):
        cmdline = self._setup_cmd(tool='nuget',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_nuget_commands())

    def test_nuget_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='nuget', dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget', result=result)
        self._assert_dry_run_execution(self._get_nuget_commands(),
                                       result.stdout)

    def test_nuget_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='nuget',
                                  include_domain_owner=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_nuget_commands(),
                                       result.stdout)

    def test_nuget_login_with_duration_seconds_dry_run(self):
        cmdline = self._setup_cmd(tool='nuget',
                                  include_duration_seconds=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_nuget_commands(),
                                       result.stdout)

    def test_nuget_login_with_domain_owner_duration_seconds_dry_run(self):
        cmdline = self._setup_cmd(tool='nuget',
                                  include_domain_owner=True,
                                  include_duration_seconds=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_nuget_commands(),
                                       result.stdout)

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_without_domain_owner_without_duration_seconds(self):
        cmdline = self._setup_cmd(tool='dotnet')
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_dotnet_commands())

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_with_domain_owner_without_duration_seconds(self):
        cmdline = self._setup_cmd(tool='dotnet', include_domain_owner=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_dotnet_commands())

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_without_domain_owner_with_duration_seconds(self):
        cmdline = self._setup_cmd(tool='dotnet', include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_dotnet_commands())

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_with_domain_owner_duration_sections(self):
        cmdline = self._setup_cmd(tool='dotnet',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_check_output_execution(
            self._get_dotnet_commands())

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='dotnet', dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget', result=result)
        self._assert_dry_run_execution(self._get_dotnet_commands(),
                                       result.stdout)

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='dotnet',
                                  include_domain_owner=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_dotnet_commands(),
                                       result.stdout)

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_with_duration_seconds_dry_run(self):
        cmdline = self._setup_cmd(tool='dotnet',
                                  include_duration_seconds=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_dotnet_commands(),
                                       result.stdout)

    @mock.patch('awscli.customizations.codeartifact.login.is_windows', True)
    def test_dotnet_login_with_domain_owner_duration_seconds_dry_run(self):
        cmdline = self._setup_cmd(tool='dotnet',
                                  include_domain_owner=True,
                                  include_duration_seconds=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='nuget',
                                       include_domain_owner=True,
                                       include_duration_seconds=True,
                                       result=result)
        self._assert_dry_run_execution(self._get_dotnet_commands(),
                                       result.stdout)

    def test_npm_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='npm')
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='npm', dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm', result=result)
        self._assert_dry_run_execution(self._get_npm_commands(), result.stdout)

    def test_npm_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='npm', include_domain_owner=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm',
                                       result=result,
                                       include_domain_owner=True,
                                       include_duration_seconds=False)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='npm',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm',
                                       result=result,
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='npm',
                                  include_domain_owner=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm',
                                       result=result,
                                       include_domain_owner=True)
        self._assert_dry_run_execution(self._get_npm_commands(), result.stdout)

    def test_npm_login_with_namespace(self):
        cmdline = self._setup_cmd(tool='npm', include_namespace=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(
            self._get_npm_commands(scope='@{}'.format(self.namespace)))

    def test_npm_login_with_namespace_dry_run(self):
        cmdline = self._setup_cmd(tool='npm',
                                  include_namespace=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='npm', result=result)
        self._assert_dry_run_execution(
            self._get_npm_commands(scope='@{}'.format(self.namespace)),
            result.stdout)

    def test_pip_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='pip')
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='pip', dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi', result=result)
        self._assert_dry_run_execution(self._get_pip_commands(), result.stdout)

    def test_pip_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='pip', include_domain_owner=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='pip',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(result.stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='pip',
                                  include_domain_owner=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True)
        self._assert_dry_run_execution(self._get_pip_commands(), result.stdout)

    def test_pip_login_with_namespace(self):
        cmdline = self._setup_cmd(tool='pip', include_namespace=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 255)
        self._assert_operations_called(package_format='pypi', result=result)
        self.assertIn('Argument --namespace is not supported for pip',
                      result.stderr)

    def test_pip_login_with_namespace_dry_run(self):
        cmdline = self._setup_cmd(tool='pip',
                                  include_namespace=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 255)
        self._assert_operations_called(package_format='pypi', result=result)
        self.assertIn('Argument --namespace is not supported for pip',
                      result.stderr)

    def test_twine_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='twine')
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi', result=result)
        self._assert_expiration_printed_to_stdout(result.stdout)
        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='twine', dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi', result=result)
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))
        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=self._get_twine_commands(),
            server='codeartifact',
            repo_url=self.endpoint,
            username='******',
            password=self.auth_token)

    def test_twine_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='twine', include_domain_owner=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True)
        self._assert_expiration_printed_to_stdout(result.stdout)

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='twine',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(result.stdout)

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='twine',
                                  include_domain_owner=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 0)
        self._assert_operations_called(package_format='pypi',
                                       result=result,
                                       include_domain_owner=True)
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))
        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=self._get_twine_commands(),
            server='codeartifact',
            repo_url=self.endpoint,
            username='******',
            password=self.auth_token)

    def test_twine_login_with_namespace(self):
        cmdline = self._setup_cmd(tool='twine', include_namespace=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 255)
        self._assert_operations_called(package_format='pypi', result=result)
        self.assertIn('Argument --namespace is not supported for twine',
                      result.stderr)

    def test_twine_login_with_namespace_dry_run(self):
        cmdline = self._setup_cmd(tool='twine',
                                  include_namespace=True,
                                  dry_run=True)
        result = self.cli_runner.run(cmdline)
        self.assertEqual(result.rc, 255)
        self._assert_operations_called(package_format='pypi', result=result)
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))
        self.assertIn('Argument --namespace is not supported for twine',
                      result.stderr)
Ejemplo n.º 11
0
class TestCodeArtifactLogin(BaseAWSCommandParamsTest):

    prefix = 'codeartifact login'

    def setUp(self):
        super(TestCodeArtifactLogin, self).setUp()

        self.file_creator = FileCreator()
        self.test_pypi_rc_path = self.file_creator.full_path('pypirc')
        if not os.path.isdir(os.path.dirname(self.test_pypi_rc_path)):
            os.makedirs(os.path.dirname(self.test_pypi_rc_path))

        self.domain = 'domain'
        self.domain_owner = 'domain-owner'
        self.repository = 'repository'
        self.auth_token = 'auth-token'
        self.duration = 3600
        self.expiration = time.time() + self.duration
        self.expiration_as_datetime = parse_timestamp(self.expiration)

        self.pypi_rc_path_patch = mock.patch(
            'awscli.customizations.codeartifact.login.TwineLogin'
            '.get_pypi_rc_path')
        self.pypi_rc_path_mock = self.pypi_rc_path_patch.start()
        self.pypi_rc_path_mock.return_value = self.test_pypi_rc_path

        self.subprocess_patch = mock.patch('subprocess.check_call')
        self.subprocess_mock = self.subprocess_patch.start()

    def tearDown(self):
        super(TestCodeArtifactLogin, self).tearDown()
        self.pypi_rc_path_patch.stop()
        self.subprocess_patch.stop()
        self.file_creator.remove_all()

    def _setup_cmd(self,
                   tool,
                   include_domain_owner=False,
                   dry_run=False,
                   include_duration_seconds=False):
        package_format = CodeArtifactLogin.TOOL_MAP[tool]['package_format']
        self.endpoint = 'https://{domain}-{domainOwner}.codeartifact.aws.' \
            'a2z.com/{format}/{repository}/'.format(
                domain=self.domain,
                domainOwner=self.domain_owner,
                format=package_format,
                repository=self.repository
            )

        cmdline = self.prefix
        cmdline += ' --domain %s' % self.domain
        cmdline += ' --repository %s' % self.repository
        cmdline += ' --tool %s' % tool

        if include_domain_owner:
            cmdline += ' --domain-owner %s' % self.domain_owner

        if dry_run:
            cmdline += ' --dry-run'

        if include_duration_seconds:
            cmdline += ' --duration-seconds %s' % self.duration

        # Responses from calls to services.
        self.parsed_responses = [
            {
                "authorizationToken": self.auth_token,
                "expiration": self.expiration
            },  # GetAuthorizationToken
            {
                "repositoryEndpoint": self.endpoint
            },  # GetRepositoryEndpoint
        ]

        return cmdline

    def _get_npm_commands(self):
        npm_cmd = 'npm.cmd' \
            if platform.system().lower() == 'windows' else 'npm'

        repo_uri = urlparse.urlsplit(self.endpoint)
        always_auth_config = '//{}{}:always-auth'.format(
            repo_uri.netloc, repo_uri.path)
        auth_token_config = '//{}{}:_authToken'.format(repo_uri.netloc,
                                                       repo_uri.path)

        commands = []
        commands.append([npm_cmd, 'config', 'set', 'registry', self.endpoint])
        commands.append([npm_cmd, 'config', 'set', always_auth_config, 'true'])
        commands.append(
            [npm_cmd, 'config', 'set', auth_token_config, self.auth_token])

        return commands

    def _get_pip_commands(self):
        pip_index_url_fmt = '{scheme}://aws:{auth_token}@{netloc}{path}simple/'
        repo_uri = urlparse.urlsplit(self.endpoint)
        pip_index_url = pip_index_url_fmt.format(scheme=repo_uri.scheme,
                                                 auth_token=self.auth_token,
                                                 netloc=repo_uri.netloc,
                                                 path=repo_uri.path)

        return [['pip', 'config', 'set', 'global.index-url', pip_index_url]]

    def _get_twine_commands(self):
        default_pypi_rc_fmt = '''\
[distutils]
index-servers=
    pypi
    codeartifact

[codeartifact]
repository: {repository_endpoint}
username: aws
password: {auth_token}'''
        default_pypi_rc = default_pypi_rc_fmt.format(
            repository_endpoint=self.endpoint, auth_token=self.auth_token)

        pypi_rc = RawConfigParser()
        if os.path.exists(self.test_pypi_rc_path):
            pypi_rc.read(self.test_pypi_rc_path)
            index_servers = pypi_rc.get('distutils', 'index-servers')
            servers = [
                server.strip() for server in index_servers.split('\n')
                if server.strip() != ''
            ]

            if 'codeartifact' not in servers:
                servers.append('codeartifact')
                pypi_rc.set('distutils', 'index-servers',
                            '\n' + '\n'.join(servers))

            if 'codeartifact' not in pypi_rc.sections():
                pypi_rc.add_section('codeartifact')

            pypi_rc.set('codeartifact', 'repository', self.endpoint)
            pypi_rc.set('codeartifact', 'username', 'aws')
            pypi_rc.set('codeartifact', 'password', self.auth_token)
        else:
            pypi_rc.readfp(StringIO(default_pypi_rc))

        pypi_rc_stream = StringIO()
        pypi_rc.write(pypi_rc_stream)
        pypi_rc_str = pypi_rc_stream.getvalue()
        pypi_rc_stream.close()

        return pypi_rc_str

    def _assert_expiration_printed_to_stdout(self, stdout):
        self.assertEqual(
            self.expiration_as_datetime.strftime("%Y-%m-%d %H:%M:%S"),
            stdout.split("at ")[1][0:19])

    def _assert_operations_called(self,
                                  package_format,
                                  include_domain_owner=False,
                                  include_duration_seconds=False):
        self.assertEqual(len(self.operations_called), 2)

        get_auth_token_kwargs = {'domain': self.domain}
        get_repo_endpoint_kwargs = {
            'domain': self.domain,
            'repository': self.repository,
            'format': package_format
        }

        if include_domain_owner:
            get_auth_token_kwargs['domainOwner'] = self.domain_owner
            get_repo_endpoint_kwargs['domainOwner'] = self.domain_owner

        if include_duration_seconds:
            get_auth_token_kwargs['durationSeconds'] = self.duration

        self.assertEqual(self.operations_called[0][0].name,
                         'GetAuthorizationToken')
        self.assertEqual(self.operations_called[0][1], get_auth_token_kwargs)

        self.assertEqual(self.operations_called[1][0].name,
                         'GetRepositoryEndpoint')
        self.assertEqual(self.operations_called[1][1],
                         get_repo_endpoint_kwargs)

    def _assert_subprocess_execution(self, commands):
        expected_calls = [
            mock.call(
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            ) for command in commands
        ]
        self.subprocess_mock.assert_has_calls(expected_calls, any_order=True)

    def _assert_dry_run_execution(self, commands, stdout):
        self.subprocess_mock.assert_not_called()
        for command in commands:
            self.assertIn(' '.join(command), stdout)

    def _assert_pypi_rc_has_expected_content(self,
                                             pypi_rc_str,
                                             server,
                                             repo_url=None,
                                             username=None,
                                             password=None):
        pypi_rc = RawConfigParser()
        pypi_rc.readfp(StringIO(pypi_rc_str))

        self.assertIn('distutils', pypi_rc.sections())
        self.assertIn('index-servers', pypi_rc.options('distutils'))
        index_servers = pypi_rc.get('distutils', 'index-servers')
        index_servers = [
            index_server.strip() for index_server in index_servers.split('\n')
            if index_server.strip() != ''
        ]
        self.assertIn(server, index_servers)

        if repo_url or username or password:
            self.assertIn(server, pypi_rc.sections())

        if repo_url:
            self.assertIn('repository', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'repository'), repo_url)

        if username:
            self.assertIn('username', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'username'), username)

        if password:
            self.assertIn('password', pypi_rc.options(server))
            self.assertEqual(pypi_rc.get(server, 'password'), password)

    def test_npm_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='npm')
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='npm')
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='npm', dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='npm')
        self._assert_dry_run_execution(self._get_npm_commands(), stdout)

    def test_npm_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='npm', include_domain_owner=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='npm',
                                       include_domain_owner=True,
                                       include_duration_seconds=False)
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='npm',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='npm',
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_npm_commands())

    def test_npm_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='npm',
                                  include_domain_owner=True,
                                  dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='npm',
                                       include_domain_owner=True)
        self._assert_dry_run_execution(self._get_npm_commands(), stdout)

    def test_pip_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='pip')
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi')
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='pip', dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi')
        self._assert_dry_run_execution(self._get_pip_commands(), stdout)

    def test_pip_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='pip', include_domain_owner=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True)
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='pip',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(stdout)
        self._assert_subprocess_execution(self._get_pip_commands())

    def test_pip_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='pip',
                                  include_domain_owner=True,
                                  dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True)
        self._assert_dry_run_execution(self._get_pip_commands(), stdout)

    def test_twine_login_without_domain_owner(self):
        cmdline = self._setup_cmd(tool='twine')
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi')
        self._assert_expiration_printed_to_stdout(stdout)
        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_without_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='twine', dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi')
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))
        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=self._get_twine_commands(),
            server='codeartifact',
            repo_url=self.endpoint,
            username='******',
            password=self.auth_token)

    def test_twine_login_with_domain_owner(self):
        cmdline = self._setup_cmd(tool='twine', include_domain_owner=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True)
        self._assert_expiration_printed_to_stdout(stdout)

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_with_domain_owner_duration(self):
        cmdline = self._setup_cmd(tool='twine',
                                  include_domain_owner=True,
                                  include_duration_seconds=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True,
                                       include_duration_seconds=True)
        self._assert_expiration_printed_to_stdout(stdout)

        with open(self.test_pypi_rc_path) as f:
            test_pypi_rc_str = f.read()

        self._assert_pypi_rc_has_expected_content(pypi_rc_str=test_pypi_rc_str,
                                                  server='codeartifact',
                                                  repo_url=self.endpoint,
                                                  username='******',
                                                  password=self.auth_token)

    def test_twine_login_with_domain_owner_dry_run(self):
        cmdline = self._setup_cmd(tool='twine',
                                  include_domain_owner=True,
                                  dry_run=True)
        stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
        self._assert_operations_called(package_format='pypi',
                                       include_domain_owner=True)
        self.assertFalse(os.path.exists(self.test_pypi_rc_path))
        self._assert_pypi_rc_has_expected_content(
            pypi_rc_str=self._get_twine_commands(),
            server='codeartifact',
            repo_url=self.endpoint,
            username='******',
            password=self.auth_token)