Beispiel #1
0
def extract_metadata(filename, temp_dir, module=None):
    """
    Pulls the module's metadata file out of the module's tarball and updates the
    module instance with its contents. The module instance itself is updated
    as part of this call. It is up to the caller to delete the temp_dir after
    this executes.

    :param filename: full path to the module file
    :type  filename: str

    :param temp_dir: location the module's files should be extracted to;
           must exist prior to this call
    :type  temp_dir: str

    :param module: module instance with name, author, version to help find
           the directory which contains metadata.json (optional)
    :type  module: Module

    :raise InvalidTarball: if the module file cannot be opened
    :raise MissingModuleFile: if the module's metadata file cannot be found
    """
    if module is None:
        metadata = _extract_non_standard_json(filename, temp_dir)
        return json.loads(metadata)

    # Attempt to load from the standard metadata file location. If it's not
    # found, try the brute force approach. If it's still not found, that call
    # will raise the appropriate MissingModuleFile exception.
    try:
        metadata = _extract_json(module, filename, temp_dir)
        return json.loads(metadata)
    except MissingModuleFile:
        metadata = _extract_non_standard_json(filename, temp_dir)
        return json.loads(metadata)
    def test_run_no_group(self):
        # Setup
        data = {OPTION_GROUP_ID.keyword: "test-group"}

        self.server_mock.request.return_value = 200, []

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        # Group lookup call
        call_args = self.server_mock.request.call_args_list[0]
        self.assertEqual("POST", call_args[0][0])

        url = call_args[0][1]
        self.assertTrue(url.endswith("/repo_groups/search/"))

        body = json.loads(call_args[0][2])
        self.assertEqual(body["criteria"]["filters"]["id"], "test-group")

        # Output
        self.assertEqual(2, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0])
        self.assertEqual("not-found", self.prompt.get_write_tags()[1])
    def test_run(self):
        # Setup
        data = {
            OPTION_GROUP_ID.keyword: "test-group",
            OPTION_NAME.keyword: "Group",
            OPTION_DESCRIPTION.keyword: "Description",
            OPTION_NOTES.keyword: {"a": "a", "b": "b"},
        }

        self.server_mock.request.return_value = 201, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual("POST", self.server_mock.request.call_args[0][0])

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual(body["id"], "test-group")
        self.assertEqual(body["display_name"], "Group")
        self.assertEqual(body["description"], "Description")
        self.assertEqual(body["notes"], {"a": "a", "b": "b"})

        self.assertEqual(1, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
    def test_run(self):
        # Setup
        data = {
            'from-repo-id': 'from',
            'to-repo-id': 'to'
        }

        self.server_mock.request.return_value = 202, self.task()

        mock_poll = mock.MagicMock().poll
        self.command.poll = mock_poll

        # Test
        self.command.run(**data)

        # Verify
        call_args = self.server_mock.request.call_args[0]
        self.assertEqual('POST', call_args[0])
        self.assertTrue(call_args[1].endswith('/to/actions/associate/'))

        body = json.loads(call_args[2])
        self.assertEqual(body['source_repo_id'], 'from')
        self.assertEqual(body['criteria']['type_ids'], [constants.TYPE_PUPPET_MODULE])

        self.assertEqual(1, mock_poll.call_count)
Beispiel #5
0
    def test_run_through_cli(self):
        """
        This test isn't complete, but is at minimum being included to verify
        903262 (--only-newest being parsed correctly). Ideally this should be
        flushed out to test all of the options.

        The test above kicks in after okaara has parsed the user input,
        simulating what okaara would pass to the command itself. That's fine,
        but doesn't pick up on issues in the parsing itself. This test will
        simulate the string entered by the user from the command line and
        force okaara to do the parsing and hand those results to the command.
        """

        # Setup
        self.server_mock.request.return_value = 201, {}

        # Test
        command = repo.RpmRepoCreateCommand(self.context)
        self.cli.add_command(command)
        self.cli.run("create --repo-id r --only-newest true".split())

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        self.assertEqual(body['id'], 'r')
        self.assertEqual(body['importer_config']['newest'], True) # not the string "true"
    def test_migrate(self, start_logging_mock, listdir_mock, mock_plugin_definitions,
                     mock_drop_indices):
        """
        Ensure that migrate() imports types on a clean types database.
        """
        migration.migrate()
        self.assertTrue(mock_drop_indices.called)

        all_collection_names = types_db.all_type_collection_names()
        self.assertEqual(len(all_collection_names), 1)

        self.assertEqual(['units_test_type_id'], all_collection_names)

        # Let's make sure we loaded the type definitions correctly
        db_type_definitions = types_db.all_type_definitions()
        self.assertEquals(len(db_type_definitions), 1)
        test_json = json.loads(_test_type_json)
        for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']:
            self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute])

        # Now let's ensure that we have the correct indexes
        collection = types_db.type_units_collection('test_type_id')
        indexes = collection.index_information()
        self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)])
        # Make sure we have the unique constraint on all three attributes
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True)
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'],
                         [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)])
        # Make sure we indexed attributes 1 and 3
        self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)])
        self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)])
        # Make sure we only have the indexes that we've hand inspected here
        self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1',
                                          u'attribute_1_1', u'attribute_3_1'])
    def test_to_json(self):
        # Setup
        metadata = RepositoryMetadata()
        metadata.update_from_json(VALID_REPO_METADATA_JSON)

        # Test
        serialized = metadata.to_json()

        # Verify
        parsed = json.loads(serialized)

        self.assertEqual(2, len(parsed))

        sorted_modules = sorted(parsed, key=lambda x : x['name'])

        self.assertEqual(4, len(sorted_modules[0]))
        self.assertEqual(sorted_modules[0]['name'], 'common')
        self.assertEqual(sorted_modules[0]['author'], 'lab42')
        self.assertEqual(sorted_modules[0]['version'], '0.0.1')
        self.assertEqual(sorted_modules[0]['tag_list'], [])

        self.assertEqual(4, len(sorted_modules[1]))
        self.assertEqual(sorted_modules[1]['name'], 'postfix')
        self.assertEqual(sorted_modules[1]['author'], 'lab42')
        self.assertEqual(sorted_modules[1]['version'], '0.0.2')
        self.assertEqual(sorted_modules[1]['tag_list'], ['postfix', 'applications'])
Beispiel #8
0
    def test_to_json(self):
        # Setup
        metadata = RepositoryMetadata()
        metadata.update_from_json(VALID_REPO_METADATA_JSON)

        # Test
        serialized = metadata.to_json()

        # Verify
        parsed = json.loads(serialized)

        self.assertEqual(2, len(parsed))

        sorted_modules = sorted(parsed, key=lambda x: x["name"])

        self.assertEqual(4, len(sorted_modules[0]))
        self.assertEqual(sorted_modules[0]["name"], "common")
        self.assertEqual(sorted_modules[0]["author"], "lab42")
        self.assertEqual(sorted_modules[0]["version"], "0.0.1")
        self.assertEqual(sorted_modules[0]["tag_list"], [])

        self.assertEqual(4, len(sorted_modules[1]))
        self.assertEqual(sorted_modules[1]["name"], "postfix")
        self.assertEqual(sorted_modules[1]["author"], "lab42")
        self.assertEqual(sorted_modules[1]["version"], "0.0.2")
        self.assertEqual(sorted_modules[1]["tag_list"], ["postfix", "applications"])
Beispiel #9
0
    def _interpret_operation_report(output, operation, full_name):
        """
        Makes a best effort to locate and deserialize the JSON output from the
        "puppet module" tool. The tool does not document exactly how this will
        be included in the output, so this method returns an empty dictionary if
        a JSON-serialized report is not found. It also logs a warning in that
        case.

        :param output:      text output from the "puppet module" tool, which
                            presumably includes some JSON
        :type  output:      str
        :param operation:   one of "install", "upgrade", "uninstall", used only
                            for logging.
        :type  operation:   str
        :param full_name:   full name in form "author/title", used only for
                            logging

        :return:    deserialized JSON output from the "puppet module" tool
        :rtype:     dict
        """
        try:
            potential_json = output.split('\n')[-2]
            operation_report = json.loads(potential_json)
        # if there was any error trying to parse puppet's JSON output, make
        # an empty report
        except (IndexError, ValueError):
            logger.warning('failed to parse JSON output from %s of %s' % (operation, full_name))
            operation_report = {}
        return operation_report
Beispiel #10
0
    def test_run(self):
        # Setup
        repo_id = 'test-repo'
        data = {
            OPTION_REPO_ID.keyword : repo_id,
            OPTION_NAME.keyword : 'Test Repository',
            OPTION_DESCRIPTION.keyword : 'Repository Description',
            OPTION_NOTES.keyword : {'a' : 'a', 'b' : 'b'},
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('PUT', self.server_mock.request.call_args[0][0])

        url = self.server_mock.request.call_args[0][1]
        self.assertTrue(url.endswith('/repositories/%s/' % repo_id))

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual(body['delta']['display_name'], 'Test Repository')
        self.assertEqual(body['delta']['description'], 'Repository Description')
        self.assertEqual(body['delta']['notes'], {'a' : 'a', 'b' : 'b'})

        self.assertEqual(1, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
    def test_pulp_manage_db_loads_types(self, listdir_mock):
        """
        Test calling pulp-manage-db imports types on a clean types database.
        """
        manage.main()

        all_collection_names = types_db.all_type_collection_names()
        self.assertEqual(len(all_collection_names), 1)

        self.assertEqual(['units_test_type_id'], all_collection_names)

        # Let's make sure we loaded the type definitions correctly
        db_type_definitions = types_db.all_type_definitions()
        self.assertEquals(len(db_type_definitions), 1)
        test_json = json.loads(_test_type_json)
        for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']:
            self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute])

        # Now let's ensure that we have the correct indexes 
        collection = types_db.type_units_collection('test_type_id')
        indexes = collection.index_information()
        self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)])
        # Make sure we have the unique constraint on all three attributes
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True)
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'],
                         [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)])
        # Make sure we indexes attributes 1 and 3
        self.assertEqual(indexes['attribute_1_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)])
        self.assertEqual(indexes['attribute_3_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)])
        # Make sure we only have the indexes that we've hand inspected here
        self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1',
                                          u'attribute_1_1', u'attribute_3_1'])
    def test_run_no_group(self):
        # Setup
        data = {
            OPTION_GROUP_ID.keyword : 'test-group',
        }

        self.server_mock.request.return_value = 200, []

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        # Group lookup call
        call_args = self.server_mock.request.call_args_list[0]
        self.assertEqual('POST', call_args[0][0])

        url = call_args[0][1]
        self.assertTrue(url.endswith('/repo_groups/search/'))

        body = json.loads(call_args[0][2])
        self.assertEqual(body['criteria']['filters']['id'], 'test-group')

        # Output
        self.assertEqual(2, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0])
        self.assertEqual('not-found', self.prompt.get_write_tags()[1])
Beispiel #13
0
    def test_run(self):
        # Setup
        data = {
            OPTION_REPO_ID.keyword : 'test-repo',
            OPTION_NAME.keyword : 'Test Repository',
            OPTION_DESCRIPTION.keyword : 'Repository Description',
            OPTION_NOTES.keyword : ['a=a', 'b=b'],
        }

        self.server_mock.request.return_value = 201, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('POST', self.server_mock.request.call_args[0][0])

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual(body['id'], 'test-repo')
        self.assertEqual(body['display_name'], 'Test Repository')
        self.assertEqual(body['description'], 'Repository Description')
        self.assertEqual(body['notes'], {'a' : 'a', 'b' : 'b'})

        self.assertEqual(1, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
    def test_run(self):
        # Setup
        data = {
            OPTION_GROUP_ID.keyword : 'test-group',
            OPTION_NAME.keyword : 'Group',
            OPTION_DESCRIPTION.keyword : 'Description',
            OPTION_NOTES.keyword : {'a' : 'a', 'b' : 'b'},
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('PUT', self.server_mock.request.call_args[0][0])

        url = self.server_mock.request.call_args[0][1]
        self.assertTrue(url.endswith('/repo_groups/test-group/'))

        body = self.server_mock.request.call_args[0][2]
        delta = json.loads(body)
        self.assertTrue('display-name' not in delta)
        self.assertEqual(delta['display_name'], 'Group')
        self.assertEqual(delta['description'], 'Description')
        self.assertEqual(delta['notes'], {'a' : 'a', 'b' : 'b'})
Beispiel #15
0
    def _do_request(self, request_type, uri, params, additional_headers, serialize_json=True):
        """
        Override the base class controller to allow for less deterministic
        responses due to integration with the dispatch package.
        """

        # Use the default headers established at setup and override/add any
        headers = dict(PulpWebserviceTests.HEADERS)
        if additional_headers is not None:
            headers.update(additional_headers)

        # Serialize the parameters if any are specified
        if params is None:
            params = {}

        if serialize_json:
            params = json.dumps(params)

        # Invoke the API
        f = getattr(PulpWebserviceTests.TEST_APP, request_type)
        response = f('http://localhost' + uri, params=params, headers=headers, expect_errors=True)

        # Collect return information and deserialize it
        status = response.status
        try:
            body = json.loads(response.body)
        except ValueError:
            body = None

        return status, body
Beispiel #16
0
    def test_run(self):
        # Setup
        data = {
            OPTION_REPO_ID.keyword: "test-repo",
            OPTION_NAME.keyword: "Test Repository",
            OPTION_DESCRIPTION.keyword: "Repository Description",
            OPTION_NOTES.keyword: ["a=a", "b=b"],
        }
        self.command.default_notes = {"foo": "bar"}

        self.server_mock.request.return_value = 201, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual("POST", self.server_mock.request.call_args[0][0])

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual(body["id"], "test-repo")
        self.assertEqual(body["display_name"], "Test Repository")
        self.assertEqual(body["description"], "Repository Description")
        self.assertEqual(body["notes"], {"a": "a", "b": "b", "foo": "bar"})
        self.assertEqual(body["distributors"], [])
        self.assertEqual(body["importer_type_id"], None)

        self.assertEqual(1, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
    def test_unset_queries(self):
        # make sure an empty list gets sent as the new value for "queries",
        # and definitely not None
        data = {
            options.OPTION_REPO_ID.keyword : 'test-repo',
            options.OPTION_NAME.keyword : 'Test Name',
            options.OPTION_DESCRIPTION.keyword : 'Test Description',
            options.OPTION_NOTES.keyword : {'a' : 'a'},
            cudl.OPTION_FEED.keyword : 'http://localhost',
            cudl.OPTION_HTTP.keyword : 'true',
            cudl.OPTION_HTTPS.keyword : 'true',
            cudl.OPTION_QUERY.keyword : None,
            cudl.OPTION_QUERIES_UPDATE.keyword : []
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        expected_config = {
            u'feed' : u'http://localhost',
            u'queries' : [], # this is the key part of this test
            }
        self.assertEqual(expected_config, body['importer_config'])
    def test_queries_overrides_query(self):
        # make sure --queries overrides --query, which is deprecated
        data = {
            options.OPTION_REPO_ID.keyword : 'test-repo',
            options.OPTION_NAME.keyword : 'Test Name',
            options.OPTION_DESCRIPTION.keyword : 'Test Description',
            options.OPTION_NOTES.keyword : {'a' : 'a'},
            cudl.OPTION_FEED.keyword : 'http://localhost',
            cudl.OPTION_HTTP.keyword : 'true',
            cudl.OPTION_HTTPS.keyword : 'true',
            cudl.OPTION_QUERY.keyword : ['q1', 'q2'],
            cudl.OPTION_QUERIES.keyword : ['x', 'y']
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        expected_config = {
            u'feed' : u'http://localhost',
            u'queries' : [u'x', u'y'],
            }
        self.assertEqual(expected_config, body['importer_config'])
    def test_run(self):
        # Setup
        data = {
            OPTION_GROUP_ID.keyword: "test-group",
            OPTION_NAME.keyword: "Group",
            OPTION_DESCRIPTION.keyword: "Description",
            OPTION_NOTES.keyword: {"a": "a", "b": "b"},
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual("PUT", self.server_mock.request.call_args[0][0])

        url = self.server_mock.request.call_args[0][1]
        self.assertTrue(url.endswith("/repo_groups/test-group/"))

        body = self.server_mock.request.call_args[0][2]
        delta = json.loads(body)
        self.assertTrue("display-name" not in delta)
        self.assertEqual(delta["display_name"], "Group")
        self.assertEqual(delta["description"], "Description")
        self.assertEqual(delta["notes"], {"a": "a", "b": "b"})
Beispiel #20
0
def load_plugin_config(config_file_name):
    """
    @type config_file_name: str
    @rtype: dict
    """
    _LOG.debug('Loading config file: %s' % config_file_name)
    contents = read_content(config_file_name)
    cfg = json.loads(contents)
    return cfg
    def test_adds_repo_to_search(self):
        data = {OPTION_GROUP_ID.keyword: "test-group", FLAG_ALL.keyword: False, OPTION_REPO_ID.keyword: ["repo1"]}
        self.server_mock.request.return_value = 200, {}

        self.command.run(**data)

        criteria = json.loads(self.server_mock.request.call_args[0][2])["criteria"]

        self.assertEqual(criteria["filters"]["id"]["$in"], ["repo1"])
    def test_from_dict(self):
        # Setup
        data = json.loads(VALID_MODULE_METADATA_JSON)

        # Test
        module = Module.from_dict(data)

        # Verify
        self.assert_valid_module(module)
    def test_repo_id_and_all(self):
        # --all should not prevent other filters from being added.
        data = {OPTION_GROUP_ID.keyword: "test-group", FLAG_ALL.keyword: False, OPTION_REPO_ID.keyword: ["repo1"]}
        self.server_mock.request.return_value = 200, {}

        self.command.run(**data)

        criteria = json.loads(self.server_mock.request.call_args[0][2])["criteria"]

        self.assertEqual(criteria["filters"]["id"]["$in"], ["repo1"])
Beispiel #24
0
    def update_from_json(self, metadata_json):
        """
        Takes the module's metadata in JSON format and merges it into this
        instance.

        :param metadata_json: module metadata in JSON
        :type  metadata_json: str
        """
        parsed = json.loads(metadata_json)
        self.update_from_dict(parsed)
    def test_run(self):
        # Setup
        data = {
            OPTION_GROUP_ID.keyword : 'test-group',
        }

        return_values = [
            (200, [{'repo_ids' : ['repo-1']}]), # return from search groups call
            (200, [{'id' : 'a'}]), # return from the repo search call
        ]

        self.server_mock.request.side_effect = return_values

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(2, self.server_mock.request.call_count)

        # Group lookup call
        call_args = self.server_mock.request.call_args_list[0]
        self.assertEqual('POST', call_args[0][0])

        url = call_args[0][1]
        self.assertTrue(url.endswith('/repo_groups/search/'))

        body = json.loads(call_args[0][2])
        self.assertEqual(body['criteria']['filters']['id'], 'test-group')

        # Repo lookup call
        call_args = self.server_mock.request.call_args_list[1]
        self.assertEqual('POST', call_args[0][0])
        url = call_args[0][1]
        self.assertTrue(url.endswith('/repositories/search/'))

        body = json.loads(call_args[0][2])
        self.assertEqual(body['criteria']['filters']['id'], {'$in' : ['repo-1']})

        # Output
        self.assertEqual(2, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0])
        self.assertEqual(TAG_DOCUMENT, self.prompt.get_write_tags()[1])
Beispiel #26
0
    def update_from_json(self, json_string):
        """
        Updates this metadata instance with packages found in the given JSON
        document. This can be called multiple times to merge multiple
        repository metadata JSON documents into this instance.

        :param json_string: A JSON string
        :type json_string: basestr
        """
        parsed = json.loads(json_string)
        self.add_packages(parsed.pop('packages', []))
        self.data(parsed)
    def test_run(self):
        # Setup
        data = {OPTION_GROUP_ID.keyword: "test-group"}

        return_values = [
            (200, [{"repo_ids": ["repo-1"]}]),  # return from search groups call
            (200, [{"id": "a"}]),  # return from the repo search call
        ]

        self.server_mock.request.side_effect = return_values

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(2, self.server_mock.request.call_count)

        # Group lookup call
        call_args = self.server_mock.request.call_args_list[0]
        self.assertEqual("POST", call_args[0][0])

        url = call_args[0][1]
        self.assertTrue(url.endswith("/repo_groups/search/"))

        body = json.loads(call_args[0][2])
        self.assertEqual(body["criteria"]["filters"]["id"], "test-group")

        # Repo lookup call
        call_args = self.server_mock.request.call_args_list[1]
        self.assertEqual("POST", call_args[0][0])
        url = call_args[0][1]
        self.assertTrue(url.endswith("/repositories/search/"))

        body = json.loads(call_args[0][2])
        self.assertEqual(body["criteria"]["filters"]["id"], {"$in": ["repo-1"]})

        # Output
        self.assertEqual(2, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0])
        self.assertEqual(TAG_DOCUMENT, self.prompt.get_write_tags()[1])
    def test_run(self):
        # Setup
        data = {
            options.OPTION_REPO_ID.keyword: 'test-repo',
            options.OPTION_NAME.keyword: 'Test Name',
            options.OPTION_DESCRIPTION.keyword: 'Test Description',
            options.OPTION_NOTES.keyword: {'b': 'b'},
            self.options_bundle.opt_feed.keyword: 'http://localhost',
            repo_options.OPT_SERVE_HTTP.keyword: True,
            repo_options.OPT_SERVE_HTTPS.keyword: True,
            repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_RPM],
            repo_options.OPT_CHECKSUM_TYPE.keyword: 'sha1',
            repo_options.OPT_UPDATEINFO_CHECKSUM_TYPE.keyword: 'md5',
            repo_options.OPT_REPOVIEW.keyword: True,
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        command = repo_create_update.RpmRepoUpdateCommand(self.context)
        command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        delta = body['delta']
        self.assertEqual(delta['display_name'], 'Test Name')
        self.assertEqual(delta['description'], 'Test Description')
        self.assertEqual(delta['notes'], {'b': 'b'})

        yum_imp_config = body['importer_config']
        self.assertEqual(yum_imp_config[constants.KEY_FEED], 'http://localhost')
        self.assertEqual(yum_imp_config[rpm_constants.CONFIG_SKIP], [ids.TYPE_ID_RPM])

        yum_dist_config = body['distributor_configs'][ids.YUM_DISTRIBUTOR_ID]
        self.assertEqual(yum_dist_config['http'], True)
        self.assertEqual(yum_dist_config['https'], True)
        self.assertEqual(yum_dist_config['skip'], [ids.TYPE_ID_RPM])
        self.assertEqual(yum_dist_config['checksum_type'], 'sha1')
        self.assertEqual(yum_dist_config['updateinfo_checksum_type'], 'md5')
        self.assertEqual(yum_dist_config['repoview'], True)
        self.assertEqual(yum_dist_config['generate_sqlite'], True)

        iso_dist_config = body['distributor_configs'][ids.EXPORT_DISTRIBUTOR_ID]
        self.assertEqual(iso_dist_config['http'], True)
        self.assertEqual(iso_dist_config['https'], True)
        self.assertEqual(iso_dist_config['skip'], [ids.TYPE_ID_RPM])
        self.assertEqual(iso_dist_config['checksum_type'], 'sha1')
        self.assertEqual(iso_dist_config['updateinfo_checksum_type'], 'md5')
    def test_run(self):
        # Setup
        data = {
            options.OPTION_REPO_ID.keyword : 'test-repo',
            options.OPTION_NAME.keyword : 'Test Name',
            options.OPTION_DESCRIPTION.keyword : 'Test Description',
            options.OPTION_NOTES.keyword : {'a' : 'a'},
            cudl.OPTION_FEED.keyword : 'http://localhost',
            cudl.OPTION_HTTP.keyword : 'true',
            cudl.OPTION_HTTPS.keyword : 'true',
            cudl.OPTION_QUERY.keyword : ['q1', 'q2'],
            cudl.OPTION_QUERIES.keyword : None
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('POST', self.server_mock.request.call_args[0][0])
        self.assertTrue(self.server_mock.request.call_args[0][1].endswith('/v2/repositories/'))

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual('test-repo', body['id'])
        self.assertEqual('Test Name', body['display_name'])
        self.assertEqual('Test Description', body['description'])

        expected_notes = {'a' : 'a', constants.REPO_NOTE_KEY : constants.REPO_NOTE_PUPPET}
        self.assertEqual(expected_notes, body['notes'])

        self.assertEqual(constants.IMPORTER_TYPE_ID, body['importer_type_id'])
        expected_config = {
            u'feed' : u'http://localhost',
            u'queries' : [u'q1', u'q2'],
        }
        self.assertEqual(expected_config, body['importer_config'])

        dist = body['distributors'][0]
        self.assertEqual(constants.DISTRIBUTOR_TYPE_ID, dist['distributor_type'])
        self.assertEqual(True, dist['auto_publish'])
        self.assertEqual(constants.DISTRIBUTOR_ID, dist['distributor_id'])

        expected_config = {
            u'serve_http' : True,
            u'serve_https' : True,
        }
        self.assertEqual(expected_config, dist['distributor_config'])

        self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
    def test_adds_repo_to_search(self):
        data = {
            OPTION_GROUP_ID.keyword : 'test-group',
            FLAG_ALL.keyword : False,
            OPTION_REPO_ID.keyword : ['repo1']
        }
        self.server_mock.request.return_value = 200, {}

        self.command.run(**data)

        criteria = json.loads(self.server_mock.request.call_args[0][2])['criteria']

        self.assertEqual(criteria['filters']['id']['$in'], ['repo1'])
Beispiel #31
0
    def test_run(self):
        # Setup
        repo_id = 'test-repo'
        data = {
            OPTION_REPO_ID.keyword: repo_id,
            OPTION_NAME.keyword: 'Test Repository',
            OPTION_DESCRIPTION.keyword: 'Repository Description',
            OPTION_NOTES.keyword: {'a': 'a', 'b': 'b'},
            'distributor_configs': {'alpha': {'beta': 'gamma'}},
            'importer_config': {'delta': 'epsilon'}
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('PUT', self.server_mock.request.call_args[0][0])

        url = self.server_mock.request.call_args[0][1]
        self.assertTrue(url.endswith('/repositories/%s/' % repo_id))

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        body_target = {
            'delta': {
                'display_name': 'Test Repository',
                'description': 'Repository Description',
                'notes': {'a': 'a', 'b': 'b'}
            },
            'distributor_configs': {'alpha': {'beta': 'gamma'}},
            'importer_config': {'delta': 'epsilon'}

        }
        compare_dict(body, body_target)

        self.assertEqual(1, len(self.prompt.get_write_tags()))
        self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
Beispiel #32
0
    def test_run_through_cli(self):
        """
        See the note in test_run_through_cli under the create tests for
        more info.
        """

        # Setup
        self.server_mock.request.return_value = 201, {}

        # Test
        command = repo_create_update.RpmRepoUpdateCommand(self.context)
        self.cli.add_command(command)
        self.cli.run("update --repo-id r --validate true".split())

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        self.assertEqual(body['importer_config'][constants.KEY_VALIDATE],
                         True)  # not the string "true"
Beispiel #33
0
    def test_pulp_manage_db_loads_types(self, initialize, start_logging_mock, listdir_mock,
                                        mock_drop_indices):
        """
        Test calling pulp-manage-db imports types on a clean types database.
        """
        manage.main()

        all_collection_names = types_db.all_type_collection_names()
        self.assertFalse(mock_drop_indices.called)
        self.assertEqual(len(all_collection_names), 1)

        self.assertEqual(['units_test_type_id'], all_collection_names)

        # Let's make sure we loaded the type definitions correctly
        db_type_definitions = types_db.all_type_definitions()
        self.assertEquals(len(db_type_definitions), 1)
        test_json = json.loads(_test_type_json)
        for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']:
            self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute])

        # Now let's ensure that we have the correct indexes
        collection = types_db.type_units_collection('test_type_id')
        indexes = collection.index_information()
        self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)])
        # Make sure we have the unique constraint on all three attributes
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True)
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'],
                         [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)])
        # Make sure we indexes attributes 1 and 3
        self.assertEqual(indexes['attribute_1_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)])
        self.assertEqual(indexes['attribute_3_1']['dropDups'], False)
        self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)])
        # Make sure we only have the indexes that we've hand inspected here
        self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1',
                                          u'attribute_1_1', u'attribute_3_1'])

        initialize.assert_called_once_with(max_timeout=1)
Beispiel #34
0
    def test_run_through_cli(self):
        # Setup
        self.server_mock.request.return_value = 201, {}

        # Test
        command = repo_create_update.PkgRepoCreateCommand(self.context)
        self.cli.add_command(command)
        cmd = ["create", "--repo-id", "r", "--validate", "true"]
        self.cli.run(cmd)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        self.assertEqual(body['id'], 'r')
        self.assertEqual(body['importer_config'][constants.KEY_VALIDATE],
                         True)  # not the string "true"
        dconfig = body['distributors'][0]['distributor_config']
        self.assertEquals(dict(http=False, https=True, relative_url='r'),
                          dconfig)
Beispiel #35
0
    def _do_request(self,
                    request_type,
                    uri,
                    params,
                    additional_headers,
                    serialize_json=True):
        """
        Override the base class controller to allow for less deterministic
        responses due to integration with the dispatch package.
        """

        # Use the default headers established at setup and override/add any
        headers = dict(PulpWebserviceTests.HEADERS)
        if additional_headers is not None:
            headers.update(additional_headers)

        # Serialize the parameters if any are specified
        if params is None:
            params = {}

        if serialize_json:
            params = json.dumps(params)

        # Invoke the API
        f = getattr(PulpWebserviceTests.TEST_APP, request_type)
        response = f('http://localhost' + uri,
                     params=params,
                     headers=headers,
                     expect_errors=True)

        # Collect return information and deserialize it
        status = response.status
        try:
            body = json.loads(response.body)
        except ValueError:
            body = None

        return status, body
Beispiel #36
0
    def test_run(self):
        # Setup
        data = {'from-repo-id': 'from', 'to-repo-id': 'to'}

        self.server_mock.request.return_value = 202, self.task()

        mock_poll = mock.MagicMock().poll
        self.command.poll = mock_poll

        # Test
        self.command.run(**data)

        # Verify
        call_args = self.server_mock.request.call_args[0]
        self.assertEqual('POST', call_args[0])
        self.assertTrue(call_args[1].endswith('/to/actions/associate/'))

        body = json.loads(call_args[2])
        self.assertEqual(body['source_repo_id'], 'from')
        self.assertEqual(body['criteria']['type_ids'],
                         [constants.TYPE_PUPPET_MODULE])

        self.assertEqual(1, mock_poll.call_count)
    def test_repo_id_and_match(self):
        data = {
            OPTION_GROUP_ID.keyword: 'test-group',
            FLAG_ALL.keyword: False,
            OPTION_REPO_ID.keyword: ['repo1'],
            'match': [('id', 'repo.+')]
        }
        self.server_mock.request.return_value = 200, {}

        self.command.run(**data)

        criteria = json.loads(
            self.server_mock.request.call_args[0][2])['criteria']

        self.assertEqual(len(criteria['filters']['$and']), 2)
        # make sure each of these filter types shows up in the criteria
        self.assertEqual(
            len(
                set(['$in', '$regex'])
                & set(criteria['filters']['$and'][0]['id'])), 1)
        self.assertEqual(
            len(
                set(['$in', '$regex'])
                & set(criteria['filters']['$and'][1]['id'])), 1)
Beispiel #38
0
class HTTPSServerWrapper(object):
    """
    Used by the PulpConnection class to make an invocation against the server.
    This abstraction is used to simplify mocking. In this implementation, the
    intricacies (read: ugliness) of invoking and getting the response from
    the HTTPConnection class are hidden in favor of a simpler API to mock.
    """
    def __init__(self, pulp_connection):
        """
        :param pulp_connection: A pulp connection object.
        :type pulp_connection: PulpConnection
        """
        self.pulp_connection = pulp_connection

    def request(self, method, url, body):
        """
        Make the request against the Pulp server, returning a tuple of (status_code, respose_body).
        This method creates a new connection each time since HTTPSConnection has problems
        reusing a connection for multiple calls (as claimed by a prior comment in this module).

        :param method: The HTTP method to be used for the request (GET, POST, etc.)
        :type  method: str
        :param url:    The Pulp URL to make the request against
        :type  url:    str
        :param body:   The body to pass with the request
        :type  body:   str
        :return:       A 2-tuple of the status_code and response_body. status_code is the HTTP
                       status code (200, 404, etc.). If the server's response is valid json,
                       it will be parsed and response_body will be a dictionary. If not, it will be
                       returned as a string.
        :rtype:        tuple
        """
        headers = dict(self.pulp_connection.headers
                       )  # copy so we don't affect the calling method

        # Despite the confusing name, 'sslv23' configures m2crypto to use any available protocol in
        # the underlying openssl implementation.
        ssl_context = SSL.Context('sslv23')
        # This restricts the protocols we are willing to do by configuring m2 not to do SSLv2.0 or
        # SSLv3.0. EL 5 does not have support for TLS > v1.0, so we have to leave support for
        # TLSv1.0 enabled.
        ssl_context.set_options(m2.SSL_OP_NO_SSLv2 | m2.SSL_OP_NO_SSLv3)

        if self.pulp_connection.verify_ssl:
            ssl_context.set_verify(SSL.verify_peer, depth=100)
            # We need to stat the ca_path to see if it exists (error if it doesn't), and if so
            # whether it is a file or a directory. m2crypto has different directives depending on
            # which type it is.
            if os.path.isfile(self.pulp_connection.ca_path):
                ssl_context.load_verify_locations(
                    cafile=self.pulp_connection.ca_path)
            elif os.path.isdir(self.pulp_connection.ca_path):
                ssl_context.load_verify_locations(
                    capath=self.pulp_connection.ca_path)
            else:
                # If it's not a file and it's not a directory, it's not a valid setting
                raise exceptions.MissingCAPathException(
                    self.pulp_connection.ca_path)
        ssl_context.set_session_timeout(self.pulp_connection.timeout)

        if self.pulp_connection.username and self.pulp_connection.password:
            raw = ':'.join(
                (self.pulp_connection.username, self.pulp_connection.password))
            encoded = base64.encodestring(raw)[:-1]
            headers['Authorization'] = 'Basic ' + encoded
        elif self.pulp_connection.cert_filename:
            ssl_context.load_cert(self.pulp_connection.cert_filename)

        # oauth configuration. This block is only True if oauth is not None, so it won't run on RHEL
        # 5.
        if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret and oauth:
            oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key,
                                            self.pulp_connection.oauth_secret)
            oauth_request = oauth.Request.from_consumer_and_token(
                oauth_consumer,
                http_method=method,
                http_url='https://%s:%d%s' %
                (self.pulp_connection.host, self.pulp_connection.port, url))
            oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(),
                                       oauth_consumer, None)
            oauth_header = oauth_request.to_header()
            # unicode header values causes m2crypto to do odd things.
            for k, v in oauth_header.items():
                oauth_header[k] = encode_unicode(v)
            headers.update(oauth_header)
            headers['pulp-user'] = self.pulp_connection.oauth_user

        connection = httpslib.HTTPSConnection(self.pulp_connection.host,
                                              self.pulp_connection.port,
                                              ssl_context=ssl_context)

        try:
            # Request against the server
            connection.request(method, url, body=body, headers=headers)
            response = connection.getresponse()
        except SSL.SSLError, err:
            # Translate stale login certificate to an auth exception
            if 'sslv3 alert certificate expired' == str(err):
                raise exceptions.ClientCertificateExpiredException(
                    self.pulp_connection.cert_filename)
            elif 'certificate verify failed' in str(err):
                raise exceptions.CertificateVerificationException()
            else:
                raise exceptions.ConnectionException(None, str(err), None)

        # Attempt to deserialize the body (should pass unless the server is busted)
        response_body = response.read()

        try:
            response_body = json.loads(response_body)
        except:
            pass
        return response.status, response_body
Beispiel #39
0
    def test_run(self):
        # Setup
        cert_file = os.path.join(DATA_DIR, 'cert.crt')
        cert_key = os.path.join(DATA_DIR, 'cert.key')
        ca_cert = os.path.join(DATA_DIR, 'valid_ca.crt')
        gpg_key = os.path.join(DATA_DIR,
                               'cert.key')  # contents shouldn't matter

        data = {
            options.OPTION_REPO_ID.keyword: 'test-repo',
            options.OPTION_NAME.keyword: 'Test Name',
            options.OPTION_DESCRIPTION.keyword: 'Test Description',
            options.OPTION_NOTES.keyword: {
                'a': 'a'
            },
            self.options_bundle.opt_feed.keyword: 'http://localhost',
            self.options_bundle.opt_validate.keyword: True,
            self.options_bundle.opt_remove_missing.keyword: True,
            self.options_bundle.opt_retain_old_count.keyword: 2,
            self.options_bundle.opt_proxy_host.keyword: 'http://localhost',
            self.options_bundle.opt_proxy_port.keyword: 80,
            self.options_bundle.opt_proxy_user.keyword: 'user',
            self.options_bundle.opt_proxy_pass.keyword: 'pass',
            self.options_bundle.opt_basic_auth_user.keyword: 'basicuser',
            self.options_bundle.opt_basic_auth_pass.keyword: 'basicpass',
            self.options_bundle.opt_max_speed.keyword: 1024,
            self.options_bundle.opt_max_downloads.keyword: 8,
            self.options_bundle.opt_feed_ca_cert.keyword: ca_cert,
            self.options_bundle.opt_verify_feed_ssl.keyword: True,
            self.options_bundle.opt_feed_cert.keyword: cert_file,
            self.options_bundle.opt_feed_key.keyword: cert_key,
            repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_RPM],
            repo_options.OPT_RELATIVE_URL.keyword: '/repo',
            repo_options.OPT_SERVE_HTTP.keyword: True,
            repo_options.OPT_SERVE_HTTPS.keyword: True,
            repo_options.OPT_CHECKSUM_TYPE.keyword: 'sha256',
            repo_options.OPT_UPDATEINFO_CHECKSUM_TYPE.keyword: 'md5',
            repo_options.OPT_GPG_KEY.keyword: gpg_key,
            repo_options.OPT_HOST_CA.keyword: ca_cert,
            repo_options.OPT_AUTH_CA.keyword: ca_cert,
            repo_options.OPT_AUTH_CERT.keyword: cert_file,
            repo_options.OPT_REPOVIEW.keyword: True,
        }

        self.server_mock.request.return_value = 201, {}

        # Test
        command = repo_create_update.RpmRepoCreateCommand(self.context)
        command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        self.assertEqual(body['display_name'], 'Test Name')
        self.assertEqual(body['description'], 'Test Description')
        self.assertEqual(body['notes'], {'_repo-type': 'rpm-repo', 'a': 'a'})

        self.assertEqual(ids.TYPE_ID_IMPORTER_YUM, body['importer_type_id'])
        importer_config = body['importer_config']
        self.assertEqual(importer_config[constants.KEY_FEED],
                         'http://localhost')
        self.assertTrue(importer_config[constants.KEY_SSL_CA_CERT] is not None)
        self.assertTrue(
            importer_config[constants.KEY_SSL_CLIENT_CERT] is not None)
        self.assertTrue(
            importer_config[constants.KEY_SSL_CLIENT_KEY] is not None)
        self.assertEqual(importer_config[constants.KEY_SSL_VALIDATION], True)
        self.assertEqual(importer_config[constants.KEY_VALIDATE], True)
        self.assertEqual(importer_config[constants.KEY_PROXY_HOST],
                         'http://localhost')
        self.assertEqual(importer_config[constants.KEY_PROXY_PORT], 80)
        self.assertEqual(importer_config[constants.KEY_PROXY_USER], 'user')
        self.assertEqual(importer_config[constants.KEY_PROXY_PASS], 'pass')
        self.assertEqual(importer_config[constants.KEY_BASIC_AUTH_USER],
                         'basicuser')
        self.assertEqual(importer_config[constants.KEY_BASIC_AUTH_PASS],
                         'basicpass')
        self.assertEqual(importer_config[constants.KEY_MAX_SPEED], 1024)
        self.assertEqual(importer_config[constants.KEY_MAX_DOWNLOADS], 8)
        self.assertEqual(importer_config[rpm_constants.CONFIG_SKIP],
                         [ids.TYPE_ID_RPM])
        self.assertEqual(importer_config[constants.KEY_UNITS_REMOVE_MISSING],
                         True)
        self.assertEqual(importer_config[constants.KEY_UNITS_RETAIN_OLD_COUNT],
                         2)

        # The API will be changing to be a dict for each distributor, not a
        # list. This code will have to change to look up the parts by key
        # instead of index.

        yum_distributor = body['distributors'][0]
        self.assertEqual(ids.TYPE_ID_DISTRIBUTOR_YUM,
                         yum_distributor['distributor_type_id'])
        self.assertEqual(True, yum_distributor['auto_publish'])
        self.assertEqual(ids.YUM_DISTRIBUTOR_ID,
                         yum_distributor['distributor_id'])

        yum_config = yum_distributor['distributor_config']
        self.assertEqual(yum_config['relative_url'], '/repo')
        self.assertEqual(yum_config['http'], True)
        self.assertEqual(yum_config['https'], True)
        self.assertTrue(yum_config['gpgkey'] is not None)
        self.assertEqual(yum_config['checksum_type'], 'sha256')
        self.assertEqual(yum_config['updateinfo_checksum_type'], 'md5')
        self.assertTrue(yum_config['auth_ca'] is not None)
        self.assertTrue(yum_config['auth_cert'] is not None)
        self.assertTrue(yum_config['https_ca'] is not None)
        self.assertEqual(yum_config['skip'], [ids.TYPE_ID_RPM])
        self.assertEqual(yum_config['repoview'], True)
        self.assertEqual(yum_config['generate_sqlite'], True)

        iso_distributor = body['distributors'][1]
        self.assertEqual(ids.TYPE_ID_DISTRIBUTOR_EXPORT,
                         iso_distributor['distributor_id'])
        self.assertEqual(False, iso_distributor['auto_publish'])
        self.assertEqual(ids.EXPORT_DISTRIBUTOR_ID,
                         iso_distributor['distributor_id'])

        iso_config = iso_distributor['distributor_config']
        self.assertEqual(iso_config['http'], True)
        self.assertEqual(iso_config['https'], True)
        self.assertEqual(iso_config['relative_url'], '/repo')
        self.assertEqual(iso_config['skip'], [ids.TYPE_ID_RPM])
        self.assertEqual(iso_config['checksum_type'], 'sha256')
        self.assertEqual(iso_config['updateinfo_checksum_type'], 'md5')

        self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
Beispiel #40
0
class HTTPSServerWrapper(object):
    """
    Used by the PulpConnection class to make an invocation against the server.
    This abstraction is used to simplify mocking. In this implementation, the
    intricacies (read: ugliness) of invoking and getting the response from
    the HTTPConnection class are hidden in favor of a simpler API to mock.
    """
    def __init__(self, pulp_connection):
        """
        :param pulp_connection: A pulp connection object.
        :type pulp_connection: PulpConnection
        """
        self.pulp_connection = pulp_connection

    def request(self, method, url, body):

        headers = dict(self.pulp_connection.headers
                       )  # copy so we don't affect the calling method

        # Create a new connection each time since HTTPSConnection has problems
        # reusing a connection for multiple calls (lame).
        ssl_context = None
        if self.pulp_connection.username and self.pulp_connection.password:
            raw = ':'.join(
                (self.pulp_connection.username, self.pulp_connection.password))
            encoded = base64.encodestring(raw)[:-1]
            headers['Authorization'] = 'Basic ' + encoded
        elif self.pulp_connection.cert_filename:
            ssl_context = SSL.Context('sslv3')
            ssl_context.set_session_timeout(self.pulp_connection.timeout)
            ssl_context.load_cert(self.pulp_connection.cert_filename)

        # oauth configuration
        if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret:
            oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key,
                                            self.pulp_connection.oauth_secret)
            oauth_request = oauth.Request.from_consumer_and_token(
                oauth_consumer,
                http_method=method,
                http_url='https://%s:%d%s' %
                (self.pulp_connection.host, self.pulp_connection.port, url))
            oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(),
                                       oauth_consumer, None)
            oauth_header = oauth_request.to_header()
            # unicode header values causes m2crypto to do odd things.
            for k, v in oauth_header.items():
                oauth_header[k] = encode_unicode(v)
            headers.update(oauth_header)
            headers['pulp-user'] = self.pulp_connection.oauth_user

        # Can't pass in None, so need to decide between two signatures (also lame)
        if ssl_context is not None:
            connection = httpslib.HTTPSConnection(self.pulp_connection.host,
                                                  self.pulp_connection.port,
                                                  ssl_context=ssl_context)
        else:
            connection = httpslib.HTTPSConnection(self.pulp_connection.host,
                                                  self.pulp_connection.port)

        # Request against the server
        connection.request(method, url, body=body, headers=headers)

        try:
            response = connection.getresponse()
        except SSL.SSLError, err:
            # Translate stale login certificate to an auth exception
            if 'sslv3 alert certificate expired' == str(err):
                raise exceptions.ClientSSLException(
                    self.pulp_connection.cert_filename)
            else:
                raise exceptions.ConnectionException(None, str(err), None)

        # Attempt to deserialize the body (should pass unless the server is busted)
        response_body = response.read()

        try:
            response_body = json.loads(response_body)
        except:
            pass
        return response.status, response_body
Beispiel #41
0
    def test_run(self):
        # Setup

        data = {
            options.OPTION_REPO_ID.keyword: 'test-repo',
            options.OPTION_NAME.keyword: 'Test Name',
            options.OPTION_DESCRIPTION.keyword: 'Test Description',
            options.OPTION_NOTES.keyword: {
                'a': 'a'
            },
            self.options_bundle.opt_feed.keyword: 'http://localhost',
            self.options_bundle.opt_validate.keyword: True,
            self.options_bundle.opt_remove_missing.keyword: True,
            repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_DEB],
            repo_options.OPT_RELATIVE_URL.keyword: '/repo',
            repo_options.OPT_SERVE_HTTP.keyword: True,
            repo_options.OPT_SERVE_HTTPS.keyword: True,
        }

        self.server_mock.request.return_value = 201, {}

        # Test
        command = repo_create_update.PkgRepoCreateCommand(self.context)
        command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)

        self.assertEqual(body['display_name'], 'Test Name')
        self.assertEqual(body['description'], 'Test Description')
        self.assertEqual(body['notes'], {'_repo-type': 'deb-repo', 'a': 'a'})

        self.assertEqual(ids.TYPE_ID_IMPORTER, body['importer_type_id'])
        importer_config = body['importer_config']
        self.assertEqual(importer_config[constants.KEY_FEED],
                         'http://localhost')
        self.assertEqual(importer_config[repo_create_update.CONFIG_KEY_SKIP],
                         [ids.TYPE_ID_DEB])
        self.assertEqual(importer_config[constants.KEY_UNITS_REMOVE_MISSING],
                         True)

        # The API will be changing to be a dict for each distributor, not a
        # list. This code will have to change to look up the parts by key
        # instead of index.

        yum_distributor = body['distributors'][0]
        self.assertEqual(ids.TYPE_ID_DISTRIBUTOR,
                         yum_distributor['distributor_type_id'])
        self.assertEqual(True, yum_distributor['auto_publish'])
        self.assertEqual(ids.TYPE_ID_DISTRIBUTOR,
                         yum_distributor['distributor_id'])

        yum_config = yum_distributor['distributor_config']
        self.assertEqual(yum_config['relative_url'], '/repo')
        self.assertEqual(yum_config['http'], True)
        self.assertEqual(yum_config['https'], True)
        self.assertEqual(yum_config['skip'], [ids.TYPE_ID_DEB])

        self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
Beispiel #42
0
    def test_run(self):
        # Setup
        data = {
            options.OPTION_REPO_ID.keyword: 'test-repo',
            options.OPTION_NAME.keyword: 'Test Name',
            options.OPTION_DESCRIPTION.keyword: 'Test Description',
            options.OPTION_NOTES.keyword: {
                'a': 'a'
            },
            cudl.OPTION_FEED.keyword: 'http://localhost',
            cudl.OPTION_HTTP.keyword: 'true',
            cudl.OPTION_HTTPS.keyword: 'true',
            cudl.OPTION_QUERY.keyword: ['q1', 'q2'],
            cudl.OPTION_QUERIES.keyword: None,
            cudl.OPTION_REMOVE_MISSING.keyword: True
        }

        self.server_mock.request.return_value = 200, {}

        # Test
        self.command.run(**data)

        # Verify
        self.assertEqual(1, self.server_mock.request.call_count)
        self.assertEqual('POST', self.server_mock.request.call_args[0][0])
        self.assertTrue(self.server_mock.request.call_args[0][1].endswith(
            '/v2/repositories/'))

        body = self.server_mock.request.call_args[0][2]
        body = json.loads(body)
        self.assertEqual('test-repo', body['id'])
        self.assertEqual('Test Name', body['display_name'])
        self.assertEqual('Test Description', body['description'])

        expected_notes = {
            'a': 'a',
            constants.REPO_NOTE_KEY: constants.REPO_NOTE_PUPPET
        }
        self.assertEqual(expected_notes, body['notes'])

        self.assertEqual(constants.IMPORTER_TYPE_ID, body['importer_type_id'])
        expected_config = {
            u'feed': u'http://localhost',
            u'queries': [u'q1', u'q2'],
            u'remove_missing': True
        }
        self.assertEqual(expected_config, body['importer_config'])

        dist = body['distributors'][0]
        self.assertEqual(constants.DISTRIBUTOR_TYPE_ID,
                         dist['distributor_type_id'])
        self.assertEqual(True, dist['auto_publish'])
        self.assertEqual(constants.DISTRIBUTOR_ID, dist['distributor_id'])

        expected_config = {
            u'serve_http': True,
            u'serve_https': True,
        }
        self.assertEqual(expected_config, dist['distributor_config'])

        self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())