class NetAppCDOTLUN(object):
    def __init__(self):

        self._size_unit_map = dict(bytes=1,
                                   b=1,
                                   kb=1024,
                                   mb=1024**2,
                                   gb=1024**3,
                                   tb=1024**4,
                                   pb=1024**5,
                                   eb=1024**6,
                                   zb=1024**7,
                                   yb=1024**8)

        self.argument_spec = netapp_utils.ontap_sf_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=True, choices=['present', 'absent']),
                name=dict(required=True, type='str'),
                size=dict(type='int'),
                size_unit=dict(default='gb',
                               choices=[
                                   'bytes', 'b', 'kb', 'mb', 'gb', 'tb', 'pb',
                                   'eb', 'zb', 'yb'
                               ],
                               type='str'),
                force_resize=dict(default=False, type='bool'),
                force_remove=dict(default=False, type='bool'),
                force_remove_fenced=dict(default=False, type='bool'),
                flexvol_name=dict(type='str'),
                vserver=dict(required=True, type='str'),
            ))

        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    required_if=[('state', 'present',
                                                  ['flexvol_name', 'size'])],
                                    supports_check_mode=True)

        p = self.module.params

        # set up state variables
        self.state = p['state']
        self.name = p['name']
        self.size_unit = p['size_unit']
        if p['size'] is not None:
            self.size = p['size'] * self._size_unit_map[self.size_unit]
        else:
            self.size = None
        self.force_resize = p['force_resize']
        self.force_remove = p['force_remove']
        self.force_remove_fenced = p['force_remove_fenced']
        self.flexvol_name = p['flexvol_name']
        self.vserver = p['vserver']

        if HAS_NETAPP_LIB is False:
            self.module.fail_json(
                msg="the python NetApp-Lib module is required")
        else:
            self.server = netapp_utils.setup_ontap_zapi(module=self.module,
                                                        vserver=self.vserver)

    def get_lun(self):
        """
        Return details about the LUN

        :return: Details about the lun
        :rtype: dict
        """

        luns = []
        tag = None
        while True:
            lun_info = netapp_utils.zapi.NaElement('lun-get-iter')
            if tag:
                lun_info.add_new_child('tag', tag, True)

            query_details = netapp_utils.zapi.NaElement('lun-info')
            query_details.add_new_child('vserver', self.vserver)
            query_details.add_new_child('volume', self.flexvol_name)

            query = netapp_utils.zapi.NaElement('query')
            query.add_child_elem(query_details)

            lun_info.add_child_elem(query)

            result = self.server.invoke_successfully(lun_info, True)
            if result.get_child_by_name('num-records') and int(
                    result.get_child_content('num-records')) >= 1:
                attr_list = result.get_child_by_name('attributes-list')
                luns.extend(attr_list.get_children())

            tag = result.get_child_content('next-tag')

            if tag is None:
                break

        # The LUNs have been extracted.
        # Find the specified lun and extract details.
        return_value = None
        for lun in luns:
            path = lun.get_child_content('path')
            _rest, _splitter, found_name = path.rpartition('/')

            if found_name == self.name:
                size = lun.get_child_content('size')

                # Find out if the lun is attached
                attached_to = None
                lun_id = None
                if lun.get_child_content('mapped') == 'true':
                    lun_map_list = netapp_utils.zapi.NaElement.create_node_with_children(
                        'lun-map-list-info', **{'path': path})

                    result = self.server.invoke_successfully(
                        lun_map_list, enable_tunneling=True)

                    igroups = result.get_child_by_name('initiator-groups')
                    if igroups:
                        for igroup_info in igroups.get_children():
                            igroup = igroup_info.get_child_content(
                                'initiator-group-name')
                            attached_to = igroup
                            lun_id = igroup_info.get_child_content('lun-id')

                return_value = {
                    'name': found_name,
                    'size': size,
                    'attached_to': attached_to,
                    'lun_id': lun_id
                }
            else:
                continue

        return return_value

    def create_lun(self):
        """
        Create LUN with requested name and size
        """
        path = '/vol/%s/%s' % (self.flexvol_name, self.name)
        lun_create = netapp_utils.zapi.NaElement.create_node_with_children(
            'lun-create-by-size', **{
                'path': path,
                'size': str(self.size),
                'ostype': 'linux'
            })

        try:
            self.server.invoke_successfully(lun_create, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as e:
            self.module.fail_json(
                msg="Error provisioning lun %s of size %s: %s" %
                (self.name, self.size, to_native(e)),
                exception=traceback.format_exc())

    def delete_lun(self):
        """
        Delete requested LUN
        """
        path = '/vol/%s/%s' % (self.flexvol_name, self.name)

        lun_delete = netapp_utils.zapi.NaElement.create_node_with_children(
            'lun-destroy', **{
                'path': path,
                'force': str(self.force_remove),
                'destroy-fenced-lun': str(self.force_remove_fenced)
            })

        try:
            self.server.invoke_successfully(lun_delete, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as e:
            self.module.fail_json(msg="Error deleting lun %s: %s" %
                                  (path, to_native(e)),
                                  exception=traceback.format_exc())

    def resize_lun(self):
        """
        Resize requested LUN.

        :return: True if LUN was actually re-sized, false otherwise.
        :rtype: bool
        """
        path = '/vol/%s/%s' % (self.flexvol_name, self.name)

        lun_resize = netapp_utils.zapi.NaElement.create_node_with_children(
            'lun-resize', **{
                'path': path,
                'size': str(self.size),
                'force': str(self.force_resize)
            })
        try:
            self.server.invoke_successfully(lun_resize, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as e:
            if to_native(e.code) == "9042":
                # Error 9042 denotes the new LUN size being the same as the
                # old LUN size. This happens when there's barely any difference
                # in the two sizes. For example, from 8388608 bytes to
                # 8194304 bytes. This should go away if/when the default size
                # requested/reported to/from the controller is changed to a
                # larger unit (MB/GB/TB).
                return False
            else:
                self.module.fail_json(msg="Error resizing lun %s: %s" %
                                      (path, to_native(e)),
                                      exception=traceback.format_exc())

        return True

    def apply(self):
        property_changed = False
        multiple_properties_changed = False
        size_changed = False
        lun_exists = False
        lun_detail = self.get_lun()

        if lun_detail:
            lun_exists = True
            current_size = lun_detail['size']

            if self.state == 'absent':
                property_changed = True

            elif self.state == 'present':
                if not int(current_size) == self.size:
                    size_changed = True
                    property_changed = True

        else:
            if self.state == 'present':
                property_changed = True

        if property_changed:
            if self.module.check_mode:
                pass
            else:
                if self.state == 'present':
                    if not lun_exists:
                        self.create_lun()

                    else:
                        if size_changed:
                            # Ensure that size was actually changed. Please
                            # read notes in 'resize_lun' function for details.
                            size_changed = self.resize_lun()
                            if not size_changed and not \
                                    multiple_properties_changed:
                                property_changed = False

                elif self.state == 'absent':
                    self.delete_lun()

        changed = property_changed or size_changed
        # TODO: include other details about the lun (size, etc.)
        self.module.exit_json(changed=changed)
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "state": {
            "required": False,
            "type": "str",
            "choices": ["present", "absent"]
        },
        "firewall_service_custom": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "state": {
                    "required": False,
                    "type": "str",
                    "choices": ["present", "absent"]
                },
                "app_category": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "id": {
                            "required": True,
                            "type": "int"
                        }
                    }
                },
                "app_service_type": {
                    "required": False,
                    "type": "str",
                    "choices": ["disable", "app-id", "app-category"]
                },
                "application": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "id": {
                            "required": True,
                            "type": "int"
                        }
                    }
                },
                "category": {
                    "required": False,
                    "type": "str"
                },
                "check_reset_range": {
                    "required": False,
                    "type": "str",
                    "choices": ["disable", "strict", "default"]
                },
                "color": {
                    "required": False,
                    "type": "int"
                },
                "comment": {
                    "required": False,
                    "type": "str"
                },
                "fqdn": {
                    "required": False,
                    "type": "str"
                },
                "helper": {
                    "required":
                    False,
                    "type":
                    "str",
                    "choices": [
                        "auto", "disable", "ftp", "tftp", "ras", "h323", "tns",
                        "mms", "sip", "pptp", "rtsp", "dns-udp", "dns-tcp",
                        "pmap", "rsh", "dcerpc", "mgcp", "gtp-c", "gtp-u",
                        "gtp-b"
                    ]
                },
                "icmpcode": {
                    "required": False,
                    "type": "int"
                },
                "icmptype": {
                    "required": False,
                    "type": "int"
                },
                "iprange": {
                    "required": False,
                    "type": "str"
                },
                "name": {
                    "required": True,
                    "type": "str"
                },
                "protocol": {
                    "required":
                    False,
                    "type":
                    "str",
                    "choices": [
                        "TCP/UDP/SCTP", "ICMP", "ICMP6", "IP", "HTTP", "FTP",
                        "CONNECT", "SOCKS-TCP", "SOCKS-UDP", "ALL"
                    ]
                },
                "protocol_number": {
                    "required": False,
                    "type": "int"
                },
                "proxy": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "sctp_portrange": {
                    "required": False,
                    "type": "str"
                },
                "session_ttl": {
                    "required": False,
                    "type": "int"
                },
                "tcp_halfclose_timer": {
                    "required": False,
                    "type": "int"
                },
                "tcp_halfopen_timer": {
                    "required": False,
                    "type": "int"
                },
                "tcp_portrange": {
                    "required": False,
                    "type": "str"
                },
                "tcp_timewait_timer": {
                    "required": False,
                    "type": "int"
                },
                "udp_idle_timer": {
                    "required": False,
                    "type": "int"
                },
                "udp_portrange": {
                    "required": False,
                    "type": "str"
                },
                "visibility": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_firewall_service(
                module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_firewall_service(
            module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
Ejemplo n.º 3
0
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "state": {
            "required": True,
            "type": "str",
            "choices": ["present", "absent"]
        },
        "system_ips_urlfilter_dns6": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "address6": {
                    "required": True,
                    "type": "str"
                },
                "status": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_system(module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_system(module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
class ElementSWInitiators(object):
    """
    Element Software Manage Element SW initiators
    """
    def __init__(self):
        self.argument_spec = netapp_utils.ontap_sf_host_argument_spec()

        self.argument_spec.update(dict(
            initiators=dict(
                type='list',
                options=dict(
                    name=dict(type='str', required=True),
                    alias=dict(type='str', default=None),
                    initiator_id=dict(type='int', default=None),
                    volume_access_groups=dict(type='list', default=None),
                    volume_access_group_id=dict(type='int', default=None),
                    attributes=dict(type='dict', default=None),
                )
            ),
            state=dict(choices=['present', 'absent'], default='present'),
        ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            supports_check_mode=True
        )

        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)

        if HAS_SF_SDK is False:
            self.module.fail_json(msg="Unable to import the SolidFire Python SDK")
        else:
            self.sfe = netapp_utils.create_sf_connection(module=self.module)

        self.elementsw_helper = NaElementSWModule(self.sfe)

        # iterate over each user-provided initiator
        for initiator in self.parameters.get('initiators'):
            # add telemetry attributes
            if 'attributes' in initiator:
                initiator['attributes'].update(self.elementsw_helper.set_element_attributes(source='na_elementsw_initiators'))
            else:
                initiator['attributes'] = self.elementsw_helper.set_element_attributes(source='na_elementsw_initiators')

    def compare_initiators(self, user_initiator, existing_initiator):
        """
        compare user input initiator with existing dict
        :return: True if matched, False otherwise
        """
        if user_initiator is None or existing_initiator is None:
            return False
        for param in user_initiator:
            # lookup initiator_name instead of name
            if param == 'name':
                if user_initiator['name'] == existing_initiator['initiator_name']:
                    pass
            elif user_initiator[param] == existing_initiator[param]:
                pass
            else:
                return True
        return False

    def initiator_to_dict(self, initiator_obj):
        """
        converts initiator class object to dict
        :return: reconstructed initiator dict
        """
        known_params = ['initiator_name',
                        'alias',
                        'initiator_id',
                        'volume_access_groups',
                        'volume_access_group_id',
                        'attributes']
        initiator_dict = {}

        # missing parameter cause error
        # so assign defaults
        for param in known_params:
            initiator_dict[param] = getattr(initiator_obj, param, None)
        return initiator_dict

    def find_initiator(self, id=None, name=None):
        """
        find a specific initiator
        :return: initiator dict
        """
        initiator_details = None
        if self.all_existing_initiators is None:
            return initiator_details
        for initiator in self.all_existing_initiators:
            # if name is provided or
            # if id is provided
            if name is not None:
                if initiator.initiator_name == name:
                    initiator_details = self.initiator_to_dict(initiator)
            elif id is not None:
                if initiator.initiator_id == id:
                    initiator_details = self.initiator_to_dict(initiator)
            else:
                # if neither id nor name provided
                # return everything
                initiator_details = self.all_existing_initiators
        return initiator_details

    def create_initiators(self, initiator):
        """
        create initiators
        """
        # create_initiators needs an array
        # so enclose this initiator in an array
        initiator_list = [initiator]
        try:
            self.sfe.create_initiators(initiator_list)
        except Exception as exception_object:
            self.module.fail_json(msg='Error creating initiator %s' % (to_native(exception_object)),
                                  exception=traceback.format_exc())

    def delete_initiators(self, initiator):
        """
        delete initiators
        """
        # delete_initiators needs an array
        # so enclose this initiator in an array
        initiator_id_array = [initiator]
        try:
            self.sfe.delete_initiators(initiator_id_array)
        except Exception as exception_object:
            self.module.fail_json(msg='Error deleting initiator %s' % (to_native(exception_object)),
                                  exception=traceback.format_exc())

    def modify_initiators(self, initiator, existing_initiator):
        """
        modify initiators
        """
        # create the new initiator dict
        # by merging old and new values
        merged_initiator = existing_initiator.copy()
        merged_initiator.update(initiator)

        # we MUST create an object before sending
        # the new initiator to modify_initiator
        initiator_object = ModifyInitiator(initiator_id=merged_initiator['initiator_id'],
                                           alias=merged_initiator['alias'],
                                           volume_access_group_id=merged_initiator['volume_access_group_id'],
                                           attributes=merged_initiator['attributes'])
        initiator_list = [initiator_object]
        try:
            self.sfe.modify_initiators(initiators=initiator_list)
        except Exception as exception_object:
            self.module.fail_json(msg='Error modifying initiator %s' % (to_native(exception_object)),
                                  exception=traceback.format_exc())

    def apply(self):
        """
        configure initiators
        """
        changed = False
        modify = None
        result_message = None

        # get all user provided initiators
        input_initiators = self.parameters.get('initiators')

        # get all initiators
        # store in a cache variable
        self.all_existing_initiators = self.sfe.list_initiators().initiators

        # iterate over each user-provided initiator
        for in_initiator in input_initiators:
            if self.parameters.get('state') == 'present':
                # check if initiator_id is provided and exists
                if 'initiator_id' in in_initiator and in_initiator['initiator_id'] is not None and \
                        self.find_initiator(id=in_initiator['initiator_id']) is not None:
                    if self.compare_initiators(in_initiator, self.find_initiator(id=in_initiator['initiator_id'])):
                        changed = True
                        result_message = 'modifying initiator(s)'
                        self.modify_initiators(in_initiator, self.find_initiator(id=in_initiator['initiator_id']))
                # otherwise check if name is provided and exists
                elif 'name' in in_initiator and in_initiator['name'] is not None and self.find_initiator(name=in_initiator['name']) is not None:
                    if self.compare_initiators(in_initiator, self.find_initiator(name=in_initiator['name'])):
                        changed = True
                        result_message = 'modifying initiator(s)'
                        self.modify_initiators(in_initiator, self.find_initiator(name=in_initiator['name']))
                # this is a create op if initiator doesn't exist
                else:
                    changed = True
                    result_message = 'creating initiator(s)'
                    self.create_initiators(in_initiator)
            elif self.parameters.get('state') == 'absent':
                # delete_initiators only processes ids
                # so pass ids of initiators to method
                if 'name' in in_initiator and in_initiator['name'] is not None and \
                        self.find_initiator(name=in_initiator['name']) is not None:
                    changed = True
                    result_message = 'deleting initiator(s)'
                    self.delete_initiators(self.find_initiator(name=in_initiator['name'])['initiator_id'])
                elif 'initiator_id' in in_initiator and in_initiator['initiator_id'] is not None and \
                        self.find_initiator(id=in_initiator['initiator_id']) is not None:
                    changed = True
                    result_message = 'deleting initiator(s)'
                    self.delete_initiators(in_initiator['initiator_id'])
        if self.module.check_mode is True:
            result_message = "Check mode, skipping changes"
        self.module.exit_json(changed=changed, msg=result_message)
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                name=dict(type='str', required=False, aliases=['alias']),
                ping=dict(type='bool', required=False, default=True),
                chap_secret=dict(type='str',
                                 required=False,
                                 aliases=['chap', 'password'],
                                 no_log=True),
                unnamed_discovery=dict(type='bool',
                                       required=False,
                                       default=True),
                log_path=dict(type='str', required=False),
            ))

        self.module = AnsibleModule(
            argument_spec=argument_spec,
            supports_check_mode=True,
        )
        args = self.module.params

        self.name = args['name']
        self.ping = args['ping']
        self.chap_secret = args['chap_secret']
        self.unnamed_discovery = args['unnamed_discovery']

        self.ssid = args['ssid']
        self.url = args['api_url']
        self.creds = dict(
            url_password=args['api_password'],
            validate_certs=args['validate_certs'],
            url_username=args['api_username'],
        )

        self.check_mode = self.module.check_mode
        self.post_body = dict()
        self.controllers = list()

        log_path = args['log_path']

        # logging setup
        self._logger = logging.getLogger(self.__class__.__name__)

        if log_path:
            logging.basicConfig(
                level=logging.DEBUG,
                filename=log_path,
                filemode='w',
                format=
                '%(relativeCreated)dms %(levelname)s %(module)s.%(funcName)s:%(lineno)d\n %(message)s'
            )

        if not self.url.endswith('/'):
            self.url += '/'

        if self.chap_secret:
            if len(self.chap_secret) < 12 or len(self.chap_secret) > 57:
                self.module.fail_json(
                    msg=
                    "The provided CHAP secret is not valid, it must be between 12 and 57"
                    " characters in length.")

            for c in self.chap_secret:
                ordinal = ord(c)
                if ordinal < 32 or ordinal > 126:
                    self.module.fail_json(
                        msg=
                        "The provided CHAP secret is not valid, it may only utilize ascii"
                        " characters with decimal values between 32 and 126.")
def main():
    module = AnsibleModule(
        argument_spec=dict(
            path=dict(type='path', required=True, aliases=['dest', 'destfile', 'name']),
            state=dict(type='str', default='present', choices=['absent', 'present']),
            marker=dict(type='str', default='# {mark} ANSIBLE MANAGED BLOCK'),
            block=dict(type='str', default='', aliases=['content']),
            insertafter=dict(type='str'),
            insertbefore=dict(type='str'),
            create=dict(type='bool', default=False),
            backup=dict(type='bool', default=False),
            validate=dict(type='str'),
            marker_begin=dict(type='str', default='BEGIN'),
            marker_end=dict(type='str', default='END'),
        ),
        mutually_exclusive=[['insertbefore', 'insertafter']],
        add_file_common_args=True,
        supports_check_mode=True
    )

    params = module.params
    path = params['path']

    if os.path.isdir(path):
        module.fail_json(rc=256,
                         msg='Path %s is a directory !' % path)

    path_exists = os.path.exists(path)
    if not path_exists:
        if not module.boolean(params['create']):
            module.fail_json(rc=257,
                             msg='Path %s does not exist !' % path)
        destpath = os.path.dirname(path)
        if not os.path.exists(destpath) and not module.check_mode:
            try:
                os.makedirs(destpath)
            except Exception as e:
                module.fail_json(msg='Error creating %s Error code: %s Error description: %s' % (destpath, e[0], e[1]))
        original = None
        lines = []
    else:
        f = open(path, 'rb')
        original = f.read()
        f.close()
        lines = original.splitlines()

    diff = {'before': '',
            'after': '',
            'before_header': '%s (content)' % path,
            'after_header': '%s (content)' % path}

    if module._diff and original:
        diff['before'] = original

    insertbefore = params['insertbefore']
    insertafter = params['insertafter']
    block = to_bytes(params['block'])
    marker = to_bytes(params['marker'])
    present = params['state'] == 'present'

    if not present and not path_exists:
        module.exit_json(changed=False, msg="File %s not present" % path)

    if insertbefore is None and insertafter is None:
        insertafter = 'EOF'

    if insertafter not in (None, 'EOF'):
        insertre = re.compile(to_bytes(insertafter, errors='surrogate_or_strict'))
    elif insertbefore not in (None, 'BOF'):
        insertre = re.compile(to_bytes(insertbefore, errors='surrogate_or_strict'))
    else:
        insertre = None

    marker0 = re.sub(b(r'{mark}'), b(params['marker_begin']), marker)
    marker1 = re.sub(b(r'{mark}'), b(params['marker_end']), marker)
    if present and block:
        # Escape sequences like '\n' need to be handled in Ansible 1.x
        if module.ansible_version.startswith('1.'):
            block = re.sub('', block, '')
        blocklines = [marker0] + block.splitlines() + [marker1]
    else:
        blocklines = []

    n0 = n1 = None
    for i, line in enumerate(lines):
        if line == marker0:
            n0 = i
        if line == marker1:
            n1 = i

    if None in (n0, n1):
        n0 = None
        if insertre is not None:
            for i, line in enumerate(lines):
                if insertre.search(line):
                    n0 = i
            if n0 is None:
                n0 = len(lines)
            elif insertafter is not None:
                n0 += 1
        elif insertbefore is not None:
            n0 = 0  # insertbefore=BOF
        else:
            n0 = len(lines)  # insertafter=EOF
    elif n0 < n1:
        lines[n0:n1 + 1] = []
    else:
        lines[n1:n0 + 1] = []
        n0 = n1

    lines[n0:n0] = blocklines

    if lines:
        result = b('\n').join(lines)
        if original is None or original.endswith(b('\n')):
            result += b('\n')
    else:
        result = b''

    if module._diff:
        diff['after'] = result

    if original == result:
        msg = ''
        changed = False
    elif original is None:
        msg = 'File created'
        changed = True
    elif not blocklines:
        msg = 'Block removed'
        changed = True
    else:
        msg = 'Block inserted'
        changed = True

    if changed and not module.check_mode:
        if module.boolean(params['backup']) and path_exists:
            module.backup_local(path)
        # We should always follow symlinks so that we change the real file
        real_path = os.path.realpath(params['path'])
        write_changes(module, result, real_path)

    if module.check_mode and not path_exists:
        module.exit_json(changed=changed, msg=msg, diff=diff)

    attr_diff = {}
    msg, changed = check_file_attrs(module, changed, msg, attr_diff)

    attr_diff['before_header'] = '%s (file attributes)' % path
    attr_diff['after_header'] = '%s (file attributes)' % path

    difflist = [diff, attr_diff]
    module.exit_json(changed=changed, msg=msg, diff=difflist)
Ejemplo n.º 7
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            vg=dict(type='str', required=True),
            lv=dict(type='str'),
            size=dict(type='str'),
            opts=dict(type='str'),
            state=dict(type='str',
                       default='present',
                       choices=['absent', 'present']),
            force=dict(type='bool', default=False),
            shrink=dict(type='bool', default=True),
            active=dict(type='bool', default=True),
            snapshot=dict(type='str'),
            pvs=dict(type='str'),
            resizefs=dict(type='bool', default=False),
            thinpool=dict(type='str'),
        ),
        supports_check_mode=True,
        required_one_of=(['lv', 'thinpool'], ),
    )

    module.run_command_environ_update = LVOL_ENV_VARS

    # Determine if the "--yes" option should be used
    version_found = get_lvm_version(module)
    if version_found is None:
        module.fail_json(msg="Failed to get LVM version number")
    version_yesopt = mkversion(2, 2, 99)  # First LVM with the "--yes" option
    if version_found >= version_yesopt:
        yesopt = "--yes"
    else:
        yesopt = ""

    vg = module.params['vg']
    lv = module.params['lv']
    size = module.params['size']
    opts = module.params['opts']
    state = module.params['state']
    force = module.boolean(module.params['force'])
    shrink = module.boolean(module.params['shrink'])
    active = module.boolean(module.params['active'])
    resizefs = module.boolean(module.params['resizefs'])
    thinpool = module.params['thinpool']
    size_opt = 'L'
    size_unit = 'm'
    snapshot = module.params['snapshot']
    pvs = module.params['pvs']

    if pvs is None:
        pvs = ""
    else:
        pvs = pvs.replace(",", " ")

    if opts is None:
        opts = ""

    # Add --test option when running in check-mode
    if module.check_mode:
        test_opt = ' --test'
    else:
        test_opt = ''

    if size:
        # LVCREATE(8) -l --extents option with percentage
        if '%' in size:
            size_parts = size.split('%', 1)
            size_percent = int(size_parts[0])
            if size_percent > 100:
                module.fail_json(
                    msg="Size percentage cannot be larger than 100%")
            size_whole = size_parts[1]
            if size_whole == 'ORIGIN':
                module.fail_json(msg="Snapshot Volumes are not supported")
            elif size_whole not in ['VG', 'PVS', 'FREE']:
                module.fail_json(
                    msg="Specify extents as a percentage of VG|PVS|FREE")
            size_opt = 'l'
            size_unit = ''

        if '%' not in size:
            # LVCREATE(8) -L --size option unit
            if size[-1].lower() in 'bskmgtpe':
                size_unit = size[-1].lower()
                size = size[0:-1]

            try:
                float(size)
                if not size[0].isdigit():
                    raise ValueError()
            except ValueError:
                module.fail_json(msg="Bad size specification of '%s'" % size)

    # when no unit, megabytes by default
    if size_opt == 'l':
        unit = 'm'
    else:
        unit = size_unit

    # Get information on volume group requested
    vgs_cmd = module.get_bin_path("vgs", required=True)
    rc, current_vgs, err = module.run_command(
        "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s"
        % (vgs_cmd, unit, vg))

    if rc != 0:
        if state == 'absent':
            module.exit_json(changed=False,
                             stdout="Volume group %s does not exist." % vg)
        else:
            module.fail_json(msg="Volume group %s does not exist." % vg,
                             rc=rc,
                             err=err)

    vgs = parse_vgs(current_vgs)
    this_vg = vgs[0]

    # Get information on logical volume requested
    lvs_cmd = module.get_bin_path("lvs", required=True)
    rc, current_lvs, err = module.run_command(
        "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s"
        % (lvs_cmd, unit, vg))

    if rc != 0:
        if state == 'absent':
            module.exit_json(changed=False,
                             stdout="Volume group %s does not exist." % vg)
        else:
            module.fail_json(msg="Volume group %s does not exist." % vg,
                             rc=rc,
                             err=err)

    changed = False

    lvs = parse_lvs(current_lvs)

    if snapshot:
        # Check snapshot pre-conditions
        for test_lv in lvs:
            if test_lv['name'] == lv or test_lv['name'] == thinpool:
                if not test_lv['thinpool'] and not thinpool:
                    break
                else:
                    module.fail_json(
                        msg="Snapshots of thin pool LVs are not supported.")
        else:
            module.fail_json(
                msg="Snapshot origin LV %s does not exist in volume group %s."
                % (lv, vg))
        check_lv = snapshot

    elif thinpool:
        if lv:
            # Check thin volume pre-conditions
            for test_lv in lvs:
                if test_lv['name'] == thinpool:
                    break
            else:
                module.fail_json(
                    msg="Thin pool LV %s does not exist in volume group %s." %
                    (thinpool, vg))
            check_lv = lv
        else:
            check_lv = thinpool
    else:
        check_lv = lv

    for test_lv in lvs:
        if test_lv['name'] in (check_lv, check_lv.rsplit('/', 1)[-1]):
            this_lv = test_lv
            break
    else:
        this_lv = None

    msg = ''
    if this_lv is None:
        if state == 'present':
            # Require size argument except for snapshot of thin volumes
            if (lv or thinpool) and not size:
                for test_lv in lvs:
                    if test_lv['name'] == lv and test_lv[
                            'thinvol'] and snapshot:
                        break
                else:
                    module.fail_json(msg="No size given.")

            # create LV
            lvcreate_cmd = module.get_bin_path("lvcreate", required=True)
            if snapshot is not None:
                if size:
                    cmd = "%s %s %s -%s %s%s -s -n %s %s %s/%s" % (
                        lvcreate_cmd, test_opt, yesopt, size_opt, size,
                        size_unit, snapshot, opts, vg, lv)
                else:
                    cmd = "%s %s %s -s -n %s %s %s/%s" % (
                        lvcreate_cmd, test_opt, yesopt, snapshot, opts, vg, lv)
            elif thinpool and lv:
                if size_opt == 'l':
                    module.fail_json(
                        changed=False,
                        msg="Thin volume sizing with percentage not supported."
                    )
                size_opt = 'V'
                cmd = "%s %s -n %s -%s %s%s %s -T %s/%s" % (
                    lvcreate_cmd, yesopt, lv, size_opt, size, size_unit, opts,
                    vg, thinpool)
            elif thinpool and not lv:
                cmd = "%s %s -%s %s%s %s -T %s/%s" % (
                    lvcreate_cmd, yesopt, size_opt, size, size_unit, opts, vg,
                    thinpool)
            else:
                cmd = "%s %s %s -n %s -%s %s%s %s %s %s" % (
                    lvcreate_cmd, test_opt, yesopt, lv, size_opt, size,
                    size_unit, opts, vg, pvs)
            rc, _, err = module.run_command(cmd)
            if rc == 0:
                changed = True
            else:
                module.fail_json(msg="Creating logical volume '%s' failed" %
                                 lv,
                                 rc=rc,
                                 err=err)
    else:
        if state == 'absent':
            # remove LV
            if not force:
                module.fail_json(
                    msg=
                    "Sorry, no removal of logical volume %s without force=yes."
                    % (this_lv['name']))
            lvremove_cmd = module.get_bin_path("lvremove", required=True)
            rc, _, err = module.run_command(
                "%s %s --force %s/%s" %
                (lvremove_cmd, test_opt, vg, this_lv['name']))
            if rc == 0:
                module.exit_json(changed=True)
            else:
                module.fail_json(msg="Failed to remove logical volume %s" %
                                 (lv),
                                 rc=rc,
                                 err=err)

        elif not size:
            pass

        elif size_opt == 'l':
            # Resize LV based on % value
            tool = None
            size_free = this_vg['free']
            if size_whole == 'VG' or size_whole == 'PVS':
                size_requested = size_percent * this_vg['size'] / 100
            else:  # size_whole == 'FREE':
                size_requested = size_percent * this_vg['free'] / 100
            if '+' in size:
                size_requested += this_lv['size']
            if this_lv['size'] < size_requested:
                if (size_free > 0) and (('+' not in size) or
                                        (size_free >=
                                         (size_requested - this_lv['size']))):
                    tool = module.get_bin_path("lvextend", required=True)
                else:
                    module.fail_json(
                        msg=
                        "Logical Volume %s could not be extended. Not enough free space left (%s%s required / %s%s available)"
                        % (this_lv['name'], (size_requested - this_lv['size']),
                           unit, size_free, unit))
            elif shrink and this_lv['size'] > size_requested + this_vg[
                    'ext_size']:  # more than an extent too large
                if size_requested == 0:
                    module.fail_json(
                        msg="Sorry, no shrinking of %s to 0 permitted." %
                        (this_lv['name']))
                elif not force:
                    module.fail_json(
                        msg="Sorry, no shrinking of %s without force=yes" %
                        (this_lv['name']))
                else:
                    tool = module.get_bin_path("lvreduce", required=True)
                    tool = '%s %s' % (tool, '--force')

            if tool:
                if resizefs:
                    tool = '%s %s' % (tool, '--resizefs')
                cmd = "%s %s -%s %s%s %s/%s %s" % (tool, test_opt, size_opt,
                                                   size, size_unit, vg,
                                                   this_lv['name'], pvs)
                rc, out, err = module.run_command(cmd)
                if "Reached maximum COW size" in out:
                    module.fail_json(msg="Unable to resize %s to %s%s" %
                                     (lv, size, size_unit),
                                     rc=rc,
                                     err=err,
                                     out=out)
                elif rc == 0:
                    changed = True
                    msg = "Volume %s resized to %s%s" % (this_lv['name'],
                                                         size_requested, unit)
                elif "matches existing size" in err:
                    module.exit_json(changed=False,
                                     vg=vg,
                                     lv=this_lv['name'],
                                     size=this_lv['size'])
                elif "not larger than existing size" in err:
                    module.exit_json(
                        changed=False,
                        vg=vg,
                        lv=this_lv['name'],
                        size=this_lv['size'],
                        msg="Original size is larger than requested size",
                        err=err)
                else:
                    module.fail_json(msg="Unable to resize %s to %s%s" %
                                     (lv, size, size_unit),
                                     rc=rc,
                                     err=err)

        else:
            # resize LV based on absolute values
            tool = None
            if float(size) > this_lv['size']:
                tool = module.get_bin_path("lvextend", required=True)
            elif shrink and float(size) < this_lv['size']:
                if float(size) == 0:
                    module.fail_json(
                        msg="Sorry, no shrinking of %s to 0 permitted." %
                        (this_lv['name']))
                if not force:
                    module.fail_json(
                        msg="Sorry, no shrinking of %s without force=yes." %
                        (this_lv['name']))
                else:
                    tool = module.get_bin_path("lvreduce", required=True)
                    tool = '%s %s' % (tool, '--force')

            if tool:
                if resizefs:
                    tool = '%s %s' % (tool, '--resizefs')
                cmd = "%s %s -%s %s%s %s/%s %s" % (tool, test_opt, size_opt,
                                                   size, size_unit, vg,
                                                   this_lv['name'], pvs)
                rc, out, err = module.run_command(cmd)
                if "Reached maximum COW size" in out:
                    module.fail_json(msg="Unable to resize %s to %s%s" %
                                     (lv, size, size_unit),
                                     rc=rc,
                                     err=err,
                                     out=out)
                elif rc == 0:
                    changed = True
                elif "matches existing size" in err:
                    module.exit_json(changed=False,
                                     vg=vg,
                                     lv=this_lv['name'],
                                     size=this_lv['size'])
                elif "not larger than existing size" in err:
                    module.exit_json(
                        changed=False,
                        vg=vg,
                        lv=this_lv['name'],
                        size=this_lv['size'],
                        msg="Original size is larger than requested size",
                        err=err)
                else:
                    module.fail_json(msg="Unable to resize %s to %s%s" %
                                     (lv, size, size_unit),
                                     rc=rc,
                                     err=err)

    if this_lv is not None:
        if active:
            lvchange_cmd = module.get_bin_path("lvchange", required=True)
            rc, _, err = module.run_command(
                "%s -ay %s/%s" % (lvchange_cmd, vg, this_lv['name']))
            if rc == 0:
                module.exit_json(changed=((not this_lv['active']) or changed),
                                 vg=vg,
                                 lv=this_lv['name'],
                                 size=this_lv['size'])
            else:
                module.fail_json(msg="Failed to activate logical volume %s" %
                                 (lv),
                                 rc=rc,
                                 err=err)
        else:
            lvchange_cmd = module.get_bin_path("lvchange", required=True)
            rc, _, err = module.run_command(
                "%s -an %s/%s" % (lvchange_cmd, vg, this_lv['name']))
            if rc == 0:
                module.exit_json(changed=(this_lv['active'] or changed),
                                 vg=vg,
                                 lv=this_lv['name'],
                                 size=this_lv['size'])
            else:
                module.fail_json(msg="Failed to deactivate logical volume %s" %
                                 (lv),
                                 rc=rc,
                                 err=err)

    module.exit_json(changed=changed, msg=msg)
Ejemplo n.º 8
0
def main():

    module = AnsibleModule(
        argument_spec=dict(
            host=dict(type='str', default='127.0.0.1'),
            timeout=dict(type='int', default=300),
            connect_timeout=dict(type='int', default=5),
            delay=dict(type='int', default=0),
            port=dict(type='int'),
            active_connection_states=dict(type='list', default=['ESTABLISHED', 'FIN_WAIT1', 'FIN_WAIT2', 'SYN_RECV', 'SYN_SENT', 'TIME_WAIT']),
            path=dict(type='path'),
            search_regex=dict(type='str'),
            state=dict(type='str', default='started', choices=['absent', 'drained', 'present', 'started', 'stopped']),
            exclude_hosts=dict(type='list'),
            sleep=dict(type='int', default=1),
            msg=dict(type='str'),
        ),
    )

    host = module.params['host']
    timeout = module.params['timeout']
    connect_timeout = module.params['connect_timeout']
    delay = module.params['delay']
    port = module.params['port']
    state = module.params['state']
    path = module.params['path']
    search_regex = module.params['search_regex']
    msg = module.params['msg']

    if search_regex is not None:
        compiled_search_re = re.compile(search_regex, re.MULTILINE)
    else:
        compiled_search_re = None

    match_groupdict = {}
    match_groups = ()

    if port and path:
        module.fail_json(msg="port and path parameter can not both be passed to wait_for", elapsed=0)
    if path and state == 'stopped':
        module.fail_json(msg="state=stopped should only be used for checking a port in the wait_for module", elapsed=0)
    if path and state == 'drained':
        module.fail_json(msg="state=drained should only be used for checking a port in the wait_for module", elapsed=0)
    if module.params['exclude_hosts'] is not None and state != 'drained':
        module.fail_json(msg="exclude_hosts should only be with state=drained", elapsed=0)
    for _connection_state in module.params['active_connection_states']:
        try:
            get_connection_state_id(_connection_state)
        except Exception:
            module.fail_json(msg="unknown active_connection_state (%s) defined" % _connection_state, elapsed=0)

    start = datetime.datetime.utcnow()

    if delay:
        time.sleep(delay)

    if not port and not path and state != 'drained':
        time.sleep(timeout)
    elif state in ['absent', 'stopped']:
        # first wait for the stop condition
        end = start + datetime.timedelta(seconds=timeout)

        while datetime.datetime.utcnow() < end:
            if path:
                try:
                    if not os.access(path, os.F_OK):
                        break
                except IOError:
                    break
            elif port:
                try:
                    s = socket.create_connection((host, port), connect_timeout)
                    s.shutdown(socket.SHUT_RDWR)
                    s.close()
                except Exception:
                    break
            # Conditions not yet met, wait and try again
            time.sleep(module.params['sleep'])
        else:
            elapsed = datetime.datetime.utcnow() - start
            if port:
                module.fail_json(msg=msg or "Timeout when waiting for %s:%s to stop." % (host, port), elapsed=elapsed.seconds)
            elif path:
                module.fail_json(msg=msg or "Timeout when waiting for %s to be absent." % (path), elapsed=elapsed.seconds)

    elif state in ['started', 'present']:
        # wait for start condition
        end = start + datetime.timedelta(seconds=timeout)
        while datetime.datetime.utcnow() < end:
            if path:
                try:
                    os.stat(path)
                except OSError as e:
                    # If anything except file not present, throw an error
                    if e.errno != 2:
                        elapsed = datetime.datetime.utcnow() - start
                        module.fail_json(msg=msg or "Failed to stat %s, %s" % (path, e.strerror), elapsed=elapsed.seconds)
                    # file doesn't exist yet, so continue
                else:
                    # File exists.  Are there additional things to check?
                    if not compiled_search_re:
                        # nope, succeed!
                        break
                    try:
                        f = open(path)
                        try:
                            search = re.search(compiled_search_re, f.read())
                            if search:
                                if search.groupdict():
                                    match_groupdict = search.groupdict()
                                if search.groups():
                                    match_groups = search.groups()

                                break
                        finally:
                            f.close()
                    except IOError:
                        pass
            elif port:
                alt_connect_timeout = math.ceil(_timedelta_total_seconds(end - datetime.datetime.utcnow()))
                try:
                    s = socket.create_connection((host, port), min(connect_timeout, alt_connect_timeout))
                except Exception:
                    # Failed to connect by connect_timeout. wait and try again
                    pass
                else:
                    # Connected -- are there additional conditions?
                    if compiled_search_re:
                        data = ''
                        matched = False
                        while datetime.datetime.utcnow() < end:
                            max_timeout = math.ceil(_timedelta_total_seconds(end - datetime.datetime.utcnow()))
                            (readable, w, e) = select.select([s], [], [], max_timeout)
                            if not readable:
                                # No new data.  Probably means our timeout
                                # expired
                                continue
                            response = s.recv(1024)
                            if not response:
                                # Server shutdown
                                break
                            data += to_native(response, errors='surrogate_or_strict')
                            if re.search(compiled_search_re, data):
                                matched = True
                                break

                        # Shutdown the client socket
                        try:
                            s.shutdown(socket.SHUT_RDWR)
                        except socket.error as e:
                            if e.errno != errno.ENOTCONN:
                                raise
                        # else, the server broke the connection on its end, assume it's not ready
                        else:
                            s.close()
                        if matched:
                            # Found our string, success!
                            break
                    else:
                        # Connection established, success!
                        try:
                            s.shutdown(socket.SHUT_RDWR)
                        except socket.error as e:
                            if e.errno != errno.ENOTCONN:
                                raise
                        # else, the server broke the connection on its end, assume it's not ready
                        else:
                            s.close()
                        break

            # Conditions not yet met, wait and try again
            time.sleep(module.params['sleep'])

        else:   # while-else
            # Timeout expired
            elapsed = datetime.datetime.utcnow() - start
            if port:
                if search_regex:
                    module.fail_json(msg=msg or "Timeout when waiting for search string %s in %s:%s" % (search_regex, host, port), elapsed=elapsed.seconds)
                else:
                    module.fail_json(msg=msg or "Timeout when waiting for %s:%s" % (host, port), elapsed=elapsed.seconds)
            elif path:
                if search_regex:
                    module.fail_json(msg=msg or "Timeout when waiting for search string %s in %s" % (search_regex, path), elapsed=elapsed.seconds)
                else:
                    module.fail_json(msg=msg or "Timeout when waiting for file %s" % (path), elapsed=elapsed.seconds)

    elif state == 'drained':
        # wait until all active connections are gone
        end = start + datetime.timedelta(seconds=timeout)
        tcpconns = TCPConnectionInfo(module)
        while datetime.datetime.utcnow() < end:
            try:
                if tcpconns.get_active_connections_count() == 0:
                    break
            except IOError:
                pass
            # Conditions not yet met, wait and try again
            time.sleep(module.params['sleep'])
        else:
            elapsed = datetime.datetime.utcnow() - start
            module.fail_json(msg=msg or "Timeout when waiting for %s:%s to drain" % (host, port), elapsed=elapsed.seconds)

    elapsed = datetime.datetime.utcnow() - start
    module.exit_json(state=state, port=port, search_regex=search_regex, match_groups=match_groups, match_groupdict=match_groupdict, path=path,
                     elapsed=elapsed.seconds)
Ejemplo n.º 9
0
def main():
    module = AnsibleModule(
        argument_spec=dict(path=dict(type='path',
                                     required=True,
                                     aliases=['name']),
                           entry=dict(type='str'),
                           entity=dict(type='str', default=''),
                           etype=dict(
                               type='str',
                               choices=['group', 'mask', 'other', 'user'],
                           ),
                           permissions=dict(type='str'),
                           state=dict(
                               type='str',
                               default='query',
                               choices=['absent', 'present', 'query'],
                           ),
                           follow=dict(type='bool', default=True),
                           default=dict(type='bool', default=False),
                           recursive=dict(type='bool', default=False),
                           recalculate_mask=dict(
                               type='str',
                               default='default',
                               choices=['default', 'mask', 'no_mask'],
                           ),
                           use_nfsv4_acls=dict(type='bool', default=False)),
        supports_check_mode=True,
    )

    if platform.system().lower() not in ['linux', 'freebsd']:
        module.fail_json(msg="The acl module is not available on this system.")

    path = module.params.get('path')
    entry = module.params.get('entry')
    entity = module.params.get('entity')
    etype = module.params.get('etype')
    permissions = module.params.get('permissions')
    state = module.params.get('state')
    follow = module.params.get('follow')
    default = module.params.get('default')
    recursive = module.params.get('recursive')
    recalculate_mask = module.params.get('recalculate_mask')
    use_nfsv4_acls = module.params.get('use_nfsv4_acls')

    if not os.path.exists(path):
        module.fail_json(msg="Path not found or not accessible.")

    if state == 'query':
        if recursive:
            module.fail_json(
                msg="'recursive' MUST NOT be set when 'state=query'.")

        if recalculate_mask in ['mask', 'no_mask']:
            module.fail_json(
                msg=
                "'recalculate_mask' MUST NOT be set to 'mask' or 'no_mask' when 'state=query'."
            )

    if not entry:
        if state == 'absent' and permissions:
            module.fail_json(
                msg="'permissions' MUST NOT be set when 'state=absent'.")

        if state == 'absent' and not entity:
            module.fail_json(msg="'entity' MUST be set when 'state=absent'.")

        if state in ['present', 'absent'] and not etype:
            module.fail_json(msg="'etype' MUST be set when 'state=%s'." %
                             state)

    if entry:
        if etype or entity or permissions:
            module.fail_json(
                msg=
                "'entry' MUST NOT be set when 'entity', 'etype' or 'permissions' are set."
            )

        if state == 'present' and not entry.count(":") in [2, 3]:
            module.fail_json(
                msg=
                "'entry' MUST have 3 or 4 sections divided by ':' when 'state=present'."
            )

        if state == 'absent' and not entry.count(":") in [1, 2]:
            module.fail_json(
                msg=
                "'entry' MUST have 2 or 3 sections divided by ':' when 'state=absent'."
            )

        if state == 'query':
            module.fail_json(msg="'entry' MUST NOT be set when 'state=query'.")

        default_flag, etype, entity, permissions = split_entry(entry)
        if default_flag is not None:
            default = default_flag

    if platform.system().lower() == 'freebsd':
        if recursive:
            module.fail_json(
                msg="recursive is not supported on that platform.")

    changed = False
    msg = ""

    if state == 'present':
        entry = build_entry(etype, entity, permissions, use_nfsv4_acls)
        command = build_command(module, 'set', path, follow, default,
                                recursive, recalculate_mask, entry)
        changed = acl_changed(module, command)

        if changed and not module.check_mode:
            run_acl(module, command)
        msg = "%s is present" % entry

    elif state == 'absent':
        entry = build_entry(etype, entity, use_nfsv4_acls)
        command = build_command(module, 'rm', path, follow, default, recursive,
                                recalculate_mask, entry)
        changed = acl_changed(module, command)

        if changed and not module.check_mode:
            run_acl(module, command, False)
        msg = "%s is absent" % entry

    elif state == 'query':
        msg = "current acl"

    acl = run_acl(
        module,
        build_command(module, 'get', path, follow, default, recursive,
                      recalculate_mask))

    module.exit_json(changed=changed, msg=msg, acl=acl)
def main():

    # define the available arguments/parameters that a user can pass to
    # the module

    fixed_ip_arg_spec = dict(
        mac=dict(type='str'),
        ip=dict(type='str'),
        name=dict(type='str'),
    )

    reserved_ip_arg_spec = dict(
        start=dict(type='str'),
        end=dict(type='str'),
        comment=dict(type='str'),
    )

    argument_spec = meraki_argument_spec()
    argument_spec.update(
        net_id=dict(type='str'),
        net_name=dict(type='str'),
        name=dict(type='str'),
        subnet=dict(type='str'),
        gateway_ip=dict(type='str'),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present', 'query']),
        fixed_ip_assignments=dict(type='list',
                                  elements='dict',
                                  options=fixed_ip_arg_spec),
        reserved_ip_ranges=dict(type='list',
                                elements='dict',
                                options=reserved_ip_arg_spec),
        route_id=dict(type='str'),
        enabled=dict(type='bool'),
    )

    # the AnsibleModule object will be our abstraction working with Ansible
    # this includes instantiation, a couple of common attr would be the
    # args/params passed to the execution, as well as if the module
    # supports check mode
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    meraki = MerakiModule(module, function='static_route')
    module.params['follow_redirects'] = 'all'
    payload = None

    query_urls = {'static_route': '/networks/{net_id}/staticRoutes'}
    query_one_urls = {
        'static_route': '/networks/{net_id}/staticRoutes/{route_id}'
    }
    create_urls = {'static_route': '/networks/{net_id}/staticRoutes/'}
    update_urls = {
        'static_route': '/networks/{net_id}/staticRoutes/{route_id}'
    }
    delete_urls = {
        'static_route': '/networks/{net_id}/staticRoutes/{route_id}'
    }
    meraki.url_catalog['get_all'].update(query_urls)
    meraki.url_catalog['get_one'].update(query_one_urls)
    meraki.url_catalog['create'] = create_urls
    meraki.url_catalog['update'] = update_urls
    meraki.url_catalog['delete'] = delete_urls

    if not meraki.params['org_name'] and not meraki.params['org_id']:
        meraki.fail_json(
            msg="Parameters 'org_name' or 'org_id' parameters are required")
    if not meraki.params['net_name'] and not meraki.params['net_id']:
        meraki.fail_json(
            msg="Parameters 'net_name' or 'net_id' parameters are required")
    if meraki.params['net_name'] and meraki.params['net_id']:
        meraki.fail_json(msg="'net_name' and 'net_id' are mutually exclusive")

    # Construct payload
    if meraki.params['state'] == 'present':
        payload = dict()
        if meraki.params['net_name']:
            payload['name'] = meraki.params['net_name']

    # manipulate or modify the state as needed (this is going to be the
    # part where your module will do what it needs to do)

    org_id = meraki.params['org_id']
    if not org_id:
        org_id = meraki.get_org_id(meraki.params['org_name'])
    net_id = meraki.params['net_id']
    if net_id is None:
        nets = meraki.get_nets(org_id=org_id)
        net_id = meraki.get_net_id(net_name=meraki.params['net_name'],
                                   data=nets)

    if meraki.params['state'] == 'query':
        if meraki.params['route_id'] is not None:
            meraki.result['data'] = get_static_route(meraki, net_id,
                                                     meraki.params['route_id'])
        else:
            meraki.result['data'] = get_static_routes(meraki, net_id)
    elif meraki.params['state'] == 'present':
        payload = {
            'name': meraki.params['name'],
            'subnet': meraki.params['subnet'],
            'gatewayIp': meraki.params['gateway_ip'],
        }
        if meraki.params['fixed_ip_assignments'] is not None:
            payload['fixedIpAssignments'] = fixed_ip_factory(
                meraki, meraki.params['fixed_ip_assignments'])
        if meraki.params['reserved_ip_ranges'] is not None:
            payload['reservedIpRanges'] = meraki.params['reserved_ip_ranges']
            # meraki.fail_json(msg="payload", payload=payload)
        if meraki.params['enabled'] is not None:
            payload['enabled'] = meraki.params['enabled']
        if meraki.params['route_id']:
            existing_route = get_static_route(meraki, net_id,
                                              meraki.params['route_id'])
            proposed = existing_route.copy()
            proposed.update(payload)
            if module.check_mode:
                meraki.result['data'] = proposed
                meraki.result['data'].update(payload)
                meraki.exit_json(**meraki.result)
            if meraki.is_update_required(existing_route,
                                         proposed,
                                         optional_ignore=['id']):
                path = meraki.construct_path(
                    'update',
                    net_id=net_id,
                    custom={'route_id': meraki.params['route_id']})
                meraki.result['data'] = meraki.request(
                    path, method="PUT", payload=json.dumps(payload))
                meraki.result['changed'] = True
            else:
                meraki.result['data'] = existing_route
        else:
            if module.check_mode:
                meraki.result['data'] = payload
                meraki.exit_json(**meraki.result)
            path = meraki.construct_path('create', net_id=net_id)
            meraki.result['data'] = meraki.request(path,
                                                   method="POST",
                                                   payload=json.dumps(payload))
            meraki.result['changed'] = True
    elif meraki.params['state'] == 'absent':
        if module.check_mode:
            meraki.exit_json(**meraki.result)
        path = meraki.construct_path(
            'delete',
            net_id=net_id,
            custom={'route_id': meraki.params['route_id']})
        meraki.result['data'] = meraki.request(path, method='DELETE')
        meraki.result['changed'] = True

    # in the event of a successful module execution, you will want to
    # simple AnsibleModule.exit_json(), passing the key/value results
    meraki.exit_json(**meraki.result)
Ejemplo n.º 11
0
def main():
    module = AnsibleModule(
        argument_spec=dict(list_all=dict(required=False,
                                         type='bool',
                                         default=False),
                           name=dict(type='str'),
                           repo=dict(type='path'),
                           scope=dict(required=False,
                                      type='str',
                                      choices=['local', 'global', 'system']),
                           state=dict(required=False,
                                      type='str',
                                      default='present',
                                      choices=['present', 'absent']),
                           value=dict(required=False)),
        mutually_exclusive=[['list_all', 'name'], ['list_all', 'value'],
                            ['list_all', 'state']],
        required_if=[('scope', 'local', ['repo'])],
        required_one_of=[['list_all', 'name']],
        supports_check_mode=True,
    )
    git_path = module.get_bin_path('git', True)

    params = module.params
    # We check error message for a pattern, so we need to make sure the messages appear in the form we're expecting.
    # Set the locale to C to ensure consistent messages.
    module.run_command_environ_update = dict(LANG='C',
                                             LC_ALL='C',
                                             LC_MESSAGES='C',
                                             LC_CTYPE='C')

    if params['name']:
        name = params['name']
    else:
        name = None

    if params['scope']:
        scope = params['scope']
    elif params['list_all']:
        scope = None
    else:
        scope = 'system'

    if params['state'] == 'absent':
        unset = 'unset'
        params['value'] = None
    else:
        unset = None

    if params['value']:
        new_value = params['value']
    else:
        new_value = None

    args = [git_path, "config", "--includes"]
    if params['list_all']:
        args.append('-l')
    if scope:
        args.append("--" + scope)
    if name:
        args.append(name)

    if scope == 'local':
        dir = params['repo']
    elif params['list_all'] and params['repo']:
        # Include local settings from a specific repo when listing all available settings
        dir = params['repo']
    else:
        # Run from root directory to avoid accidentally picking up any local config settings
        dir = "/"

    (rc, out, err) = module.run_command(' '.join(args), cwd=dir)
    if params[
            'list_all'] and scope and rc == 128 and 'unable to read config file' in err:
        # This just means nothing has been set at the given scope
        module.exit_json(changed=False, msg='', config_values={})
    elif rc >= 2:
        # If the return code is 1, it just means the option hasn't been set yet, which is fine.
        module.fail_json(rc=rc, msg=err, cmd=' '.join(args))

    if params['list_all']:
        values = out.rstrip().splitlines()
        config_values = {}
        for value in values:
            k, v = value.split('=', 1)
            config_values[k] = v
        module.exit_json(changed=False, msg='', config_values=config_values)
    elif not new_value and not unset:
        module.exit_json(changed=False, msg='', config_value=out.rstrip())
    elif unset and not out:
        module.exit_json(changed=False, msg='no setting to unset')
    else:
        old_value = out.rstrip()
        if old_value == new_value:
            module.exit_json(changed=False, msg="")

    if not module.check_mode:
        if unset:
            args.insert(len(args) - 1, "--" + unset)
            cmd = ' '.join(args)
        else:
            new_value_quoted = shlex_quote(new_value)
            cmd = ' '.join(args + [new_value_quoted])
        (rc, out, err) = module.run_command(cmd, cwd=dir)
        if err:
            module.fail_json(rc=rc, msg=err, cmd=cmd)

    module.exit_json(msg='setting changed',
                     diff=dict(before_header=' '.join(args),
                               before=old_value + "\n",
                               after_header=' '.join(args),
                               after=(new_value or '') + "\n"),
                     changed=True)
Ejemplo n.º 12
0
class ElementSWClusterPair(object):
    """ class to handle cluster pairing operations """
    def __init__(self):
        """
            Setup Ansible parameters and ElementSW connection
        """
        self.argument_spec = netapp_utils.ontap_sf_host_argument_spec()
        self.argument_spec.update(
            dict(state=dict(required=False,
                            choices=['present', 'absent'],
                            default='present'),
                 dest_mvip=dict(required=True, type='str'),
                 dest_username=dict(required=False, type='str'),
                 dest_password=dict(required=False, type='str', no_log=True)))

        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    supports_check_mode=True)

        if HAS_SF_SDK is False:
            self.module.fail_json(
                msg="Unable to import the SolidFire Python SDK")
        else:
            self.elem = netapp_utils.create_sf_connection(module=self.module)

        self.elementsw_helper = NaElementSWModule(self.elem)
        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        # get element_sw_connection for destination cluster
        # overwrite existing source host, user and password with destination credentials
        self.module.params['hostname'] = self.parameters['dest_mvip']
        # username and password is same as source,
        # if dest_username and dest_password aren't specified
        if self.parameters.get('dest_username'):
            self.module.params['username'] = self.parameters['dest_username']
        if self.parameters.get('dest_password'):
            self.module.params['password'] = self.parameters['dest_password']
        self.dest_elem = netapp_utils.create_sf_connection(module=self.module)
        self.dest_elementsw_helper = NaElementSWModule(self.dest_elem)

    def check_if_already_paired(self, paired_clusters, hostname):
        for pair in paired_clusters.cluster_pairs:
            if pair.mvip == hostname:
                return pair.cluster_pair_id
        return None

    def get_src_pair_id(self):
        """
            Check for idempotency
        """
        # src cluster and dest cluster exist
        paired_clusters = self.elem.list_cluster_pairs()
        return self.check_if_already_paired(paired_clusters,
                                            self.parameters['dest_mvip'])

    def get_dest_pair_id(self):
        """
        Getting destination cluster_pair_id
        """
        paired_clusters = self.dest_elem.list_cluster_pairs()
        return self.check_if_already_paired(paired_clusters,
                                            self.parameters['hostname'])

    def pair_clusters(self):
        """
            Start cluster pairing on source, and complete on target cluster
        """
        try:
            pair_key = self.elem.start_cluster_pairing()
            self.dest_elem.complete_cluster_pairing(
                cluster_pairing_key=pair_key.cluster_pairing_key)
        except solidfire.common.ApiServerError as err:
            self.module.fail_json(
                msg="Error pairing cluster %s and %s" %
                (self.parameters['hostname'], self.parameters['dest_mvip']),
                exception=to_native(err))

    def unpair_clusters(self, pair_id_source, pair_id_dest):
        """
            Delete cluster pair
        """
        try:
            self.elem.remove_cluster_pair(cluster_pair_id=pair_id_source)
            self.dest_elem.remove_cluster_pair(cluster_pair_id=pair_id_dest)
        except solidfire.common.ApiServerError as err:
            self.module.fail_json(
                msg="Error unpairing cluster %s and %s" %
                (self.parameters['hostname'], self.parameters['dest_mvip']),
                exception=to_native(err))

    def apply(self):
        """
            Call create / delete cluster pair methods
        """
        pair_id_source = self.get_src_pair_id()
        # If already paired, find the cluster_pair_id of destination cluster
        if pair_id_source:
            pair_id_dest = self.get_dest_pair_id()
        # calling helper to determine action
        cd_action = self.na_helper.get_cd_action(pair_id_source,
                                                 self.parameters)
        if cd_action == "create":
            self.pair_clusters()
        elif cd_action == "delete":
            self.unpair_clusters(pair_id_source, pair_id_dest)
        self.module.exit_json(changed=self.na_helper.changed)
Ejemplo n.º 13
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(type='str', required=True),
            state=dict(type='str',
                       choices=[
                           'killed', 'once', 'reloaded', 'restarted',
                           'started', 'stopped'
                       ]),
            enabled=dict(type='bool'),
            downed=dict(type='bool'),
            service_dir=dict(type='str', default='/service'),
            service_src=dict(type='str', default='/etc/service'),
        ),
        supports_check_mode=True,
    )

    module.run_command_environ_update = dict(LANG='C',
                                             LC_ALL='C',
                                             LC_MESSAGES='C',
                                             LC_CTYPE='C')

    state = module.params['state']
    enabled = module.params['enabled']
    downed = module.params['downed']

    svc = Svc(module)
    changed = False
    orig_state = svc.report()

    if enabled is not None and enabled != svc.enabled:
        changed = True
        if not module.check_mode:
            try:
                if enabled:
                    svc.enable()
                else:
                    svc.disable()
            except (OSError, IOError) as e:
                module.fail_json(msg="Could not change service link: %s" %
                                 to_native(e))

    if state is not None and state != svc.state:
        changed = True
        if not module.check_mode:
            getattr(svc, state[:-2])()

    if downed is not None and downed != svc.downed:
        changed = True
        if not module.check_mode:
            d_file = "%s/down" % svc.svc_full
            try:
                if downed:
                    open(d_file, "a").close()
                else:
                    os.unlink(d_file)
            except (OSError, IOError) as e:
                module.fail_json(msg="Could not change downed file: %s " %
                                 (to_native(e)))

    module.exit_json(changed=changed, svc=svc.report())
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "state": {
            "required": False,
            "type": "str",
            "choices": ["present", "absent"]
        },
        "vpn_ipsec_manualkey": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "state": {
                    "required": False,
                    "type": "str",
                    "choices": ["present", "absent"]
                },
                "authentication": {
                    "required":
                    False,
                    "type":
                    "str",
                    "choices":
                    ["null", "md5", "sha1", "sha256", "sha384", "sha512"]
                },
                "authkey": {
                    "required": False,
                    "type": "str"
                },
                "enckey": {
                    "required": False,
                    "type": "str"
                },
                "encryption": {
                    "required": False,
                    "type": "str",
                    "choices": ["null", "des"]
                },
                "interface": {
                    "required": False,
                    "type": "str"
                },
                "local_gw": {
                    "required": False,
                    "type": "str"
                },
                "localspi": {
                    "required": False,
                    "type": "str"
                },
                "name": {
                    "required": True,
                    "type": "str"
                },
                "remote_gw": {
                    "required": False,
                    "type": "str"
                },
                "remotespi": {
                    "required": False,
                    "type": "str"
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_vpn_ipsec(
                module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_vpn_ipsec(module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "system_ha": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "arps": {
                    "required": False,
                    "type": "int"
                },
                "arps_interval": {
                    "required": False,
                    "type": "int"
                },
                "authentication": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "cpu_threshold": {
                    "required": False,
                    "type": "str"
                },
                "encryption": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "ftp_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "gratuitous_arps": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "group_id": {
                    "required": False,
                    "type": "int"
                },
                "group_name": {
                    "required": False,
                    "type": "str"
                },
                "ha_direct": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "ha_eth_type": {
                    "required": False,
                    "type": "str"
                },
                "ha_mgmt_interfaces": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "dst": {
                            "required": False,
                            "type": "str"
                        },
                        "gateway": {
                            "required": False,
                            "type": "str"
                        },
                        "gateway6": {
                            "required": False,
                            "type": "str"
                        },
                        "id": {
                            "required": True,
                            "type": "int"
                        },
                        "interface": {
                            "required": False,
                            "type": "str"
                        }
                    }
                },
                "ha_mgmt_status": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "ha_uptime_diff_margin": {
                    "required": False,
                    "type": "int"
                },
                "hb_interval": {
                    "required": False,
                    "type": "int"
                },
                "hb_lost_threshold": {
                    "required": False,
                    "type": "int"
                },
                "hbdev": {
                    "required": False,
                    "type": "str"
                },
                "hc_eth_type": {
                    "required": False,
                    "type": "str"
                },
                "hello_holddown": {
                    "required": False,
                    "type": "int"
                },
                "http_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "imap_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "inter_cluster_session_sync": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "key": {
                    "required": False,
                    "type": "str"
                },
                "l2ep_eth_type": {
                    "required": False,
                    "type": "str"
                },
                "link_failed_signal": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "load_balance_all": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "memory_compatible_mode": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "memory_threshold": {
                    "required": False,
                    "type": "str"
                },
                "mode": {
                    "required": False,
                    "type": "str",
                    "choices": ["standalone", "a-a", "a-p"]
                },
                "monitor": {
                    "required": False,
                    "type": "str"
                },
                "multicast_ttl": {
                    "required": False,
                    "type": "int"
                },
                "nntp_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "override": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "override_wait_time": {
                    "required": False,
                    "type": "int"
                },
                "password": {
                    "required": False,
                    "type": "str"
                },
                "pingserver_failover_threshold": {
                    "required": False,
                    "type": "int"
                },
                "pingserver_flip_timeout": {
                    "required": False,
                    "type": "int"
                },
                "pingserver_monitor_interface": {
                    "required": False,
                    "type": "str"
                },
                "pingserver_slave_force_reset": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "pop3_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "priority": {
                    "required": False,
                    "type": "int"
                },
                "route_hold": {
                    "required": False,
                    "type": "int"
                },
                "route_ttl": {
                    "required": False,
                    "type": "int"
                },
                "route_wait": {
                    "required": False,
                    "type": "int"
                },
                "schedule": {
                    "required":
                    False,
                    "type":
                    "str",
                    "choices": [
                        "none", "hub", "leastconnection", "round-robin",
                        "weight-round-robin", "random", "ip", "ipport"
                    ]
                },
                "secondary_vcluster": {
                    "required": False,
                    "type": "dict",
                    "options": {
                        "monitor": {
                            "required": False,
                            "type": "str"
                        },
                        "override": {
                            "required": False,
                            "type": "str",
                            "choices": ["enable", "disable"]
                        },
                        "override_wait_time": {
                            "required": False,
                            "type": "int"
                        },
                        "pingserver_failover_threshold": {
                            "required": False,
                            "type": "int"
                        },
                        "pingserver_monitor_interface": {
                            "required": False,
                            "type": "str"
                        },
                        "pingserver_slave_force_reset": {
                            "required": False,
                            "type": "str",
                            "choices": ["enable", "disable"]
                        },
                        "priority": {
                            "required": False,
                            "type": "int"
                        },
                        "vcluster_id": {
                            "required": False,
                            "type": "int"
                        },
                        "vdom": {
                            "required": False,
                            "type": "str"
                        }
                    }
                },
                "session_pickup": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "session_pickup_connectionless": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "session_pickup_delay": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "session_pickup_expectation": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "session_pickup_nat": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "session_sync_dev": {
                    "required": False,
                    "type": "str"
                },
                "smtp_proxy_threshold": {
                    "required": False,
                    "type": "str"
                },
                "standalone_config_sync": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "standalone_mgmt_vdom": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "sync_config": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "sync_packet_balance": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "unicast_hb": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "unicast_hb_netmask": {
                    "required": False,
                    "type": "str"
                },
                "unicast_hb_peerip": {
                    "required": False,
                    "type": "str"
                },
                "uninterruptible_upgrade": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "vcluster_id": {
                    "required": False,
                    "type": "int"
                },
                "vcluster2": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "vdom": {
                    "required": False,
                    "type": "str"
                },
                "weight": {
                    "required": False,
                    "type": "str"
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_system(module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_system(module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
Ejemplo n.º 16
0
class NetAppontapExportRule(object):
    ''' object initialize and class methods '''
    def __init__(self):

        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type='str',
                           choices=['present', 'absent'],
                           default='present'),
                name=dict(required=True, type='str', aliases=['policy_name']),
                protocol=dict(required=False,
                              type='list',
                              default=None,
                              choices=[
                                  'any', 'nfs', 'nfs3', 'nfs4', 'cifs',
                                  'flexcache'
                              ]),
                client_match=dict(required=False, type='list'),
                ro_rule=dict(required=False,
                             type='list',
                             default=None,
                             choices=[
                                 'any', 'none', 'never', 'krb5', 'krb5i',
                                 'krb5p', 'ntlm', 'sys'
                             ]),
                rw_rule=dict(required=False,
                             type='list',
                             default=None,
                             choices=[
                                 'any', 'none', 'never', 'krb5', 'krb5i',
                                 'krb5p', 'ntlm', 'sys'
                             ]),
                super_user_security=dict(required=False,
                                         type='list',
                                         default=None,
                                         choices=[
                                             'any', 'none', 'never', 'krb5',
                                             'krb5i', 'krb5p', 'ntlm', 'sys'
                                         ]),
                allow_suid=dict(required=False, type='bool'),
                rule_index=dict(required=False, type='int'),
                vserver=dict(required=True, type='str'),
            ))

        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    supports_check_mode=True)

        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        self.set_playbook_zapi_key_map()

        if HAS_NETAPP_LIB is False:
            self.module.fail_json(
                msg="the python NetApp-Lib module is required")
        else:
            self.server = netapp_utils.setup_na_ontap_zapi(
                module=self.module, vserver=self.parameters['vserver'])

    def set_playbook_zapi_key_map(self):
        self.na_helper.zapi_string_keys = {
            'client_match': 'client-match',
            'name': 'policy-name'
        }
        self.na_helper.zapi_list_keys = {
            'protocol': ('protocol', 'access-protocol'),
            'ro_rule': ('ro-rule', 'security-flavor'),
            'rw_rule': ('rw-rule', 'security-flavor'),
            'super_user_security': ('super-user-security', 'security-flavor'),
        }
        self.na_helper.zapi_bool_keys = {
            'allow_suid': 'is-allow-set-uid-enabled'
        }
        self.na_helper.zapi_int_keys = {'rule_index': 'rule-index'}

    def set_query_parameters(self):
        """
        Return dictionary of query parameters and
        :return:
        """
        query = {
            'policy-name': self.parameters['name'],
            'vserver': self.parameters['vserver']
        }

        if self.parameters.get('rule_index'):
            query['rule-index'] = self.parameters['rule_index']
        elif self.parameters.get('client_match'):
            query['client-match'] = self.parameters['client_match']
        else:
            self.module.fail_json(
                msg=
                "Need to specify at least one of the rule_index and client_match option."
            )

        attributes = {'query': {'export-rule-info': query}}
        return attributes

    def get_export_policy_rule(self):
        """
        Return details about the export policy rule
        :param:
            name : Name of the export_policy
        :return: Details about the export_policy. None if not found.
        :rtype: dict
        """
        current, result = None, None
        rule_iter = netapp_utils.zapi.NaElement('export-rule-get-iter')
        rule_iter.translate_struct(self.set_query_parameters())
        try:
            result = self.server.invoke_successfully(rule_iter, True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(
                msg='Error getting export policy rule %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())
        if result is not None and \
                result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1:
            current = dict()
            rule_info = result.get_child_by_name(
                'attributes-list').get_child_by_name('export-rule-info')
            for item_key, zapi_key in self.na_helper.zapi_string_keys.items():
                current[item_key] = rule_info.get_child_content(zapi_key)
            for item_key, zapi_key in self.na_helper.zapi_bool_keys.items():
                current[item_key] = self.na_helper.get_value_for_bool(
                    from_zapi=True, value=rule_info[zapi_key])
            for item_key, zapi_key in self.na_helper.zapi_int_keys.items():
                current[item_key] = self.na_helper.get_value_for_int(
                    from_zapi=True, value=rule_info[zapi_key])
            for item_key, zapi_key in self.na_helper.zapi_list_keys.items():
                parent, dummy = zapi_key
                current[item_key] = self.na_helper.get_value_for_list(
                    from_zapi=True,
                    zapi_parent=rule_info.get_child_by_name(parent))
            current['num_records'] = int(
                result.get_child_content('num-records'))
            if not self.parameters.get('rule_index'):
                self.parameters['rule_index'] = current['rule_index']
        return current

    def get_export_policy(self):
        """
        Return details about the export-policy
        :param:
            name : Name of the export-policy

        :return: Details about the export-policy. None if not found.
        :rtype: dict
        """
        export_policy_iter = netapp_utils.zapi.NaElement(
            'export-policy-get-iter')
        attributes = {
            'query': {
                'export-policy-info': {
                    'policy-name': self.parameters['name'],
                    'vserver': self.parameters['vserver']
                }
            }
        }

        export_policy_iter.translate_struct(attributes)
        try:
            result = self.server.invoke_successfully(export_policy_iter, True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error getting export policy %s: %s' %
                                  (self.parameters['name'], to_native(error)),
                                  exception=traceback.format_exc())

        if result.get_child_by_name('num-records') and int(
                result.get_child_content('num-records')) == 1:
            return result

        return None

    def add_parameters_for_create_or_modify(self, na_element_object, values):
        """
            Add children node for create or modify NaElement object
            :param na_element_object: modify or create NaElement object
            :param values: dictionary of cron values to be added
            :return: None
        """
        for key in values:
            if key in self.na_helper.zapi_string_keys:
                zapi_key = self.na_helper.zapi_string_keys.get(key)
                na_element_object[zapi_key] = values[key]
            elif key in self.na_helper.zapi_list_keys:
                parent_key, child_key = self.na_helper.zapi_list_keys.get(key)
                na_element_object.add_child_elem(
                    self.na_helper.get_value_for_list(from_zapi=False,
                                                      zapi_parent=parent_key,
                                                      zapi_child=child_key,
                                                      data=values[key]))
            elif key in self.na_helper.zapi_int_keys:
                zapi_key = self.na_helper.zapi_int_keys.get(key)
                na_element_object[zapi_key] = self.na_helper.get_value_for_int(
                    from_zapi=False, value=values[key])
            elif key in self.na_helper.zapi_bool_keys:
                zapi_key = self.na_helper.zapi_bool_keys.get(key)
                na_element_object[
                    zapi_key] = self.na_helper.get_value_for_bool(
                        from_zapi=False, value=values[key])

    def create_export_policy_rule(self):
        """
        create rule for the export policy.
        """
        for key in ['client_match', 'ro_rule', 'rw_rule']:
            if self.parameters.get(key) is None:
                self.module.fail_json(
                    msg=
                    'Error: Missing required param for creating export policy rule %s'
                    % key)
        export_rule_create = netapp_utils.zapi.NaElement('export-rule-create')
        self.add_parameters_for_create_or_modify(export_rule_create,
                                                 self.parameters)
        try:
            self.server.invoke_successfully(export_rule_create,
                                            enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(
                msg='Error creating export policy rule %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def create_export_policy(self):
        """
        Creates an export policy
        """
        export_policy_create = netapp_utils.zapi.NaElement.create_node_with_children(
            'export-policy-create', **{'policy-name': self.parameters['name']})
        try:
            self.server.invoke_successfully(export_policy_create,
                                            enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error creating export-policy %s: %s' %
                                  (self.parameters['name'], to_native(error)),
                                  exception=traceback.format_exc())

    def delete_export_policy_rule(self, rule_index):
        """
        delete rule for the export policy.
        """
        export_rule_delete = netapp_utils.zapi.NaElement.create_node_with_children(
            'export-rule-destroy', **{
                'policy-name': self.parameters['name'],
                'rule-index': str(rule_index)
            })

        try:
            self.server.invoke_successfully(export_rule_delete,
                                            enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(
                msg='Error deleting export policy rule %s: %s' %
                (self.parameters['name'], to_native(error)),
                exception=traceback.format_exc())

    def modify_export_policy_rule(self, params):
        '''
        Modify an existing export policy rule
        :param params: dict() of attributes with desired values
        :return: None
        '''
        export_rule_modify = netapp_utils.zapi.NaElement.create_node_with_children(
            'export-rule-modify', **{
                'policy-name': self.parameters['name'],
                'rule-index': str(self.parameters['rule_index'])
            })
        self.add_parameters_for_create_or_modify(export_rule_modify, params)
        try:
            self.server.invoke_successfully(export_rule_modify,
                                            enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(
                msg='Error modifying allow_suid %s: %s' %
                (self.parameters['allow_suid'], to_native(error)),
                exception=traceback.format_exc())

    def autosupport_log(self):
        netapp_utils.ems_log_event("na_ontap_export_policy_rules", self.server)

    def apply(self):
        ''' Apply required action from the play'''
        self.autosupport_log()
        # convert client_match list to comma-separated string
        if self.parameters.get('client_match') is not None:
            self.parameters['client_match'] = ','.join(
                self.parameters['client_match'])
            self.parameters['client_match'] = self.parameters[
                'client_match'].replace(' ', '')

        current, modify = self.get_export_policy_rule(), None
        action = self.na_helper.get_cd_action(current, self.parameters)
        if action is None and self.parameters['state'] == 'present':
            modify = self.na_helper.get_modified_attributes(
                current, self.parameters)

        if self.na_helper.changed:
            if self.module.check_mode:
                pass
            else:
                # create export policy (if policy doesn't exist) only when changed=True
                if not self.get_export_policy():
                    self.create_export_policy()
                if action == 'create':
                    self.create_export_policy_rule()
                elif action == 'delete':
                    if current['num_records'] > 1:
                        self.module.fail_json(
                            msg='Multiple export policy rules exist.'
                            'Please specify a rule_index to delete')
                    self.delete_export_policy_rule(current['rule_index'])
                elif modify:
                    self.modify_export_policy_rule(modify)
        self.module.exit_json(changed=self.na_helper.changed)
def main():
    argument_spec = dict(
        adom=dict(required=False, type="str", default="root"),
        device_unique_name=dict(required=True, type="str"),
        device_hostname=dict(required=False, type="str"),
        interface=dict(required=False, type="str"),
        interface_ip=dict(required=False, type="str"),
        interface_allow_access=dict(required=False, type="str"),
        install_config=dict(required=False, type="str", default="disable"),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False,
    )
    paramgram = {
        "device_unique_name": module.params["device_unique_name"],
        "device_hostname": module.params["device_hostname"],
        "interface": module.params["interface"],
        "interface_ip": module.params["interface_ip"],
        "interface_allow_access": module.params["interface_allow_access"],
        "install_config": module.params["install_config"],
        "adom": module.params["adom"]
    }
    module.paramgram = paramgram
    fmgr = None
    if module._socket_path:
        connection = Connection(module._socket_path)
        fmgr = FortiManagerHandler(connection, module)
        fmgr.tools = FMGRCommon()
    else:
        module.fail_json(**FAIL_SOCKET_MSG)

    # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
    results = DEFAULT_RESULT_OBJ
    try:
        if paramgram["device_hostname"] is not None:
            results = update_device_hostname(fmgr, paramgram)
            fmgr.govern_response(module=module,
                                 results=results,
                                 ansible_facts=fmgr.construct_ansible_facts(
                                     results, module.params, paramgram))

        if paramgram["interface_ip"] is not None or paramgram[
                "interface_allow_access"] is not None:
            results = update_device_interface(fmgr, paramgram)
            fmgr.govern_response(module=module,
                                 results=results,
                                 ansible_facts=fmgr.construct_ansible_facts(
                                     results, module.params, paramgram))

        if paramgram["install_config"] == "enable":
            results = exec_config(fmgr, paramgram)
            fmgr.govern_response(module=module,
                                 results=results,
                                 ansible_facts=fmgr.construct_ansible_facts(
                                     results, module.params, paramgram))

    except Exception as err:
        raise FMGBaseException(err)

    return module.exit_json(**results[1])
Ejemplo n.º 18
0
def main():
    """ This section is for arguments parsing """
    module = AnsibleModule(
        argument_spec=dict(
            pn_cliusername=dict(required=False, type='str'),
            pn_clipassword=dict(required=False, type='str', no_log=True),
            pn_cliswitch=dict(required=False, type='str', default='local'),
            state=dict(type='str', default='present', choices=['present',
                                                               'absent']),
            pn_vrouter_name=dict(required=True, type='str'),
            pn_network_ip=dict(required=True, type='str'),
            pn_ospf_area=dict(type='str')
        ),
        required_if=(
            ['state', 'present',
             ['pn_network_ip', 'pn_ospf_area']],
            ['state', 'absent', ['pn_network_ip']]
        )
    )

    # Accessing the arguments
    state = module.params['state']
    vrouter_name = module.params['pn_vrouter_name']
    network_ip = module.params['pn_network_ip']
    ospf_area = module.params['pn_ospf_area']

    command = get_command_from_state(state)

    # Building the CLI command string
    cli = pn_cli(module)
    check_cli(module, cli)

    if state == 'present':
        if VROUTER_EXISTS is False:
            module.exit_json(
                skipped=True,
                msg='vRouter %s does not exist' % vrouter_name
            )
        if NETWORK_EXISTS is True:
            module.exit_json(
                skipped=True,
                msg=('OSPF with network ip %s already exists on %s'
                     % (network_ip, vrouter_name))
            )
        cli += (' %s vrouter-name %s network %s ospf-area %s'
                % (command, vrouter_name, network_ip, ospf_area))

    if state == 'absent':
        if VROUTER_EXISTS is False:
            module.exit_json(
                skipped=True,
                msg='vRouter %s does not exist' % vrouter_name
            )
        if NETWORK_EXISTS is False:
            module.exit_json(
                skipped=True,
                msg=('OSPF with network ip %s already exists on %s'
                     % (network_ip, vrouter_name))
            )
        cli += (' %s vrouter-name %s network %s'
                % (command, vrouter_name, network_ip))

    run_cli(module, cli)
def main():
    argument_spec = dict(
        ip_address=dict(required=True, type='str'),
        password=dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True),
        username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME']), default="admin"),
        interval=dict(default=0.5),
        timeout=dict(),
        sync=dict(type='bool', default=True),
        description=dict(type='str'),
        commit_changes_by=dict(type='list'),
        commit_vsys=dict(type='list')
    )
    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)

    if not HAS_LIB:
        module.fail_json(msg='pan-python is required for this module')

    ip_address = module.params["ip_address"]
    if not ip_address:
        module.fail_json(msg="ip_address should be specified")

    password = module.params["password"]
    if not password:
        module.fail_json(msg="password is required")

    username = module.params['username']
    if not username:
        module.fail_json(msg="username is required")

    interval = module.params['interval']
    timeout = module.params['timeout']
    sync = module.params['sync']

    xapi = pan.xapi.PanXapi(
        hostname=ip_address,
        api_username=username,
        api_password=password
    )

    cmd = "<commit>"

    description = module.params["description"]
    if description:
        cmd += "<description>" + description + "</description>"

    commit_changes_by = module.params["commit_changes_by"]
    commit_vsys = module.params["commit_vsys"]

    if commit_changes_by or commit_vsys:

        cmd += "<partial>"

        if commit_changes_by:
            cmd += "<admin>"
            for admin in commit_changes_by:
                cmd += "<member>" + admin + "</member>"
            cmd += "</admin>"

        if commit_vsys:
            cmd += "<vsys>"
            for vsys in commit_vsys:
                cmd += "<member>" + vsys + "</member>"
            cmd += "</vsys>"

        cmd += "</partial><force></force>"

    cmd += "</commit>"

    xapi.commit(
        cmd=cmd,
        sync=sync,
        interval=interval,
        timeout=timeout
    )

    try:
        result = xapi.xml_root().encode('utf-8')
        root = etree.fromstring(result)
        job_id = root.find('./result/job/id').text
    except AttributeError:
        job_id = None

    panos_commit_details = dict(
        status_text=xapi.status,
        status_code=xapi.status_code,
        status_detail=xapi.status_detail,
        job_id=job_id
    )

    if "Commit failed" in xapi.status_detail:
        module.fail_json(msg=xapi.status_detail, panos_commit=panos_commit_details)

    if job_id:
        module.exit_json(changed=True, msg="Commit successful.", panos_commit=panos_commit_details)
    else:
        module.exit_json(changed=False, msg="No changes to commit.", panos_commit=panos_commit_details)
class NetAppONTAPFlexCache(object):
    """
    Class with FlexCache methods
    """
    def __init__(self):

        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
        self.argument_spec.update(
            dict(
                state=dict(required=False,
                           type='str',
                           choices=['present', 'absent'],
                           default='present'),
                origin_volume=dict(required=False, type='str'),
                origin_vserver=dict(required=False, type='str'),
                origin_cluster=dict(required=False, type='str'),
                auto_provision_as=dict(required=False, type='str'),
                volume=dict(required=True, type='str'),
                junction_path=dict(required=False, type='str'),
                size=dict(required=False, type='int'),
                size_unit=dict(default='gb',
                               choices=[
                                   'bytes', 'b', 'kb', 'mb', 'gb', 'tb', 'pb',
                                   'eb', 'zb', 'yb'
                               ],
                               type='str'),
                vserver=dict(required=True, type='str'),
                aggr_list=dict(required=False, type='list'),
                aggr_list_multiplier=dict(required=False, type='int'),
                force_offline=dict(required=False, type='bool', default=False),
                force_unmount=dict(required=False, type='bool', default=False),
                time_out=dict(required=False, type='int', default=180),
            ))

        self.module = AnsibleModule(argument_spec=self.argument_spec,
                                    mutually_exclusive=[
                                        ('aggr_list', 'auto_provision_as'),
                                    ],
                                    supports_check_mode=True)

        self.na_helper = NetAppModule()
        self.parameters = self.na_helper.set_parameters(self.module.params)
        if self.parameters.get('size'):
            self.parameters['size'] = self.parameters['size'] * \
                netapp_utils.POW2_BYTE_MAP[self.parameters['size_unit']]
        # setup later if required
        self.origin_server = None
        if HAS_NETAPP_LIB is False:
            self.module.fail_json(
                msg="the python NetApp-Lib module is required")
        else:
            self.server = netapp_utils.setup_na_ontap_zapi(
                module=self.module, vserver=self.parameters['vserver'])

    def add_parameter_to_dict(self, adict, name, key=None, tostr=False):
        ''' add defined parameter (not None) to adict using key '''
        if key is None:
            key = name
        if self.parameters.get(name) is not None:
            if tostr:
                adict[key] = str(self.parameters.get(name))
            else:
                adict[key] = self.parameters.get(name)

    def get_job(self, jobid, server):
        """
        Get job details by id
        """
        job_get = netapp_utils.zapi.NaElement('job-get')
        job_get.add_new_child('job-id', jobid)
        try:
            result = server.invoke_successfully(job_get, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            if to_native(error.code) == "15661":
                # Not found
                return None
            self.module.fail_json(msg='Error fetching job info: %s' %
                                  to_native(error),
                                  exception=traceback.format_exc())
        results = dict()
        job_info = result.get_child_by_name('attributes').get_child_by_name(
            'job-info')
        results = {
            'job-progress': job_info['job-progress'],
            'job-state': job_info['job-state']
        }
        if job_info.get_child_by_name('job-completion') is not None:
            results['job-completion'] = job_info['job-completion']
        else:
            results['job-completion'] = None
        return results

    def check_job_status(self, jobid):
        """
        Loop until job is complete
        """
        server = self.server
        sleep_time = 5
        time_out = self.parameters['time_out']
        while time_out > 0:
            results = self.get_job(jobid, server)
            # If running as cluster admin, the job is owned by cluster vserver
            # rather than the target vserver.
            if results is None and server == self.server:
                results = netapp_utils.get_cserver(self.server)
                server = netapp_utils.setup_na_ontap_zapi(module=self.module,
                                                          vserver=results)
                continue
            if results is None:
                error = 'cannot locate job with id: %d' % jobid
                break
            if results['job-state'] in ('queued', 'running'):
                time.sleep(sleep_time)
                time_out -= sleep_time
                continue
            if results['job-state'] in ('success', 'failure'):
                break
            else:
                self.module.fail_json(msg='Unexpected job status in: %s' %
                                      repr(results))

        if results is not None:
            if results['job-state'] == 'success':
                error = None
            elif results['job-state'] in ('queued', 'running'):
                error = 'job completion exceeded expected timer of: %s seconds' % \
                        self.parameters['time_out']
            else:
                if results['job-completion'] is not None:
                    error = results['job-completion']
                else:
                    error = results['job-progress']
        return error

    def flexcache_get_iter(self):
        """
        Compose NaElement object to query current FlexCache relation
        """
        options = {'volume': self.parameters['volume']}
        self.add_parameter_to_dict(options, 'origin_volume', 'origin-volume')
        self.add_parameter_to_dict(options, 'origin_vserver', 'origin-vserver')
        self.add_parameter_to_dict(options, 'origin_cluster', 'origin-cluster')
        flexcache_info = netapp_utils.zapi.NaElement.create_node_with_children(
            'flexcache-info', **options)
        query = netapp_utils.zapi.NaElement('query')
        query.add_child_elem(flexcache_info)
        flexcache_get_iter = netapp_utils.zapi.NaElement('flexcache-get-iter')
        flexcache_get_iter.add_child_elem(query)
        return flexcache_get_iter

    def flexcache_get(self):
        """
        Get current FlexCache relations
        :return: Dictionary of current FlexCache details if query successful, else None
        """
        flexcache_get_iter = self.flexcache_get_iter()
        flex_info = dict()
        try:
            result = self.server.invoke_successfully(flexcache_get_iter,
                                                     enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error fetching FlexCache info: %s' %
                                  to_native(error),
                                  exception=traceback.format_exc())
        if result.get_child_by_name('num-records') and \
                int(result.get_child_content('num-records')) == 1:
            flexcache_info = result.get_child_by_name('attributes-list') \
                                   .get_child_by_name('flexcache-info')
            flex_info['origin_cluster'] = flexcache_info.get_child_content(
                'origin-cluster')
            flex_info['origin_volume'] = flexcache_info.get_child_content(
                'origin-volume')
            flex_info['origin_vserver'] = flexcache_info.get_child_content(
                'origin-vserver')
            flex_info['size'] = flexcache_info.get_child_content('size')
            flex_info['volume'] = flexcache_info.get_child_content('volume')
            flex_info['vserver'] = flexcache_info.get_child_content('vserver')
            flex_info['auto_provision_as'] = flexcache_info.get_child_content(
                'auto-provision-as')

            return flex_info
        if result.get_child_by_name('num-records') and \
                int(result.get_child_content('num-records')) > 1:
            msg = 'Multiple records found for %s:' % self.parameters['volume']
            self.module.fail_json(msg='Error fetching FlexCache info: %s' %
                                  msg)
        return None

    def flexcache_create_async(self):
        """
        Create a FlexCache relationship
        """
        options = {
            'origin-volume': self.parameters['origin_volume'],
            'origin-vserver': self.parameters['origin_vserver'],
            'volume': self.parameters['volume']
        }
        self.add_parameter_to_dict(options, 'junction_path', 'junction-path')
        self.add_parameter_to_dict(options, 'auto_provision_as',
                                   'auto-provision-as')
        self.add_parameter_to_dict(options, 'size', 'size', tostr=True)
        if self.parameters.get('aggr_list'):
            if self.parameters.get('aggr_list_multiplier'):
                self.tobytes_aggr_list_multiplier = bytes(
                    self.parameters['aggr_list_multiplier'])
                self.add_parameter_to_dict(options,
                                           'tobytes_aggr_list_multiplier',
                                           'aggr-list-multiplier')
        flexcache_create = netapp_utils.zapi.NaElement.create_node_with_children(
            'flexcache-create-async', **options)
        if self.parameters.get('aggr_list'):
            aggregates = netapp_utils.zapi.NaElement('aggr-list')
            for aggregate in self.parameters['aggr_list']:
                aggregates.add_new_child('aggr-name', aggregate)
            flexcache_create.add_child_elem(aggregates)
        try:
            result = self.server.invoke_successfully(flexcache_create,
                                                     enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error creating FlexCache %s' %
                                  to_native(error),
                                  exception=traceback.format_exc())
        results = dict()
        for key in ('result-status', 'result-jobid'):
            if result.get_child_by_name(key):
                results[key] = result[key]
        return results

    def flexcache_create(self):
        """
        Create a FlexCache relationship
        Check job status
        """
        results = self.flexcache_create_async()
        status = results.get('result-status')
        if status == 'in_progress' and 'result-jobid' in results:
            if self.parameters['time_out'] == 0:
                # asynchronous call, assuming success!
                return
            error = self.check_job_status(results['result-jobid'])
            if error is None:
                return
            else:
                self.module.fail_json(msg='Error when creating flexcache: %s' %
                                      error)
        self.module.fail_json(
            msg='Unexpected error when creating flexcache: results is: %s' %
            repr(results))

    def flexcache_delete_async(self):
        """
        Delete FlexCache relationship at destination cluster
        """
        options = {'volume': self.parameters['volume']}
        flexcache_delete = netapp_utils.zapi.NaElement.create_node_with_children(
            'flexcache-destroy-async', **options)
        try:
            result = self.server.invoke_successfully(flexcache_delete,
                                                     enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error deleting FlexCache : %s' %
                                  (to_native(error)),
                                  exception=traceback.format_exc())
        results = dict()
        for key in ('result-status', 'result-jobid'):
            if result.get_child_by_name(key):
                results[key] = result[key]
        return results

    def volume_offline(self):
        """
        Offline FlexCache volume at destination cluster
        """
        options = {'name': self.parameters['volume']}
        xml = netapp_utils.zapi.NaElement.create_node_with_children(
            'volume-offline', **options)
        try:
            self.server.invoke_successfully(xml, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error offlining FlexCache volume: %s' %
                                  (to_native(error)),
                                  exception=traceback.format_exc())

    def volume_unmount(self):
        """
        Unmount FlexCache volume at destination cluster
        """
        options = {'volume-name': self.parameters['volume']}
        xml = netapp_utils.zapi.NaElement.create_node_with_children(
            'volume-unmount', **options)
        try:
            self.server.invoke_successfully(xml, enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error unmounting FlexCache volume: %s' %
                                  (to_native(error)),
                                  exception=traceback.format_exc())

    def flexcache_delete_async(self):
        """
        Delete FlexCache relationship at destination cluster
        """
        options = {'volume': self.parameters['volume']}
        flexcache_delete = netapp_utils.zapi.NaElement.create_node_with_children(
            'flexcache-destroy-async', **options)
        try:
            result = self.server.invoke_successfully(flexcache_delete,
                                                     enable_tunneling=True)
        except netapp_utils.zapi.NaApiError as error:
            self.module.fail_json(msg='Error deleting FlexCache : %s' %
                                  (to_native(error)),
                                  exception=traceback.format_exc())
        results = dict()
        for key in ('result-status', 'result-jobid'):
            if result.get_child_by_name(key):
                results[key] = result[key]
        return results

    def flexcache_delete(self):
        """
        Delete FlexCache relationship at destination cluster
        Check job status
        """
        if self.parameters['force_unmount']:
            self.volume_unmount()
        if self.parameters['force_offline']:
            self.volume_offline()
        results = self.flexcache_delete_async()
        status = results.get('result-status')
        if status == 'in_progress' and 'result-jobid' in results:
            if self.parameters['time_out'] == 0:
                # asynchronous call, assuming success!
                return
            error = self.check_job_status(results['result-jobid'])
            if error is None:
                return
            else:
                self.module.fail_json(msg='Error when deleting flexcache: %s' %
                                      error)
        self.module.fail_json(
            msg='Unexpected error when deleting flexcache: results is: %s' %
            repr(results))

    def check_parameters(self):
        """
        Validate parameters and fail if one or more required params are missing
        """
        missings = list()
        expected = ('origin_volume', 'origin_vserver')
        if self.parameters['state'] == 'present':
            for param in expected:
                if not self.parameters.get(param):
                    missings.append(param)
        if missings:
            plural = 's' if len(missings) > 1 else ''
            msg = 'Missing parameter%s: %s' % (plural, ', '.join(missings))
            self.module.fail_json(msg=msg)

    def apply(self):
        """
        Apply action to FlexCache
        """
        netapp_utils.ems_log_event("na_ontap_flexcache", self.server)
        current = self.flexcache_get()
        cd_action = self.na_helper.get_cd_action(current, self.parameters)
        if cd_action == 'create':
            self.check_parameters()
            self.flexcache_create()
        elif cd_action == 'delete':
            self.flexcache_delete()
        self.module.exit_json(changed=self.na_helper.changed)
Ejemplo n.º 21
0
def main():
    argument_spec = cs_argument_spec()
    argument_spec.update(
        dict(
            name=dict(required=True),
            disk_offering=dict(),
            display_volume=dict(type='bool'),
            max_iops=dict(type='int'),
            min_iops=dict(type='int'),
            size=dict(type='int'),
            snapshot=dict(),
            vm=dict(),
            device_id=dict(type='int'),
            custom_id=dict(),
            force=dict(type='bool', default=False),
            shrink_ok=dict(type='bool', default=False),
            state=dict(default='present',
                       choices=[
                           'present',
                           'absent',
                           'attached',
                           'detached',
                           'extracted',
                           'uploaded',
                       ]),
            zone=dict(),
            domain=dict(),
            account=dict(),
            project=dict(),
            poll_async=dict(type='bool', default=True),
            tags=dict(type='list', aliases=['tag']),
            url=dict(),
            mode=dict(choices=['http_download', 'ftp_upload'],
                      default='http_download'),
            format=dict(choices=['QCOW2', 'RAW', 'VHD', 'VHDX', 'OVA']),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           required_together=cs_required_together(),
                           mutually_exclusive=(['snapshot',
                                                'disk_offering'], ),
                           required_if=[
                               ('state', 'uploaded', ['url', 'format']),
                           ],
                           supports_check_mode=True)

    acs_vol = AnsibleCloudStackVolume(module)

    state = module.params.get('state')

    if state in ['absent']:
        volume = acs_vol.absent_volume()
    elif state in ['attached']:
        volume = acs_vol.attached_volume()
    elif state in ['detached']:
        volume = acs_vol.detached_volume()
    elif state == 'extracted':
        volume = acs_vol.extract_volume()
    elif state == 'uploaded':
        volume = acs_vol.upload_volume()
    else:
        volume = acs_vol.present_volume()

    result = acs_vol.get_result(volume)

    module.exit_json(**result)
Ejemplo n.º 22
0
class Lacp(object):
    """
    Manages Eth-Trunk interfaces LACP.
    """

    def __init__(self, argument_spec):
        self.spec = argument_spec
        self.module = None
        self.init_module()

        # module input info
        self.trunk_id = self.module.params['trunk_id']
        self.mode = self.module.params['mode']
        self.param = dict()

        self.state = self.module.params['state']

        # state
        self.changed = False
        self.updates_cmd = list()
        self.results = dict()
        self.proposed = dict()
        self.existing = dict()
        self.end_state = dict()

    def init_module(self):
        """ init AnsibleModule """

        self.module = AnsibleModule(
            argument_spec=self.spec,
            mutually_exclusive=[['trunk_id', 'global_priority']],
            required_one_of=[['trunk_id', 'global_priority']],
            supports_check_mode=True)

    def check_params(self):
        """check module params """
        for key in self.module.params.keys():
            if key in LACP.keys() and self.module.params[key] is not None:
                self.param[key] = self.module.params[key]
                if isinstance(self.module.params[key], bool):
                    self.param[key] = str(self.module.params[key]).lower()
        msg = check_param(self.param)
        if msg != 'ok':
            self.module.fail_json(msg=msg)

    def get_existing(self):
        """get existing"""
        xml_str = bulid_xml(self.param)
        xml = get_nc_config(self.module, xml_str)
        return xml_to_dict(xml)

    def get_proposed(self):
        """get proposed"""
        proposed = dict(state=self.state)
        proposed.update(self.param)
        return proposed

    def get_end_state(self):
        """ get end_state"""
        xml_str = bulid_xml(self.param)
        xml = get_nc_config(self.module, xml_str)
        return xml_to_dict(xml)

    def work(self):
        """worker"""

        self.check_params()
        existing = self.get_existing()
        proposed = self.get_proposed()

        # deal present or absent
        if self.state == "present":
            operation = 'merge'
        else:
            operation = 'delete'

        xml_str = bulid_xml(self.param, operation=operation)
        set_nc_config(self.module, xml_str)
        end_state = self.get_end_state()

        self.results['proposed'] = proposed
        self.results['existing'] = existing
        self.results['end_state'] = end_state
        updates_cmd = compare_config(self.module, existing, end_state)
        self.results['updates'] = updates_cmd
        if updates_cmd:
            self.results['changed'] = True
        else:
            self.results['changed'] = False

        self.module.exit_json(**self.results)
class IscsiTarget(object):
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                name=dict(type='str', required=False, aliases=['alias']),
                ping=dict(type='bool', required=False, default=True),
                chap_secret=dict(type='str',
                                 required=False,
                                 aliases=['chap', 'password'],
                                 no_log=True),
                unnamed_discovery=dict(type='bool',
                                       required=False,
                                       default=True),
                log_path=dict(type='str', required=False),
            ))

        self.module = AnsibleModule(
            argument_spec=argument_spec,
            supports_check_mode=True,
        )
        args = self.module.params

        self.name = args['name']
        self.ping = args['ping']
        self.chap_secret = args['chap_secret']
        self.unnamed_discovery = args['unnamed_discovery']

        self.ssid = args['ssid']
        self.url = args['api_url']
        self.creds = dict(
            url_password=args['api_password'],
            validate_certs=args['validate_certs'],
            url_username=args['api_username'],
        )

        self.check_mode = self.module.check_mode
        self.post_body = dict()
        self.controllers = list()

        log_path = args['log_path']

        # logging setup
        self._logger = logging.getLogger(self.__class__.__name__)

        if log_path:
            logging.basicConfig(
                level=logging.DEBUG,
                filename=log_path,
                filemode='w',
                format=
                '%(relativeCreated)dms %(levelname)s %(module)s.%(funcName)s:%(lineno)d\n %(message)s'
            )

        if not self.url.endswith('/'):
            self.url += '/'

        if self.chap_secret:
            if len(self.chap_secret) < 12 or len(self.chap_secret) > 57:
                self.module.fail_json(
                    msg=
                    "The provided CHAP secret is not valid, it must be between 12 and 57"
                    " characters in length.")

            for c in self.chap_secret:
                ordinal = ord(c)
                if ordinal < 32 or ordinal > 126:
                    self.module.fail_json(
                        msg=
                        "The provided CHAP secret is not valid, it may only utilize ascii"
                        " characters with decimal values between 32 and 126.")

    @property
    def target(self):
        """Provide information on the iSCSI Target configuration

        Sample:
        {
          'alias': 'myCustomName',
          'ping': True,
          'unnamed_discovery': True,
          'chap': False,
          'iqn': 'iqn.1992-08.com.netapp:2800.000a132000b006d2000000005a0e8f45',
        }
        """
        target = dict()
        try:
            (rc, data) = request(
                self.url +
                'storage-systems/%s/graph/xpath-filter?query=/storagePoolBundle/target'
                % self.ssid,
                headers=HEADERS,
                **self.creds)
            # This likely isn't an iSCSI-enabled system
            if not data:
                self.module.fail_json(
                    msg=
                    "This storage-system doesn't appear to have iSCSI interfaces. Array Id [%s]."
                    % (self.ssid))

            data = data[0]

            chap = any([
                auth
                for auth in data['configuredAuthMethods']['authMethodData']
                if auth['authMethod'] == 'chap'
            ])

            target.update(
                dict(alias=data['alias']['iscsiAlias'],
                     iqn=data['nodeName']['iscsiNodeName'],
                     chap=chap))

            (rc, data) = request(
                self.url +
                'storage-systems/%s/graph/xpath-filter?query=/sa/iscsiEntityData'
                % self.ssid,
                headers=HEADERS,
                **self.creds)

            data = data[0]
            target.update(
                dict(
                    ping=data['icmpPingResponseEnabled'],
                    unnamed_discovery=data['unnamedDiscoverySessionsEnabled']))

        except Exception as err:
            self.module.fail_json(
                msg=
                "Failed to retrieve the iSCSI target information. Array Id [%s]. Error [%s]."
                % (self.ssid, to_native(err)))

        return target

    def apply_iscsi_settings(self):
        """Update the iSCSI target alias and CHAP settings"""
        update = False
        target = self.target

        body = dict()

        if self.name is not None and self.name != target['alias']:
            update = True
            body['alias'] = self.name

        # If the CHAP secret was provided, we trigger an update.
        if self.chap_secret:
            update = True
            body.update(
                dict(enableChapAuthentication=True,
                     chapSecret=self.chap_secret))
        # If no secret was provided, then we disable chap
        elif target['chap']:
            update = True
            body.update(dict(enableChapAuthentication=False))

        if update and not self.check_mode:
            try:
                request(self.url +
                        'storage-systems/%s/iscsi/target-settings' % self.ssid,
                        method='POST',
                        data=json.dumps(body),
                        headers=HEADERS,
                        **self.creds)
            except Exception as err:
                self.module.fail_json(
                    msg=
                    "Failed to update the iSCSI target settings. Array Id [%s]. Error [%s]."
                    % (self.ssid, to_native(err)))

        return update

    def apply_target_changes(self):
        update = False
        target = self.target

        body = dict()

        if self.ping != target['ping']:
            update = True
            body['icmpPingResponseEnabled'] = self.ping

        if self.unnamed_discovery != target['unnamed_discovery']:
            update = True
            body['unnamedDiscoverySessionsEnabled'] = self.unnamed_discovery

        self._logger.info(pformat(body))
        if update and not self.check_mode:
            try:
                request(self.url +
                        'storage-systems/%s/iscsi/entity' % self.ssid,
                        method='POST',
                        data=json.dumps(body),
                        timeout=60,
                        headers=HEADERS,
                        **self.creds)
            except Exception as err:
                self.module.fail_json(
                    msg=
                    "Failed to update the iSCSI target settings. Array Id [%s]. Error [%s]."
                    % (self.ssid, to_native(err)))
        return update

    def update(self):
        update = self.apply_iscsi_settings()
        update = self.apply_target_changes() or update

        target = self.target
        data = dict(
            (key, target[key]) for key in target if key in ['iqn', 'alias'])

        self.module.exit_json(msg="The interface settings have been updated.",
                              changed=update,
                              **data)

    def __call__(self, *args, **kwargs):
        self.update()
Ejemplo n.º 24
0
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "state": {
            "required": True,
            "type": "str",
            "choices": ["present", "absent"]
        },
        "system_snmp_user": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "auth_proto": {
                    "required": False,
                    "type": "str",
                    "choices": ["md5", "sha"]
                },
                "auth_pwd": {
                    "required": False,
                    "type": "str"
                },
                "events": {
                    "required":
                    False,
                    "type":
                    "list",
                    "choices": [
                        "cpu-high", "mem-low", "log-full", "intf-ip",
                        "vpn-tun-up", "vpn-tun-down", "ha-switch",
                        "ha-hb-failure", "ips-signature", "ips-anomaly",
                        "av-virus", "av-oversize", "av-pattern",
                        "av-fragmented", "fm-if-change", "fm-conf-change",
                        "bgp-established", "bgp-backward-transition",
                        "ha-member-up", "ha-member-down", "ent-conf-change",
                        "av-conserve", "av-bypass", "av-oversize-passed",
                        "av-oversize-blocked", "ips-pkg-update",
                        "ips-fail-open", "faz-disconnect", "wc-ap-up",
                        "wc-ap-down", "fswctl-session-up",
                        "fswctl-session-down", "load-balance-real-server-down",
                        "device-new", "per-cpu-high"
                    ]
                },
                "ha_direct": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "name": {
                    "required": True,
                    "type": "str"
                },
                "notify_hosts": {
                    "required": False,
                    "type": "list"
                },
                "notify_hosts6": {
                    "required": False,
                    "type": "list"
                },
                "priv_proto": {
                    "required": False,
                    "type": "str",
                    "choices": ["aes", "des", "aes256", "aes256cisco"]
                },
                "priv_pwd": {
                    "required": False,
                    "type": "str"
                },
                "queries": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "query_port": {
                    "required": False,
                    "type": "int"
                },
                "security_level": {
                    "required": False,
                    "type": "str",
                    "choices":
                    ["no-auth-no-priv", "auth-no-priv", "auth-priv"]
                },
                "source_ip": {
                    "required": False,
                    "type": "str"
                },
                "source_ipv6": {
                    "required": False,
                    "type": "str"
                },
                "status": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                },
                "trap_lport": {
                    "required": False,
                    "type": "int"
                },
                "trap_rport": {
                    "required": False,
                    "type": "int"
                },
                "trap_status": {
                    "required": False,
                    "type": "str",
                    "choices": ["enable", "disable"]
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_system_snmp(
                module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_system_snmp(module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
Ejemplo n.º 25
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            paths=dict(type='list', required=True, aliases=['name', 'path']),
            patterns=dict(type='list', default=['*'], aliases=['pattern']),
            excludes=dict(type='list', aliases=['exclude']),
            contains=dict(type='str'),
            file_type=dict(type='str',
                           default="file",
                           choices=['any', 'directory', 'file', 'link']),
            age=dict(type='str'),
            age_stamp=dict(type='str',
                           default="mtime",
                           choices=['atime', 'ctime', 'mtime']),
            size=dict(type='str'),
            recurse=dict(type='bool', default=False),
            hidden=dict(type='bool', default=False),
            follow=dict(type='bool', default=False),
            get_checksum=dict(type='bool', default=False),
            use_regex=dict(type='bool', default=False),
            depth=dict(type='int'),
        ),
        supports_check_mode=True,
    )

    params = module.params

    filelist = []

    if params['age'] is None:
        age = None
    else:
        # convert age to seconds:
        m = re.match(r"^(-?\d+)(s|m|h|d|w)?$", params['age'].lower())
        seconds_per_unit = {
            "s": 1,
            "m": 60,
            "h": 3600,
            "d": 86400,
            "w": 604800
        }
        if m:
            age = int(m.group(1)) * seconds_per_unit.get(m.group(2), 1)
        else:
            module.fail_json(age=params['age'], msg="failed to process age")

    if params['size'] is None:
        size = None
    else:
        # convert size to bytes:
        m = re.match(r"^(-?\d+)(b|k|m|g|t)?$", params['size'].lower())
        bytes_per_unit = {
            "b": 1,
            "k": 1024,
            "m": 1024**2,
            "g": 1024**3,
            "t": 1024**4
        }
        if m:
            size = int(m.group(1)) * bytes_per_unit.get(m.group(2), 1)
        else:
            module.fail_json(size=params['size'], msg="failed to process size")

    now = time.time()
    msg = ''
    looked = 0
    for npath in params['paths']:
        npath = os.path.expanduser(os.path.expandvars(npath))
        if os.path.isdir(npath):
            for root, dirs, files in os.walk(npath,
                                             followlinks=params['follow']):
                if params['depth']:
                    depth = root.replace(npath.rstrip(os.path.sep),
                                         '').count(os.path.sep)
                    if files or dirs:
                        depth += 1
                    if depth > params['depth']:
                        del (dirs[:])
                        continue
                looked = looked + len(files) + len(dirs)
                for fsobj in (files + dirs):
                    fsname = os.path.normpath(os.path.join(root, fsobj))

                    if os.path.basename(fsname).startswith(
                            '.') and not params['hidden']:
                        continue

                    try:
                        st = os.lstat(fsname)
                    except Exception:
                        msg += "%s was skipped as it does not seem to be a valid file or it cannot be accessed\n" % fsname
                        continue

                    r = {'path': fsname}
                    if params['file_type'] == 'any':
                        if pfilter(fsobj, params['patterns'],
                                   params['excludes'],
                                   params['use_regex']) and agefilter(
                                       st, now, age, params['age_stamp']):

                            r.update(statinfo(st))
                            if stat.S_ISREG(
                                    st.st_mode) and params['get_checksum']:
                                r['checksum'] = module.sha1(fsname)
                            filelist.append(r)

                    elif stat.S_ISDIR(
                            st.st_mode) and params['file_type'] == 'directory':
                        if pfilter(fsobj, params['patterns'],
                                   params['excludes'],
                                   params['use_regex']) and agefilter(
                                       st, now, age, params['age_stamp']):

                            r.update(statinfo(st))
                            filelist.append(r)

                    elif stat.S_ISREG(
                            st.st_mode) and params['file_type'] == 'file':
                        if pfilter(fsobj, params['patterns'], params['excludes'], params['use_regex']) and \
                           agefilter(st, now, age, params['age_stamp']) and \
                           sizefilter(st, size) and contentfilter(fsname, params['contains']):

                            r.update(statinfo(st))
                            if params['get_checksum']:
                                r['checksum'] = module.sha1(fsname)
                            filelist.append(r)

                    elif stat.S_ISLNK(
                            st.st_mode) and params['file_type'] == 'link':
                        if pfilter(fsobj, params['patterns'],
                                   params['excludes'],
                                   params['use_regex']) and agefilter(
                                       st, now, age, params['age_stamp']):

                            r.update(statinfo(st))
                            filelist.append(r)

                if not params['recurse']:
                    break
        else:
            msg += "%s was skipped as it does not seem to be a valid directory or it cannot be accessed\n" % npath

    matched = len(filelist)
    module.exit_json(files=filelist,
                     changed=False,
                     msg=msg,
                     matched=matched,
                     examined=looked)
def main():
    fields = {
        "host": {
            "required": False,
            "type": "str"
        },
        "username": {
            "required": False,
            "type": "str"
        },
        "password": {
            "required": False,
            "type": "str",
            "default": "",
            "no_log": True
        },
        "vdom": {
            "required": False,
            "type": "str",
            "default": "root"
        },
        "https": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "ssl_verify": {
            "required": False,
            "type": "bool",
            "default": True
        },
        "state": {
            "required": False,
            "type": "str",
            "choices": ["present", "absent"]
        },
        "firewall_vip46": {
            "required": False,
            "type": "dict",
            "default": None,
            "options": {
                "state": {
                    "required": False,
                    "type": "str",
                    "choices": ["present", "absent"]
                },
                "arp_reply": {
                    "required": False,
                    "type": "str",
                    "choices": ["disable", "enable"]
                },
                "color": {
                    "required": False,
                    "type": "int"
                },
                "comment": {
                    "required": False,
                    "type": "str"
                },
                "extip": {
                    "required": False,
                    "type": "str"
                },
                "extport": {
                    "required": False,
                    "type": "str"
                },
                "id": {
                    "required": False,
                    "type": "int"
                },
                "ldb_method": {
                    "required":
                    False,
                    "type":
                    "str",
                    "choices": [
                        "static", "round-robin", "weighted", "least-session",
                        "least-rtt", "first-alive"
                    ]
                },
                "mappedip": {
                    "required": False,
                    "type": "str"
                },
                "mappedport": {
                    "required": False,
                    "type": "str"
                },
                "monitor": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "name": {
                            "required": True,
                            "type": "str"
                        }
                    }
                },
                "name": {
                    "required": True,
                    "type": "str"
                },
                "portforward": {
                    "required": False,
                    "type": "str",
                    "choices": ["disable", "enable"]
                },
                "protocol": {
                    "required": False,
                    "type": "str",
                    "choices": ["tcp", "udp"]
                },
                "realservers": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "client_ip": {
                            "required": False,
                            "type": "str"
                        },
                        "healthcheck": {
                            "required": False,
                            "type": "str",
                            "choices": ["disable", "enable", "vip"]
                        },
                        "holddown_interval": {
                            "required": False,
                            "type": "int"
                        },
                        "id": {
                            "required": True,
                            "type": "int"
                        },
                        "ip": {
                            "required": False,
                            "type": "str"
                        },
                        "max_connections": {
                            "required": False,
                            "type": "int"
                        },
                        "monitor": {
                            "required": False,
                            "type": "str"
                        },
                        "port": {
                            "required": False,
                            "type": "int"
                        },
                        "status": {
                            "required": False,
                            "type": "str",
                            "choices": ["active", "standby", "disable"]
                        },
                        "weight": {
                            "required": False,
                            "type": "int"
                        }
                    }
                },
                "server_type": {
                    "required": False,
                    "type": "str",
                    "choices": ["http", "tcp", "udp", "ip"]
                },
                "src_filter": {
                    "required": False,
                    "type": "list",
                    "options": {
                        "range": {
                            "required": True,
                            "type": "str"
                        }
                    }
                },
                "type": {
                    "required": False,
                    "type": "str",
                    "choices": ["static-nat", "server-load-balance"]
                },
                "uuid": {
                    "required": False,
                    "type": "str"
                }
            }
        }
    }

    module = AnsibleModule(argument_spec=fields, supports_check_mode=False)

    # legacy_mode refers to using fortiosapi instead of HTTPAPI
    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
                  'username' in module.params and module.params['username'] is not None and \
                  'password' in module.params and module.params['password'] is not None

    if not legacy_mode:
        if module._socket_path:
            connection = Connection(module._socket_path)
            fos = FortiOSHandler(connection)

            is_error, has_changed, result = fortios_firewall(
                module.params, fos)
        else:
            module.fail_json(**FAIL_SOCKET_MSG)
    else:
        try:
            from fortiosapi import FortiOSAPI
        except ImportError:
            module.fail_json(msg="fortiosapi module is required")

        fos = FortiOSAPI()

        login(module.params, fos)
        is_error, has_changed, result = fortios_firewall(module.params, fos)
        fos.logout()

    if not is_error:
        module.exit_json(changed=has_changed, meta=result)
    else:
        module.fail_json(msg="Error in repo", meta=result)
def main():
    """entry point for module execution
    """
    argument_spec = dict(
        path=dict(required=True),
        content=dict(),
        method=dict(choices=['post', 'put', 'patch', 'delete'], default='post'),
        format=dict(choices=['json', 'xml'], default='json'),
    )
    required_if = [
        ['method', 'post', ['content']],
        ['method', 'put', ['content']],
        ['method', 'patch', ['content']],
    ]

    module = AnsibleModule(
        argument_spec=argument_spec,
        required_if=required_if,
        supports_check_mode=True
    )

    path = module.params['path']
    candidate = module.params['content']
    method = module.params['method']
    format = module.params['format']

    if isinstance(candidate, string_types):
        candidate = json.loads(candidate)

    warnings = list()
    result = {'changed': False, 'warnings': warnings}

    running = None
    commit = not module.check_mode
    try:
        running = restconf.get(module, path, output=format)
    except ConnectionError as exc:
        if exc.code == 404:
            running = None
        else:
            module.fail_json(msg=to_text(exc), code=exc.code)

    try:
        if method == 'delete':
            if running:
                if commit:
                    restconf.edit_config(module, path=path, method='DELETE')
                result['changed'] = True
            else:
                warnings.append("delete not executed as resource '%s' does not exist" % path)
        else:
            if running:
                if method == 'post':
                    module.fail_json(msg="resource '%s' already exist" % path, code=409)
                diff = dict_diff(running, candidate)
                result['candidate'] = candidate
                result['running'] = running
            else:
                method = 'POST'
                diff = candidate

            if diff:
                if module._diff:
                    result['diff'] = {'prepared': diff, 'before': candidate, 'after': running}

                if commit:
                    restconf.edit_config(module, path=path, content=diff, method=method.upper(), format=format)
                result['changed'] = True

    except ConnectionError as exc:
        module.fail_json(msg=str(exc), code=exc.code)

    module.exit_json(**result)
def main():
    argument_spec = ucs_argument_spec
    argument_spec.update(
        org_dn=dict(type='str', default='org-root'),
        name=dict(type='str', required=True),
        descr=dict(type='str',
                   default='',
                   aliases=['description', 'descrption']),
        order=dict(type='str',
                   default='default',
                   choices=['default', 'sequential']),
        first_addr=dict(type='str'),
        last_addr=dict(type='str'),
        state=dict(default='present',
                   choices=['present', 'absent'],
                   type='str'),
    )
    module = AnsibleModule(
        argument_spec,
        supports_check_mode=True,
    )
    # UCSModule verifies ucsmsdk is present and exits on failure.  Imports are below ucs object creation.
    ucs = UCSModule(module)

    err = False

    from ucsmsdk.mometa.macpool.MacpoolPool import MacpoolPool
    from ucsmsdk.mometa.macpool.MacpoolBlock import MacpoolBlock

    changed = False
    try:
        mo_exists = False
        props_match = False
        # dn is <org_dn>/mac-pool-<name>
        dn = module.params['org_dn'] + '/mac-pool-' + module.params['name']
        mo = ucs.login_handle.query_dn(dn)
        if mo:
            mo_exists = True

        if module.params['state'] == 'absent':
            if mo_exists:
                if not module.check_mode:
                    ucs.login_handle.remove_mo(mo)
                    ucs.login_handle.commit()
                changed = True
        else:
            if mo_exists:
                # check top-level mo props
                kwargs = dict(assignment_order=module.params['order'])
                kwargs['descr'] = module.params['descr']
                if (mo.check_prop_match(**kwargs)):
                    # top-level props match, check next level mo/props
                    if module.params['last_addr'] and module.params[
                            'first_addr']:
                        # mac address block specified, check properties
                        block_dn = dn + '/block-' + module.params[
                            'first_addr'].upper(
                            ) + '-' + module.params['last_addr'].upper()
                        mo_1 = ucs.login_handle.query_dn(block_dn)
                        if mo_1:
                            props_match = True
                    else:
                        # no MAC address block specified, but top-level props matched
                        props_match = True

            if not props_match:
                if not module.check_mode:
                    # create if mo does not already exist
                    mo = MacpoolPool(
                        parent_mo_or_dn=module.params['org_dn'],
                        name=module.params['name'],
                        descr=module.params['descr'],
                        assignment_order=module.params['order'],
                    )

                    if module.params['last_addr'] and module.params[
                            'first_addr']:
                        mo_1 = MacpoolBlock(
                            parent_mo_or_dn=mo,
                            to=module.params['last_addr'],
                            r_from=module.params['first_addr'],
                        )

                    ucs.login_handle.add_mo(mo, True)
                    ucs.login_handle.commit()
                changed = True

    except Exception as e:
        err = True
        ucs.result['msg'] = "setup error: %s " % str(e)

    ucs.result['changed'] = changed
    if err:
        module.fail_json(**ucs.result)
    module.exit_json(**ucs.result)
Ejemplo n.º 29
0
def main():
    module = AnsibleModule(argument_spec=dict(
        server_url=dict(type='str', required=True, aliases=['url']),
        login_user=dict(type='str', required=True),
        login_password=dict(type='str', required=True, no_log=True),
        host_name=dict(type='str', required=True),
        http_login_user=dict(type='str', required=False, default=None),
        http_login_password=dict(type='str',
                                 required=False,
                                 default=None,
                                 no_log=True),
        validate_certs=dict(type='bool', required=False, default=True),
        host_groups=dict(type='list', required=False),
        link_templates=dict(type='list', required=False),
        status=dict(type='str',
                    default="enabled",
                    choices=['enabled', 'disabled']),
        state=dict(type='str',
                   default="present",
                   choices=['present', 'absent']),
        inventory_mode=dict(type='str',
                            required=False,
                            choices=['automatic', 'manual', 'disabled']),
        ipmi_authtype=dict(type='int', default=None),
        ipmi_privilege=dict(type='int', default=None),
        ipmi_username=dict(type='str', required=False, default=None),
        ipmi_password=dict(type='str',
                           required=False,
                           default=None,
                           no_log=True),
        tls_connect=dict(type='int', default=1),
        tls_accept=dict(type='int', default=1),
        tls_psk_identity=dict(type='str', required=False),
        tls_psk=dict(type='str', required=False),
        ca_cert=dict(type='str', required=False, aliases=['tls_issuer']),
        tls_subject=dict(type='str', required=False),
        inventory_zabbix=dict(type='dict', required=False),
        timeout=dict(type='int', default=10),
        interfaces=dict(type='list', required=False),
        force=dict(type='bool', default=True),
        proxy=dict(type='str', required=False),
        visible_name=dict(type='str', required=False),
        description=dict(type='str', required=False)),
                           supports_check_mode=True)

    if not HAS_ZABBIX_API:
        module.fail_json(msg=missing_required_lib(
            'zabbix-api', url='https://pypi.org/project/zabbix-api/'),
                         exception=ZBX_IMP_ERR)

    server_url = module.params['server_url']
    login_user = module.params['login_user']
    login_password = module.params['login_password']
    http_login_user = module.params['http_login_user']
    http_login_password = module.params['http_login_password']
    validate_certs = module.params['validate_certs']
    host_name = module.params['host_name']
    visible_name = module.params['visible_name']
    description = module.params['description']
    host_groups = module.params['host_groups']
    link_templates = module.params['link_templates']
    inventory_mode = module.params['inventory_mode']
    ipmi_authtype = module.params['ipmi_authtype']
    ipmi_privilege = module.params['ipmi_privilege']
    ipmi_username = module.params['ipmi_username']
    ipmi_password = module.params['ipmi_password']
    tls_connect = module.params['tls_connect']
    tls_accept = module.params['tls_accept']
    tls_psk_identity = module.params['tls_psk_identity']
    tls_psk = module.params['tls_psk']
    tls_issuer = module.params['ca_cert']
    tls_subject = module.params['tls_subject']
    inventory_zabbix = module.params['inventory_zabbix']
    status = module.params['status']
    state = module.params['state']
    timeout = module.params['timeout']
    interfaces = module.params['interfaces']
    force = module.params['force']
    proxy = module.params['proxy']

    # convert enabled to 0; disabled to 1
    status = 1 if status == "disabled" else 0

    zbx = None
    # login to zabbix
    try:
        zbx = ZabbixAPI(server_url,
                        timeout=timeout,
                        user=http_login_user,
                        passwd=http_login_password,
                        validate_certs=validate_certs)
        zbx.login(login_user, login_password)
        atexit.register(zbx.logout)
    except Exception as e:
        module.fail_json(msg="Failed to connect to Zabbix server: %s" % e)

    host = Host(module, zbx)

    template_ids = []
    if link_templates:
        template_ids = host.get_template_ids(link_templates)

    group_ids = []

    if host_groups:
        group_ids = host.get_group_ids_by_group_names(host_groups)

    ip = ""
    if interfaces:
        # ensure interfaces are well-formed
        for interface in interfaces:
            if 'type' not in interface:
                module.fail_json(
                    msg=
                    "(interface) type needs to be specified for interface '%s'."
                    % interface)
            interfacetypes = {'agent': 1, 'snmp': 2, 'ipmi': 3, 'jmx': 4}
            if interface['type'] in interfacetypes.keys():
                interface['type'] = interfacetypes[interface['type']]
            if interface['type'] < 1 or interface['type'] > 4:
                module.fail_json(
                    msg="Interface type can only be 1-4 for interface '%s'." %
                    interface)
            if 'useip' not in interface:
                interface['useip'] = 0
            if 'dns' not in interface:
                if interface['useip'] == 0:
                    module.fail_json(
                        msg=
                        "dns needs to be set if useip is 0 on interface '%s'."
                        % interface)
                interface['dns'] = ''
            if 'ip' not in interface:
                if interface['useip'] == 1:
                    module.fail_json(
                        msg=
                        "ip needs to be set if useip is 1 on interface '%s'." %
                        interface)
                interface['ip'] = ''
            if 'main' not in interface:
                interface['main'] = 0
            if 'port' in interface and not isinstance(interface['port'], str):
                try:
                    interface['port'] = str(interface['port'])
                except ValueError:
                    module.fail_json(
                        msg=
                        "port should be convertable to string on interface '%s'."
                        % interface)
            if 'port' not in interface:
                if interface['type'] == 1:
                    interface['port'] = "10050"
                elif interface['type'] == 2:
                    interface['port'] = "161"
                elif interface['type'] == 3:
                    interface['port'] = "623"
                elif interface['type'] == 4:
                    interface['port'] = "12345"

            if interface['type'] == 1:
                ip = interface['ip']

    # Use proxy specified, or set to 0
    if proxy:
        proxy_id = host.get_proxyid_by_proxy_name(proxy)
    else:
        proxy_id = 0

    # check if host exist
    is_host_exist = host.is_host_exist(host_name)

    if is_host_exist:
        # get host id by host name
        zabbix_host_obj = host.get_host_by_host_name(host_name)
        host_id = zabbix_host_obj['hostid']

        # If proxy is not specified as a module parameter, use the existing setting
        if proxy is None:
            proxy_id = int(zabbix_host_obj['proxy_hostid'])

        if state == "absent":
            # remove host
            host.delete_host(host_id, host_name)
            module.exit_json(changed=True,
                             result="Successfully delete host %s" % host_name)
        else:
            if not host_groups:
                # if host_groups have not been specified when updating an existing host, just
                # get the group_ids from the existing host without updating them.
                group_ids = host.get_group_ids_by_host_id(host_id)

            # get existing host's interfaces
            exist_interfaces = host._zapi.hostinterface.get({
                'output': 'extend',
                'hostids': host_id
            })

            # if no interfaces were specified with the module, start with an empty list
            if not interfaces:
                interfaces = []

            # When force=no is specified, append existing interfaces to interfaces to update. When
            # no interfaces have been specified, copy existing interfaces as specified from the API.
            # Do the same with templates and host groups.
            if not force or not interfaces:
                for interface in copy.deepcopy(exist_interfaces):
                    # remove values not used during hostinterface.add/update calls
                    for key in tuple(interface.keys()):
                        if key in ['interfaceid', 'hostid', 'bulk']:
                            interface.pop(key, None)

                    for index in interface.keys():
                        if index in ['useip', 'main', 'type']:
                            interface[index] = int(interface[index])

                    if interface not in interfaces:
                        interfaces.append(interface)

            if not force or link_templates is None:
                template_ids = list(
                    set(template_ids +
                        host.get_host_templates_by_host_id(host_id)))

            if not force:
                for group_id in host.get_group_ids_by_host_id(host_id):
                    if group_id not in group_ids:
                        group_ids.append(group_id)

            # update host
            if host.check_all_properties(
                    host_id, group_ids, status, interfaces, template_ids,
                    exist_interfaces, zabbix_host_obj, proxy_id, visible_name,
                    description, host_name, inventory_mode, inventory_zabbix,
                    tls_accept, tls_psk_identity, tls_psk, tls_issuer,
                    tls_subject, tls_connect, ipmi_authtype, ipmi_privilege,
                    ipmi_username, ipmi_password):
                host.update_host(host_name, group_ids, status, host_id,
                                 interfaces, exist_interfaces, proxy_id,
                                 visible_name, description, tls_connect,
                                 tls_accept, tls_psk_identity, tls_psk,
                                 tls_issuer, tls_subject, ipmi_authtype,
                                 ipmi_privilege, ipmi_username, ipmi_password)
                host.link_or_clear_template(host_id, template_ids, tls_connect,
                                            tls_accept, tls_psk_identity,
                                            tls_psk, tls_issuer, tls_subject,
                                            ipmi_authtype, ipmi_privilege,
                                            ipmi_username, ipmi_password)
                host.update_inventory_mode(host_id, inventory_mode)
                host.update_inventory_zabbix(host_id, inventory_zabbix)

                module.exit_json(
                    changed=True,
                    result=
                    "Successfully update host %s (%s) and linked with template '%s'"
                    % (host_name, ip, link_templates))
            else:
                module.exit_json(changed=False)

    else:
        if state == "absent":
            # the host is already deleted.
            module.exit_json(changed=False)

        if not group_ids:
            module.fail_json(
                msg="Specify at least one group for creating host '%s'." %
                host_name)

        if not interfaces or (interfaces and len(interfaces) == 0):
            module.fail_json(
                msg="Specify at least one interface for creating host '%s'." %
                host_name)

        # create host
        host_id = host.add_host(host_name, group_ids, status, interfaces,
                                proxy_id, visible_name, description,
                                tls_connect, tls_accept, tls_psk_identity,
                                tls_psk, tls_issuer, tls_subject,
                                ipmi_authtype, ipmi_privilege, ipmi_username,
                                ipmi_password)
        host.link_or_clear_template(host_id, template_ids, tls_connect,
                                    tls_accept, tls_psk_identity, tls_psk,
                                    tls_issuer, tls_subject, ipmi_authtype,
                                    ipmi_privilege, ipmi_username,
                                    ipmi_password)
        host.update_inventory_mode(host_id, inventory_mode)
        host.update_inventory_zabbix(host_id, inventory_zabbix)
        module.exit_json(
            changed=True,
            result=
            "Successfully added host %s (%s) and linked with template '%s'" %
            (host_name, ip, link_templates))
Ejemplo n.º 30
0
def main():
    module = AnsibleModule(argument_spec=dict(
        hosts=dict(required=True, type='str'),
        name=dict(required=True, type='str'),
        value=dict(required=False, default=None, type='str'),
        op=dict(required=False, default=None, choices=['get', 'wait', 'list']),
        state=dict(choices=['present', 'absent']),
        timeout=dict(required=False, default=300, type='int'),
        recursive=dict(required=False, default=False, type='bool')),
                           supports_check_mode=False)

    if not KAZOO_INSTALLED:
        module.fail_json(msg=missing_required_lib('kazoo >= 2.1'),
                         exception=KAZOO_IMP_ERR)

    check = check_params(module.params)
    if not check['success']:
        module.fail_json(msg=check['msg'])

    zoo = KazooCommandProxy(module)
    try:
        zoo.start()
    except KazooTimeoutError:
        module.fail_json(
            msg='The connection to the ZooKeeper ensemble timed out.')

    command_dict = {
        'op': {
            'get': zoo.get,
            'list': zoo.list,
            'wait': zoo.wait
        },
        'state': {
            'present': zoo.present,
            'absent': zoo.absent
        }
    }

    command_type = 'op' if 'op' in module.params and module.params[
        'op'] is not None else 'state'
    method = module.params[command_type]
    result, result_dict = command_dict[command_type][method]()
    zoo.shutdown()

    if result:
        module.exit_json(**result_dict)
    else:
        module.fail_json(**result_dict)