예제 #1
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            # Foreman credentials
            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),
            # Entity parameter
            audit_comment=dict(),
            description_format=dict(),
            # effectice_user=dict(type='dict'),
            file_name=dict(type='path'),
            job_category=dict(),
            locations=dict(type='list'),
            locked=dict(type='bool', default=False),
            name=dict(),
            organizations=dict(type='list'),
            provider_type=dict(default='SSH'),
            snippet=dict(type='bool'),
            template=dict(),
            template_inputs=dict(type='list'),
            # Control parameter
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
        ),
        supports_check_mode=True,
        mutually_exclusive=[
            ['file_name', 'template'],
        ],
        required_one_of=[
            ['name', 'file_name', 'template'],
        ],
    )
    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['template']:
            module.fail_json(
                msg="Neither file_name nor template allowed if 'name: *'!")

    if HAS_IMPORT_ERROR:
        module.fail_json(msg=IMPORT_ERROR)

    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')
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'template' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['template'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a job template name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        entity_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    name = entity_dict['name']

    affects_multiple = name == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if state == 'absent':
            if list(entity_dict.keys()) != ['name']:
                module.fail_json(
                    msg=
                    "When deleting all job templates, there is no need to specify further parameters."
                )

    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)

    try:
        if affects_multiple:
            entities = find_entities(JobTemplate)
        else:
            entities = find_entities(JobTemplate, name=entity_dict['name'])
    except Exception as e:
        module.fail_json(msg='Failed to find entity: %s ' % e)

    # Set Locations of job template
    if 'locations' in entity_dict:
        entity_dict['locations'] = find_entities_by_name(
            Location, entity_dict['locations'], module)

    # Set Organizations of job template
    if 'organizations' in entity_dict:
        entity_dict['organizations'] = find_entities_by_name(
            Organization, entity_dict['organizations'], module)

    # TemplateInputs need to be added as separate entities later
    template_input_list = entity_dict.get('template_inputs', [])

    entity_dict = sanitize_entity_dict(entity_dict, name_map)

    changed = False
    if not affects_multiple:
        if entities:
            entity = entities[0]
        else:
            entity = None
        changed, result = naildown_entity(JobTemplate, entity_dict, entity,
                                          state, module)

        if state in ("present", "present_with_defaults"):

            # Manage TemplateInputs here
            for template_input_dict in template_input_list:
                template_input_dict = template_input_dict.copy()

                # assign template_input to a template
                template_input_dict['template'] = result

                ti_entity = find_template_input(
                    module, str(template_input_dict['name']), result)

                changed |= naildown_entity_state(TemplateInput,
                                                 template_input_dict,
                                                 ti_entity, state, module)

            # remove template inputs if they aren't present in template_input_list
            found_tis = find_entities(
                entity_class=lambda: TemplateInput(template=result))
            template_input_names = set(ti['name']
                                       for ti in template_input_list)
            for ti in found_tis:
                if ti.name not in template_input_names:
                    changed |= naildown_entity_state(TemplateInput, None, ti,
                                                     "absent", module)

    else:
        entity_dict.pop('name')
        for entity in entities:
            changed |= naildown_entity_state(JobTemplate, entity_dict, entity,
                                             state, module)

    module.exit_json(changed=changed)
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),
            audit_comment=dict(),
            kind=dict(choices=[
                'finish',
                'iPXE',
                'job_template',
                'POAP',
                'provision',
                'ptable',
                'PXELinux',
                'PXEGrub',
                'PXEGrub2',
                'script',
                'snippet',
                'user_data',
                'ZTP',
            ]),
            template=dict(),
            file_name=dict(type='path'),
            locations=dict(type='list'),
            locked=dict(type='bool', default=False),
            name=dict(),
            organizations=dict(type='list'),
            operatingsystems=dict(type='list'),
            state=dict(default='present', choices=['absent', 'present_with_defaults', 'present']),
        ),
        supports_check_mode=True,
        mutually_exclusive=[
            ['file_name', 'template'],
        ],
        required_one_of=[
            ['name', 'file_name', 'template'],
        ],

    )

    # We do not want a template text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['template']:
            module.fail_json(
                msg="Neither file_name nor template allowed if 'name: *'!")

    handle_no_nailgun(module, HAS_NAILGUN_PACKAGE)

    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')
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'template' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['template'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a template name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        entity_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    name = entity_dict['name']

    affects_multiple = name == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if state == 'present_with_defaults':
            module.fail_json(msg="'state: present_with_defaults' and 'name: *' cannot be used together")
        if state == 'absent':
            if entity_dict.keys() != ['name', 'locked']:
                module.fail_json(msg="When deleting all templates, there is no need to specify further parameters.")

    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)

    try:
        if affects_multiple:
            entities = find_entities(ProvisioningTemplate)
        else:
            entities = find_entities(ProvisioningTemplate, name=entity_dict['name'])
    except Exception as e:
        module.fail_json(msg='Failed to search for entities: %s ' % e)

    # Set Locations of Template
    if 'locations' in entity_dict:
        entity_dict['locations'] = find_entities_by_name(
            Location, entity_dict['locations'], module)

    # Set Organizations of Template
    if 'organizations' in entity_dict:
        entity_dict['organizations'] = find_entities_by_name(
            Organization, entity_dict['organizations'], module)

    if 'operatingsystems' in entity_dict:
        entity_dict['operatingsystems'] = [find_operating_system_by_title(module, title)
                                           for title in entity_dict['operatingsystems']]

    if not affects_multiple:
        entity_dict = find_template_kind(entity_dict, module)

    entity_dict = sanitize_entity_dict(entity_dict, name_map)

    changed = False
    if not affects_multiple:
        if len(entities) == 0:
            entity = None
        else:
            entity = entities[0]
        changed = naildown_entity_state(
            ProvisioningTemplate, entity_dict, entity, state, module)
    else:
        entity_dict.pop('name')
        for entity in entities:
            changed |= naildown_entity_state(
                ProvisioningTemplate, entity_dict, entity, state, module)

    module.exit_json(changed=changed)
예제 #3
0
def main():
    module = ForemanEntityAnsibleModule(
        argument_spec=dict(
            # audit_comment=dict(),
            layout=dict(),
            file_name=dict(type='path'),
            locations=dict(type='list'),
            locked=dict(type='bool'),
            name=dict(),
            organizations=dict(type='list'),
            os_family=dict(choices=list(_OPERATING_SYSTEMS)),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
        ),
        supports_check_mode=True,
        mutually_exclusive=[
            ['file_name', 'layout'],
        ],
        required_one_of=[
            ['name', 'file_name', 'layout'],
        ],
    )
    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['layout']:
            module.fail_json(
                msg="Neither file_name nor layout allowed if 'name: *'!")

    (entity_dict, state) = module.parse_params()
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'layout' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['layout'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a partition table name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        entity_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    name = entity_dict['name']

    affects_multiple = name == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if state == 'absent':
            if len(entity_dict.keys()) != 1:
                module.fail_json(
                    msg=
                    "When deleting all partition tables, there is no need to specify further parameters."
                )

    module.connect()

    try:
        if affects_multiple:
            entities = find_entities(PartitionTable)
        else:
            entities = find_entities(PartitionTable, name=entity_dict['name'])
    except Exception as e:
        module.fail_json(msg='Failed to find entity: %s ' % e)

    # Set Locations of partition table
    if 'locations' in entity_dict:
        entity_dict['locations'] = find_entities_by_name(
            Location, entity_dict['locations'], module)

    # Set Organizations of partition table
    if 'organizations' in entity_dict:
        entity_dict['organizations'] = find_entities_by_name(
            Organization, entity_dict['organizations'], module)

    entity_dict = sanitize_entity_dict(entity_dict, name_map)

    changed = False
    if not affects_multiple:
        if len(entities) == 0:
            entity = None
        else:
            entity = entities[0]
        changed = naildown_entity_state(PartitionTable, entity_dict, entity,
                                        state, module)
    else:
        entity_dict.pop('name')
        for entity in entities:
            changed |= naildown_entity_state(PartitionTable, entity_dict,
                                             entity, state, module)

    module.exit_json(changed=changed)
def main():
    module = ForemanEntityApypieAnsibleModule(
        argument_spec=dict(
            file_name=dict(type='path'),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
        ),
        entity_spec=dict(
            audit_comment=dict(),
            kind=dict(choices=[
                'finish',
                'iPXE',
                'job_template',
                'POAP',
                'provision',
                'ptable',
                'PXELinux',
                'PXEGrub',
                'PXEGrub2',
                'script',
                'snippet',
                'user_data',
                'ZTP',
            ],
                      type='entity',
                      flat_name='template_kind_id'),
            template=dict(),
            locations=dict(type='entity_list', flat_name='location_ids'),
            locked=dict(type='bool'),
            name=dict(),
            organizations=dict(type='entity_list',
                               flat_name='organization_ids'),
            operatingsystems=dict(type='entity_list',
                                  flat_name='operatingsystem_ids'),
            snippet=dict(type='invisible'),
        ),
        mutually_exclusive=[
            ['file_name', 'template'],
        ],
        required_one_of=[
            ['name', 'file_name', 'template'],
        ],
    )

    # We do not want a template text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['template']:
            module.fail_json(
                msg="Neither file_name nor template allowed if 'name: *'!")

    entity_dict = module.clean_params()
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'template' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['template'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a template name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        entity_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    affects_multiple = entity_dict['name'] == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if module.state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if module.desired_absent:
            if len(entity_dict.keys()) != 1:
                module.fail_json(
                    msg=
                    "When deleting all templates, there is no need to specify further parameters."
                )

    module.connect()

    if affects_multiple:
        entities = module.list_resource('provisioning_templates')
        if not entities:
            # Nothing to do; shortcut to exit
            module.exit_json(changed=False)
        if not module.desired_absent:  # not 'thin'
            entities = [
                module.show_resource('provisioning_templates', entity['id'])
                for entity in entities
            ]
    else:
        entity = module.find_resource_by_name('provisioning_templates',
                                              name=entity_dict['name'],
                                              failsafe=True)

    if not module.desired_absent:
        if 'locations' in entity_dict:
            entity_dict['locations'] = module.find_resources_by_title(
                'locations', entity_dict['locations'], thin=True)

        if 'organizations' in entity_dict:
            entity_dict['organizations'] = module.find_resources_by_name(
                'organizations', entity_dict['organizations'], thin=True)

        if 'operatingsystems' in entity_dict:
            entity_dict['operatingsystems'] = module.find_operatingsystems(
                entity_dict['operatingsystems'], thin=True)

    if not affects_multiple:
        entity_dict = find_template_kind(module, entity_dict)

    changed = False
    if not affects_multiple:
        changed = module.ensure_entity_state('provisioning_templates',
                                             entity_dict, entity)
    else:
        entity_dict.pop('name')
        for entity in entities:
            changed |= module.ensure_entity_state('provisioning_templates',
                                                  entity_dict, entity)

    module.exit_json(changed=changed)
def main():
    module = ForemanTaxonomicEntityAnsibleModule(
        entity_spec=dict(
            description_format=dict(),
            job_category=dict(),
            locked=dict(type='bool', default=False),
            name=dict(),
            provider_type=dict(),
            snippet=dict(type='bool'),
            template=dict(),
            template_inputs=dict(type='nested_list',
                                 entity_spec=template_input_entity_spec),
        ),
        argument_spec=dict(
            audit_comment=dict(),
            file_name=dict(type='path'),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
        ),
        mutually_exclusive=[
            ['file_name', 'template'],
        ],
        required_one_of=[
            ['name', 'file_name', 'template'],
        ],
    )

    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['template']:
            module.fail_json(
                msg="Neither file_name nor template allowed if 'name: *'!")

    entity_dict = module.clean_params()
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'template' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['template'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a job template name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        # make sure certain values are set
        entity_dict = template_defaults.copy()
        entity_dict.update(parsed_dict)

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    name = entity_dict['name']

    affects_multiple = name == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if module.state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if module.desired_absent:
            if len(entity_dict.keys()) != 1:
                module.fail_json(
                    msg=
                    "When deleting all job templates, there is no need to specify further parameters."
                )

    with module.api_connection():
        if affects_multiple:
            entities = module.list_resource('job_templates')
            if not entities:
                # Nothing to do; shortcut to exit
                module.exit_json()
            if not module.desired_absent:  # not 'thin'
                entities = [
                    module.show_resource('job_templates', entity['id'])
                    for entity in entities
                ]
        else:
            entity = module.find_resource_by_name('job_templates',
                                                  name=entity_dict['name'],
                                                  failsafe=True)

        entity_dict = module.handle_taxonomy_params(entity_dict)

        # TemplateInputs need to be added as separate entities later
        template_inputs = entity_dict.get('template_inputs')

        if 'audit_comment' in entity_dict:
            extra_params = {'audit_comment': entity_dict['audit_comment']}
        else:
            extra_params = {}

        if not affects_multiple:
            job_template = module.ensure_entity('job_templates',
                                                entity_dict,
                                                entity,
                                                params=extra_params)

            update_dependent_entities = (
                module.state == 'present' or
                (module.state == 'present_with_defaults' and module.changed))
            if update_dependent_entities and template_inputs is not None:
                scope = {'template_id': job_template['id']}

                # Manage TemplateInputs here
                current_template_input_list = module.list_resource(
                    'template_inputs', params=scope) if entity else []
                current_template_inputs = {
                    item['name']: item
                    for item in current_template_input_list
                }
                for template_input_dict in template_inputs:
                    template_input_dict = {
                        key: value
                        for key, value in template_input_dict.items()
                        if value is not None
                    }

                    template_input_entity = current_template_inputs.pop(
                        template_input_dict['name'], None)

                    module.ensure_entity(
                        'template_inputs',
                        template_input_dict,
                        template_input_entity,
                        params=scope,
                        entity_spec=template_input_entity_spec,
                    )

                # At this point, desired template inputs have been removed from the dict.
                for template_input_entity in current_template_inputs.values():
                    module.ensure_entity(
                        'template_inputs',
                        None,
                        template_input_entity,
                        state="absent",
                        params=scope,
                        entity_spec=template_input_entity_spec,
                    )

        else:
            entity_dict.pop('name')
            for entity in entities:
                module.ensure_entity('job_templates',
                                     entity_dict,
                                     entity,
                                     params=extra_params)
예제 #6
0
def main():
    module = ForemanEntityAnsibleModule(
        argument_spec=dict(
            file_name=dict(type='path'),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
        ),
        entity_spec=dict(
            layout=dict(),
            locations=dict(type='entity_list', flat_name='location_ids'),
            locked=dict(type='bool'),
            name=dict(),
            organizations=dict(type='entity_list',
                               flat_name='organization_ids'),
            os_family=dict(choices=[
                'AIX',
                'Altlinux',
                'Archlinux',
                'Debian',
                'Freebsd',
                'Gentoo',
                'Junos',
                'Redhat',
                'Solaris',
                'Suse',
                'Windows',
            ]),
        ),
        mutually_exclusive=[
            ['file_name', 'layout'],
        ],
        required_one_of=[
            ['name', 'file_name', 'layout'],
        ],
    )

    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['layout']:
            module.fail_json(
                msg="Neither file_name nor layout allowed if 'name: *'!")

    entity_dict = module.clean_params()
    file_name = entity_dict.pop('file_name', None)

    if file_name or 'layout' in entity_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(entity_dict['layout'], module)
        parsed_dict['layout'] = parsed_dict.pop('template')
        if 'oses' in parsed_dict:
            parsed_dict['os_family'] = parsed_dict.pop('oses')
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a partition table name!")
        # module params are priorized
        parsed_dict.update(entity_dict)
        entity_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in entity_dict:
        if file_name:
            entity_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    affects_multiple = entity_dict['name'] == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if module.state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if module.desired_absent:
            if len(entity_dict.keys()) != 1:
                module.fail_json(
                    msg=
                    'When deleting all partition tables, there is no need to specify further parameters.'
                )

    module.connect()

    if affects_multiple:
        entities = module.list_resource('ptables')
        if not entities:
            # Nothing to do; shortcut to exit
            module.exit_json(changed=False)
        if not module.desired_absent:  # not 'thin'
            entities = [
                module.show_resource('ptables', entity['id'])
                for entity in entities
            ]
    else:
        entity = module.find_resource_by_name('ptables',
                                              name=entity_dict['name'],
                                              failsafe=True)

    if not module.desired_absent:
        if 'locations' in entity_dict:
            entity_dict['locations'] = module.find_resources_by_title(
                'locations', entity_dict['locations'], thin=True)

        if 'organizations' in entity_dict:
            entity_dict['organizations'] = module.find_resources_by_name(
                'organizations', entity_dict['organizations'], thin=True)

    changed = False
    if not affects_multiple:
        changed = module.ensure_entity_state('ptables', entity_dict, entity)
    else:
        entity_dict.pop('name')
        for entity in entities:
            changed |= module.ensure_entity_state('ptables', entity_dict,
                                                  entity)

    module.exit_json(changed=changed)
예제 #7
0
def main():
    module = ForemanProvisioningTemplateModule(
        argument_spec=dict(
            audit_comment=dict(),
            file_name=dict(type='path'),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
            updated_name=dict(),
        ),
        foreman_spec=dict(
            kind=dict(choices=[
                'finish',
                'iPXE',
                'job_template',
                'POAP',
                'provision',
                'ptable',
                'PXELinux',
                'PXEGrub',
                'PXEGrub2',
                'script',
                'snippet',
                'user_data',
                'ZTP',
            ],
                      type='entity',
                      flat_name='template_kind_id',
                      resolve=False),
            template=dict(),
            locked=dict(type='bool'),
            name=dict(),
            operatingsystems=dict(type='entity_list'),
            snippet=dict(type='invisible'),
        ),
        mutually_exclusive=[
            ['file_name', 'template'],
        ],
        required_one_of=[
            ['name', 'file_name', 'template'],
        ],
    )

    # We do not want a template text for bulk operations
    if module.foreman_params.get('name') == '*':
        if module.foreman_params.get('file_name') or module.foreman_params.get(
                'template') or module.foreman_params.get('updated_name'):
            module.fail_json(
                msg=
                "Neither file_name nor template nor updated_name allowed if 'name: *'!"
            )

    entity = None
    file_name = module.foreman_params.pop('file_name', None)

    if file_name or 'template' in module.foreman_params:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(module.foreman_params['template'],
                                         module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if parsed_dict.get('name') == '*':
            module.fail_json(msg="Cannot use '*' as a template name!")
        # module params are priorized
        parsed_dict.update(module.foreman_params)
        module.foreman_params = parsed_dict

    # make sure, we have a name
    if 'name' not in module.foreman_params:
        if file_name:
            module.foreman_params['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    affects_multiple = module.foreman_params['name'] == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if module.foreman_params.get('updated_name'):
            module.fail_json(msg="updated_name not allowed if 'name: *'!")
        if module.state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if module.desired_absent:
            further_params = set(
                module.foreman_params.keys()) - {'name', 'entity'}
            if further_params:
                module.fail_json(
                    msg=
                    'When deleting all templates, there is no need to specify further parameters: %s '
                    % further_params)

    with module.api_connection():
        if 'audit_comment' in module.foreman_params:
            extra_params = {
                'audit_comment': module.foreman_params['audit_comment']
            }
        else:
            extra_params = {}

        if affects_multiple:
            module.set_entity('entity', None)  # prevent lookup
            entities = module.list_resource('provisioning_templates')
            if not entities:
                # Nothing to do; shortcut to exit
                module.exit_json()
            if not module.desired_absent:  # not 'thin'
                entities = [
                    module.show_resource('provisioning_templates',
                                         entity['id']) for entity in entities
                ]
                module.auto_lookup_entities()
            module.foreman_params.pop('name')
            for entity in entities:
                module.ensure_entity('provisioning_templates',
                                     module.foreman_params,
                                     entity,
                                     params=extra_params)
        else:
            # The name could have been determined to late, so copy it again
            module.foreman_params['entity'] = module.foreman_params['name']

            module.foreman_params = find_template_kind(module,
                                                       module.foreman_params)

            module.run(params=extra_params)
예제 #8
0
def main():
    module = ForemanPtableModule(
        argument_spec=dict(
            file_name=dict(type='path'),
            state=dict(default='present',
                       choices=['absent', 'present_with_defaults', 'present']),
            updated_name=dict(),
        ),
        foreman_spec=dict(
            layout=dict(),
            locked=dict(type='bool'),
            name=dict(),
            os_family=dict(choices=OS_LIST),
        ),
        mutually_exclusive=[
            ['file_name', 'layout'],
        ],
        required_one_of=[
            ['name', 'file_name', 'layout'],
        ],
        entity_resolve=False,
    )

    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params[
                'layout'] or module.params['updated_name']:
            module.fail_json(
                msg=
                "Neither file_name nor layout nor updated_name allowed if 'name: *'!"
            )

    entity = None
    module_params = module.clean_params()
    file_name = module_params.pop('file_name', None)

    if file_name or 'layout' in module_params:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(module_params['layout'], module)
        parsed_dict['layout'] = parsed_dict.pop('template')
        if 'oses' in parsed_dict:
            parsed_dict['os_family'] = parsed_dict.pop('oses')
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a partition table name!")
        # module params are priorized
        parsed_dict.update(module_params)
        module_params = parsed_dict

    # make sure, we have a name
    if 'name' not in module_params:
        if file_name:
            module_params['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    affects_multiple = module_params['name'] == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if module.state == 'present_with_defaults':
            module.fail_json(
                msg=
                "'state: present_with_defaults' and 'name: *' cannot be used together"
            )
        if module.desired_absent:
            if len(module_params.keys()) != 1:
                module.fail_json(
                    msg=
                    'When deleting all partition tables, there is no need to specify further parameters.'
                )

    with module.api_connection():
        if affects_multiple:
            entities = module.list_resource('ptables')
            if not entities:
                # Nothing to do; shortcut to exit
                module.exit_json()
            if not module.desired_absent:  # not 'thin'
                entities = [
                    module.show_resource('ptables', entity['id'])
                    for entity in entities
                ]
        else:
            entity = module.find_resource_by_name('ptables',
                                                  name=module_params['name'],
                                                  failsafe=True)

        if not module.desired_absent:
            _entity, module_params = module.resolve_entities(
                module_params, entity)

        if not affects_multiple:
            module.ensure_entity('ptables', module_params, entity)
        else:
            module_params.pop('name')
            for entity in entities:
                module.ensure_entity('ptables', module_params, entity)
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),
            # audit_comment=dict(),
            layout=dict(),
            file_name=dict(type='path'),
            locations=dict(type='list'),
            # locked=dict(type='bool', default=False),
            name=dict(),
            organizations=dict(type='list'),
            os_family=dict(choices=list(_OPERATING_SYSTEMS)),
            state=dict(required=True, choices=['absent', 'present', 'latest']),
        ),
        supports_check_mode=True,
        mutually_exclusive=[
            ['file_name', 'layout'],
        ],
        required_one_of=[
            ['name', 'file_name', 'layout'],
        ],
    )
    # We do not want a layout text for bulk operations
    if module.params['name'] == '*':
        if module.params['file_name'] or module.params['layout']:
            module.fail_json(
                msg="Neither file_name nor layout allowed if 'name: *'!")

    handle_no_nailgun(module, HAS_NAILGUN_PACKAGE)

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

    server_url = ptable_dict.pop('server_url')
    username = ptable_dict.pop('username')
    password = ptable_dict.pop('password')
    verify_ssl = ptable_dict.pop('verify_ssl')
    state = ptable_dict.pop('state')
    file_name = ptable_dict.pop('file_name', None)

    if file_name or 'layout' in ptable_dict:
        if file_name:
            parsed_dict = parse_template_from_file(file_name, module)
        else:
            parsed_dict = parse_template(ptable_dict['layout'], module)
        # sanitize name from template data
        # The following condition can actually be hit, when someone is trying to import a
        # template with the name set to '*'.
        # Besides not being sensible, this would go horribly wrong in this module.
        if 'name' in parsed_dict and parsed_dict['name'] == '*':
            module.fail_json(msg="Cannot use '*' as a partition table name!")
        # module params are priorized
        parsed_dict.update(ptable_dict)
        ptable_dict = parsed_dict

    # make sure, we have a name
    if 'name' not in ptable_dict:
        if file_name:
            ptable_dict['name'] = os.path.splitext(
                os.path.basename(file_name))[0]
        else:
            module.fail_json(
                msg='No name specified and no filename to infer it.')

    name = ptable_dict['name']

    affects_multiple = name == '*'
    # sanitize user input, filter unuseful configuration combinations with 'name: *'
    if affects_multiple:
        if state == 'present':
            module.fail_json(
                msg="'state: present' and 'name: *' cannot be used together")
        if state == 'absent':
            if ptable_dict.keys() != ['name']:
                module.fail_json(
                    msg=
                    "When deleting all partition tables, there is no need to specify further parameters."
                )

    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)

    try:
        if affects_multiple:
            entities = find_entities(PartitionTable)
        else:
            entities = find_entities(PartitionTable, name=ptable_dict['name'])
    except Exception as e:
        module.fail_json(msg='Failed to find entity: %s ' % e)

    # Set Locations of partition table
    if 'locations' in ptable_dict:
        ptable_dict['locations'] = find_entities_by_name(
            Location, ptable_dict['locations'], module)

    # Set Organizations of partition table
    if 'organizations' in ptable_dict:
        ptable_dict['organizations'] = find_entities_by_name(
            Organization, ptable_dict['organizations'], module)

    ptable_dict = sanitize_ptable_dict(ptable_dict)

    changed = False
    if not affects_multiple:
        if len(entities) == 0:
            entity = None
        else:
            entity = entities[0]
        changed = naildown_entity_state(PartitionTable, ptable_dict, entity,
                                        state, module)
    else:
        ptable_dict.pop('name')
        for entity in entities:
            changed |= naildown_entity_state(PartitionTable, ptable_dict,
                                             entity, state, module)

    module.exit_json(changed=changed)