Beispiel #1
0
def find_subscription(module, name, organization, failsafe=False):
    subscription = Subscription(organization=organization)
    return handle_find_response(
        module,
        subscription.search(query={'search': 'name="{}"'.format(name)}),
        message="No subscription found for %s" % name,
        failsafe=failsafe)
def manifest(module,
             organization,
             state,
             manifest_path=None,
             redhat_repository_url="https://cdn.redhat.com"):
    changed = False
    organization = find_organization(module, organization).read()
    current_manifest = current_subscription_manifest(module, organization)
    manifest_present = current_manifest is not None

    if organization.redhat_repository_url != redhat_repository_url:
        if not module.check_mode:
            organization.redhat_repository_url = redhat_repository_url
            organization.update({'redhat_repository_url'})
        changed = True

    if state == 'present':
        try:
            with open(manifest_path, 'rb') as manifest_file:
                files = {
                    'content':
                    (manifest_path, manifest_file, 'application/zip')
                }
                data = {
                    'organization_id': organization.id,
                    'repository_url': redhat_repository_url
                }
                headers = {
                    'content_type': 'multipart/form-data',
                    'multipart': 'true'
                }
                if not module.check_mode:
                    Subscription().upload(data=data,
                                          files=files,
                                          headers=headers)
                changed = True
        except IOError as e:
            module.fail_json(msg="Unable to open the manifest file: %s" % e)
        except TaskFailedError as e:
            if "same as existing data" in e.message:
                pass
            elif "older than existing data" in e.message:
                module.fail_json(
                    msg="Manifest is older than existing data: %s" % e)
            else:
                module.fail_json(msg="Upload of the mainfest failed: %s" % e)
    elif state == 'absent' and manifest_present:
        if not module.check_mode:
            Subscription().delete_manifest(
                data={'organization_id': organization.id})
        changed = True
    elif state == 'refreshed':
        if not manifest_present:
            module.fail_json(msg="No manifest found to refresh.")
        else:
            if not module.check_mode:
                Subscription().refresh_manifest(
                    data={'organization_id': organization.id})
            changed = True
    return changed
def main():
    module = KatelloEntityAnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            new_name=dict(),
            lifecycle_environment=dict(),
            content_view=dict(),
            subscriptions=dict(type='list'),
            host_collections=dict(type='list'),
            content_overrides=dict(type='list'),
            auto_attach=dict(type='bool', default=True),
            state=dict(default='present',
                       choices=[
                           'present', 'present_with_defaults', 'absent',
                           'copied'
                       ]),
        ),
        supports_check_mode=True,
        required_if=[
            ['state', 'copied', ['new_name']],
        ],
    )

    (entity_dict, state) = module.parse_params()

    module.connect()

    entity_dict['organization'] = find_organization(
        module, name=entity_dict['organization'])
    if 'lifecycle_environment' in entity_dict:
        entity_dict['lifecycle_environment'] = find_lifecycle_environment(
            module, entity_dict['lifecycle_environment'],
            entity_dict['organization'])

    if 'content_view' in entity_dict:
        entity_dict['content_view'] = find_content_view(
            module, entity_dict['content_view'], entity_dict['organization'])

    if 'host_collections' in entity_dict:
        entity_dict['host_collections'] = find_host_collections(
            module, entity_dict['host_collections'],
            entity_dict['organization'])

    activation_key_entity = find_activation_key(
        module,
        name=entity_dict['name'],
        organization=entity_dict['organization'],
        failsafe=True)

    activation_key_dict = sanitize_entity_dict(entity_dict, name_map)

    try:
        changed, activation_key_entity = naildown_entity(
            ActivationKey, activation_key_dict, activation_key_entity, state,
            module)

        # only update subscriptions of newly created or updated AKs
        # copied keys inherit the subscriptions of the origin, so one would not have to specify them again
        # deleted keys don't need subscriptions anymore either
        if state == 'present' or (state == 'present_with_defaults'
                                  and changed):
            if 'subscriptions' in entity_dict:
                subscriptions = entity_dict['subscriptions']
                desired_subscription_ids = set(
                    s.id for s in find_subscriptions(
                        module, subscriptions, entity_dict['organization']))
                current_subscriptions = [
                    Subscription(**result)
                    for result in Subscription().search_normalize(
                        activation_key_entity.subscriptions()['results'])
                ]
                current_subscription_ids = set(s.id
                                               for s in current_subscriptions)

                if desired_subscription_ids != current_subscription_ids:
                    if not module.check_mode:
                        for subscription_id in (desired_subscription_ids -
                                                current_subscription_ids):
                            activation_key_entity.add_subscriptions(
                                data={
                                    'quantity': 1,
                                    'subscription_id': subscription_id
                                })
                        for subscription_id in (current_subscription_ids -
                                                desired_subscription_ids):
                            activation_key_entity.remove_subscriptions(
                                data={'subscription_id': subscription_id})
                    changed = True

            if 'content_overrides' in entity_dict:
                content_overrides = entity_dict['content_overrides']
                product_content = activation_key_entity.product_content()
                current_content_overrides = set(
                    (product['content']['label'],
                     product['enabled_content_override'])
                    for product in product_content['results']
                    if product['enabled_content_override'] is not None)
                desired_content_overrides = set(
                    (product['label'],
                     override_to_boolnone(product['override']))
                    for product in content_overrides)

                if desired_content_overrides != current_content_overrides:
                    if not module.check_mode:
                        for (
                                label, override
                        ) in current_content_overrides - desired_content_overrides:
                            activation_key_entity.content_override(
                                data={
                                    'content_override': {
                                        'content_label': label,
                                        'value': 'default'
                                    }
                                })
                        for (
                                label, override
                        ) in desired_content_overrides - current_content_overrides:
                            activation_key_entity.content_override(
                                data={
                                    'content_override': {
                                        'content_label': label,
                                        'value': str(override).lower()
                                    }
                                })
                    changed = True

        module.exit_json(changed=changed)
    except Exception as e:
        module.fail_json(msg=e)
Beispiel #4
0
    def setUpClass(cls):
        """Creates all the pre-requisites for the Incremental updates test"""
        super(IncrementalUpdateTestCase, cls).setUpClass()
        # Step 1 - Create a new Organization
        cls.org = Organization(name=gen_alpha()).create()

        # Step 2 - Create two life cycle environments - DEV, QE
        cls.dev_lce = LifecycleEnvironment(name='DEV',
                                           organization=cls.org).create()
        cls.qe_lce = LifecycleEnvironment(name='QE',
                                          prior=cls.dev_lce,
                                          organization=cls.org).create()

        # Step 3: Upload manifest
        with manifests.clone() as manifest:
            upload_manifest(cls.org.id, manifest.content)

        # Step 4: Enable repositories - 6Server and rhel6 sat6tools
        rhel_66_repo_id = enable_rhrepo_and_fetchid(
            basearch=PRD_SETS['rhel_66']['arch'],
            org_id=cls.org.id,
            product=PRD_SETS['rhel_66']['product'],
            repo=PRD_SETS['rhel_66']['reponame'],
            reposet=PRD_SETS['rhel_66']['reposet'],
            releasever=PRD_SETS['rhel_66']['releasever'])
        rhel6_sat6tools_repo_id = enable_rhrepo_and_fetchid(
            basearch=PRD_SETS['rhel6_sat6tools']['arch'],
            org_id=cls.org.id,
            product=PRD_SETS['rhel6_sat6tools']['product'],
            repo=PRD_SETS['rhel6_sat6tools']['reponame'],
            reposet=PRD_SETS['rhel6_sat6tools']['reposet'],
            releasever=PRD_SETS['rhel6_sat6tools']['releasever'])

        # Step 5: Read the repositories
        cls.rhel_66_repo = Repository(id=rhel_66_repo_id).read()
        cls.rhel6_sat6tools_repo = Repository(
            id=rhel6_sat6tools_repo_id).read()

        # Step 6: Sync the enabled repositories
        try:
            cls.old_task_timeout = entity_mixins.TASK_TIMEOUT
            # Update timeout to 2 hours to finish sync
            entity_mixins.TASK_TIMEOUT = 7200
            for repo in [cls.rhel_66_repo, cls.rhel6_sat6tools_repo]:
                assert Repository(id=repo.id).sync()['result'] == u'success'
        finally:
            entity_mixins.TASK_TIMEOUT = cls.old_task_timeout

        # Step 7: Create two content views - one will be used with all erratas
        # and another with erratas filtered
        for cv_name in ('rhel_6_cv', 'rhel_6_partial_cv'):
            setattr(
                cls, cv_name,
                ContentView(
                    organization=cls.org,
                    name=cv_name,
                    repository=[cls.rhel_66_repo,
                                cls.rhel6_sat6tools_repo]).create())

        # Step 8: Create a content view filter to filter out errata
        rhel_6_partial_cvf = ErratumContentViewFilter(
            content_view=cls.rhel_6_partial_cv,
            type='erratum',
            name='rhel_6_partial_cv_filter',
            repository=[cls.rhel_66_repo]).create()

        # Step 9: Create a content view filter rule - filtering out errata in
        # the last 365 days
        start_date = (date.today() - timedelta(days=365)).strftime('%Y-%m-%d')
        ContentViewFilterRule(
            content_view_filter=rhel_6_partial_cvf,
            types=['security', 'enhancement', 'bugfix'],
            start_date=start_date,
            end_date=date.today().strftime('%Y-%m-%d')).create()

        # Step 10: Publish both the content views and re-read the content views

        # Changing the nailgun timeout time for the rest of the steps as
        # publish/promote of larger repos take more than 5 minutes
        entity_mixins.TASK_TIMEOUT = 3600
        for content_view in (cls.rhel_6_cv, cls.rhel_6_partial_cv):
            content_view.publish()
        cls.rhel_6_cv = cls.rhel_6_cv.read()
        cls.rhel_6_partial_cv = cls.rhel_6_partial_cv.read()

        # Step 11: Promote both content views to 'DEV' and 'QE'
        for content_view in (cls.rhel_6_cv, cls.rhel_6_partial_cv):
            assert len(content_view.version) == 1
            for env in (cls.dev_lce, cls.qe_lce):
                promote(content_view.version[0], env.id)

        # Step 12: Create host collections
        for hc_name in ('rhel_6_hc', 'rhel_6_partial_hc'):
            setattr(
                cls, hc_name,
                HostCollection(organization=cls.org,
                               name=hc_name,
                               max_content_hosts=5).create())

        # Step 13: Create activation keys for both content views
        kwargs = {'organization': cls.org, 'environment': cls.qe_lce.id}
        rhel_6_ak = ActivationKey(name=u'rhel_6_ak',
                                  content_view=cls.rhel_6_cv,
                                  host_collection=[cls.rhel_6_hc],
                                  **kwargs).create()
        rhel_6_partial_ak = ActivationKey(
            name=u'rhel_6_partial_ak',
            content_view=cls.rhel_6_partial_cv,
            host_collection=[cls.rhel_6_partial_hc],
            **kwargs).create()

        # Step 14: Assign subscriptions to activation keys
        # Fetch available subscriptions
        subs = Subscription(organization=cls.org).search()
        assert len(subs) > 0

        # Add subscriptions to activation key
        sub_found = False
        for sub in subs:
            if sub.read_json()['product_name'] == u'Employee SKU':
                for act_key in [rhel_6_ak, rhel_6_partial_ak]:
                    act_key.add_subscriptions(
                        data={u'subscription_id': sub.id})
                sub_found = True
        assert sub_found

        # Step 15: Enable product content in activation keys
        for act_key in [rhel_6_ak, rhel_6_partial_ak]:
            act_key.content_override(
                data={
                    'content_override': {
                        u'content_label': PRD_SETS['rhel6_sat6tools']['label'],
                        u'value': u'1'
                    }
                })

        # Step 16: Create three client machines and register them to satellite
        # Register the first vm with rhel_6_ak and the other two vms with
        # rhel_6_partial_ak
        cls.vm = [
            VirtualMachine(distro='rhel67', tag='incupdate') for _ in range(3)
        ]
        cls.setup_vm(cls.vm[0], rhel_6_ak.name, cls.org.label)
        for i in range(1, 3):
            cls.setup_vm(cls.vm[i], rhel_6_partial_ak.name, cls.org.label)

        # Find the content hosts (systems) and save them
        systems = System(organization=cls.org).search()
        cls.systems = []
        cls.partial_systems = []

        for system in systems:
            if system.content_view.read().name == cls.rhel_6_cv.name:
                cls.systems.append(system)
            else:
                cls.partial_systems.append(system)
    def setUp(self):
        """Creates the pre-requisites for the Incremental updates that used per
        each test"""
        super(IncrementalUpdateTestCase, self).setUp()
        # Create content view that will be used filtered erratas
        self.rhel_6_partial_cv = ContentView(
            organization=self.org,
            name=gen_alpha(),
            repository=[self.rhva_6_repo, self.rhel6_sat6tools_repo]
        ).create()

        # Create a content view filter to filter out errata
        rhel_6_partial_cvf = ErratumContentViewFilter(
            content_view=self.rhel_6_partial_cv,
            type='erratum',
            name='rhel_6_partial_cv_filter',
            repository=[self.rhva_6_repo]
        ).create()

        # Create a content view filter rule - filtering out errata in the last
        # 365 days
        start_date = (date.today() - timedelta(days=365)).strftime('%Y-%m-%d')
        ContentViewFilterRule(
            content_view_filter=rhel_6_partial_cvf,
            types=['security', 'enhancement', 'bugfix'],
            start_date=start_date,
            end_date=date.today().strftime('%Y-%m-%d')
        ).create()

        # Publish content view and re-read it

        self.rhel_6_partial_cv.publish()
        self.rhel_6_partial_cv = self.rhel_6_partial_cv.read()

        # Promote content view to 'DEV' and 'QE'
        assert len(self.rhel_6_partial_cv.version) == 1
        for env in (self.dev_lce, self.qe_lce):
            promote(self.rhel_6_partial_cv.version[0], env.id)

        # Create host collection
        self.rhel_6_partial_hc = HostCollection(
            organization=self.org, name=gen_alpha(), max_hosts=5).create()

        # Create activation key for content view
        kwargs = {'organization': self.org, 'environment': self.qe_lce.id}
        rhel_6_partial_ak = ActivationKey(
            name=gen_alpha(),
            content_view=self.rhel_6_partial_cv,
            host_collection=[self.rhel_6_partial_hc],
            **kwargs
        ).create()

        # Assign subscription to activation key. Fetch available subscriptions
        subs = Subscription(organization=self.org).search()
        assert len(subs) > 0

        # Add subscription to activation key
        sub_found = False
        for sub in subs:
            if sub.read_json()['product_name'] == DEFAULT_SUBSCRIPTION_NAME:
                rhel_6_partial_ak.add_subscriptions(data={
                    u'subscription_id': sub.id
                })
                sub_found = True
        assert sub_found

        # Enable product content in activation key
        rhel_6_partial_ak.content_override(data={'content_override': {
            u'content_label': REPOS['rhst6']['id'],
            u'value': u'1'
        }})

        # Create client machine and register it to satellite with
        # rhel_6_partial_ak
        self.vm = VirtualMachine(distro=DISTRO_RHEL6, tag='incupdate')
        self.addCleanup(vm_cleanup, self.vm)
        self.setup_vm(self.vm, rhel_6_partial_ak.name, self.org.label)
        self.vm.enable_repo(REPOS['rhva6']['id'])
        self.vm.run('yum install -y {0}'.format(REAL_0_RH_PACKAGE))

        # Find the content hosts and save them
        hosts = Host(organization=str(self.org.id)).search()
        self.partial_hosts = []
        for host in hosts:
            self.partial_hosts.append(host)
Beispiel #6
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            server_url=dict(required=True),
            username=dict(required=True, no_log=True),
            password=dict(required=True, no_log=True),
            verify_ssl=dict(type='bool', default=True),
            name=dict(required=True),
            new_name=dict(),
            organization=dict(required=True),
            lifecycle_environment=dict(),
            content_view=dict(),
            subscriptions=dict(type='list'),
            content_overrides=dict(type='list'),
            auto_attach=dict(type='bool', default=True),
            state=dict(default='present',
                       choices=[
                           'present', 'present_with_defaults', 'absent',
                           'copied'
                       ]),
        ),
        supports_check_mode=True,
        required_if=[
            ['state', 'copied', ['new_name']],
        ],
    )

    if has_import_error:
        module.fail_json(msg=import_error_msg)

    entity_dict = dict([(k, v) for (k, v) in module.params.items()
                        if v is not None])

    server_url = entity_dict.pop('server_url')
    username = entity_dict.pop('username')
    password = entity_dict.pop('password')
    verify_ssl = entity_dict.pop('verify_ssl')
    state = entity_dict.pop('state')

    try:
        create_server(server_url, (username, password), verify_ssl)
    except Exception as e:
        module.fail_json(msg="Failed to connect to Foreman server: %s " % e)

    ping_server(module)

    entity_dict['organization'] = find_organization(
        module, name=entity_dict['organization'])
    if 'lifecycle_environment' in entity_dict:
        entity_dict['lifecycle_environment'] = find_lifecycle_environment(
            module, entity_dict['lifecycle_environment'],
            entity_dict['organization'])

    if 'content_view' in entity_dict:
        entity_dict['content_view'] = find_content_view(
            module, entity_dict['content_view'], entity_dict['organization'])

    activation_key_dict = sanitize_entity_dict(entity_dict, name_map)
    activation_key_entity = find_activation_key(
        module,
        name=entity_dict['name'],
        organization=entity_dict['organization'],
        failsafe=True)

    try:
        changed, activation_key_entity = naildown_entity(
            ActivationKey, activation_key_dict, activation_key_entity, state,
            module)

        # only update subscriptions of newly created or updated AKs
        # copied keys inherit the subscriptions of the origin, so one would not have to specify them again
        # deleted keys don't need subscriptions anymore either
        if state == 'present' or (state == 'present_with_defaults'
                                  and changed):
            if 'subscriptions' in entity_dict:
                subscriptions = entity_dict['subscriptions']
                desired_subscription_ids = map(
                    lambda s: s.id,
                    find_subscriptions(module, subscriptions,
                                       entity_dict['organization']))
                current_subscriptions = [
                    Subscription(**result)
                    for result in Subscription().search_normalize(
                        activation_key_entity.subscriptions()['results'])
                ]
                current_subscription_ids = map(lambda s: s.id,
                                               current_subscriptions)

                if set(desired_subscription_ids) != set(
                        current_subscription_ids):
                    if not module.check_mode:
                        for subscription_id in set(
                                desired_subscription_ids) - set(
                                    current_subscription_ids):
                            activation_key_entity.add_subscriptions(
                                data={
                                    'quantity': 1,
                                    'subscription_id': subscription_id
                                })
                        for subscription_id in set(
                                current_subscription_ids) - set(
                                    desired_subscription_ids):
                            activation_key_entity.remove_subscriptions(
                                data={'subscription_id': subscription_id})
                    changed = True

            if 'content_overrides' in entity_dict:
                content_overrides = entity_dict['content_overrides']
                product_content = activation_key_entity.product_content()
                current_content_overrides = set()
                for product in product_content['results']:
                    if product['enabled_content_override'] is not None:
                        current_content_overrides.add(
                            (product['content']['label'],
                             product['enabled_content_override']))
                desired_content_overrides = set()
                for product in content_overrides:
                    desired_content_overrides.add(
                        (product['label'],
                         override_to_boolnone(product['override'])))

                if desired_content_overrides != current_content_overrides:
                    if not module.check_mode:
                        for (
                                label, override
                        ) in current_content_overrides - desired_content_overrides:
                            activation_key_entity.content_override(
                                data={
                                    'content_override': {
                                        'content_label': label,
                                        'value': 'default'
                                    }
                                })
                        for (
                                label, override
                        ) in desired_content_overrides - current_content_overrides:
                            activation_key_entity.content_override(
                                data={
                                    'content_override': {
                                        'content_label':
                                        label,
                                        'value':
                                        str(override_to_boolnone(
                                            override)).lower()
                                    }
                                })
                    changed = True

        module.exit_json(changed=changed)
    except Exception as e:
        module.fail_json(msg=e)