Example #1
0
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(state=dict(required=True, choices=["present", "absent"]),
                 target=dict(required=False, default=None),
                 volume_name=dict(required=True, aliases=["volume"]),
                 lun=dict(type="int", required=False),
                 target_type=dict(required=False, choices=["host", "group"])))
        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True)
        args = self.module.params

        self.state = args["state"] in ["present"]
        self.target = args["target"]
        self.volume = args["volume_name"]
        self.lun = args["lun"]
        self.target_type = args["target_type"]
        self.ssid = args["ssid"]
        self.url = args["api_url"]
        self.check_mode = self.module.check_mode
        self.creds = dict(url_username=args["api_username"],
                          url_password=args["api_password"],
                          validate_certs=args["validate_certs"])
        self.mapping_info = None

        if not self.url.endswith('/'):
            self.url += '/'
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(max_records=dict(type="int", default=50000),
                 log_level=dict(type="str",
                                default="writeOnly",
                                choices=["all", "writeOnly"]),
                 full_policy=dict(type="str",
                                  default="overWrite",
                                  choices=["overWrite",
                                           "preventSystemAccess"]),
                 threshold=dict(type="int", default=90),
                 force=dict(type="bool", default=False),
                 log_path=dict(type='str', required=False)))

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

        self.max_records = args["max_records"]
        if self.max_records < 100 or self.max_records > self.MAX_RECORDS:
            self.module.fail_json(
                msg=
                "Audit-log max_records count must be between 100 and 50000: [%s]"
                % self.max_records)
        self.threshold = args["threshold"]
        if self.threshold < 60 or self.threshold > 90:
            self.module.fail_json(
                msg=
                "Audit-log percent threshold must be between 60 and 90: [%s]" %
                self.threshold)
        self.log_level = args["log_level"]
        self.full_policy = args["full_policy"]
        self.force = args["force"]
        self.ssid = args['ssid']
        self.url = args['api_url']
        if not self.url.endswith('/'):
            self.url += '/'
        self.creds = dict(
            url_password=args['api_password'],
            validate_certs=args['validate_certs'],
            url_username=args['api_username'],
        )

        # logging setup
        log_path = args['log_path']
        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'
            )

        self.proxy_used = self.is_proxy()
        self._logger.info(self.proxy_used)
        self.check_mode = self.module.check_mode
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(dict(
            state=dict(type='str', required=False, default='present',
                       choices=['present', 'absent']),
            identifier=dict(type='str', required=False, ),
            username=dict(type='str', required=False, aliases=['bind_username']),
            password=dict(type='str', required=False, aliases=['bind_password'], no_log=True),
            name=dict(type='list', required=False, ),
            server=dict(type='str', required=False, aliases=['server_url']),
            search_base=dict(type='str', required=False, ),
            role_mappings=dict(type='dict', required=False, ),
            user_attribute=dict(type='str', required=False, default='sAMAccountName'),
            attributes=dict(type='list', default=['memberOf'], required=False, ),
            log_path=dict(type='str', required=False),
        ))

        required_if = [
            ["state", "present", ["username", "password", "server", "search_base", "role_mappings", ]]
        ]

        self.module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, required_if=required_if)
        args = self.module.params
        self.ldap = args['state'] == 'present'
        self.identifier = args['identifier']
        self.username = args['username']
        self.password = args['password']
        self.names = args['name']
        self.server = args['server']
        self.search_base = args['search_base']
        self.role_mappings = args['role_mappings']
        self.user_attribute = args['user_attribute']
        self.attributes = args['attributes']

        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'],
                          timeout=60)

        self.check_mode = self.module.check_mode

        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 += '/'

        self.embedded = None
        self.base_path = None
    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 __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                name=dict(type='str', required=False, aliases=['label']),
                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.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

        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.name and len(self.name) > 30:
            self.module.fail_json(
                msg=
                "The provided name is invalid, it must be < 30 characters in length."
            )
Example #6
0
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                state=dict(type='str',
                           required=False,
                           default='enabled',
                           aliases=['asup', 'auto_support', 'autosupport'],
                           choices=['enabled', 'disabled']),
                active=dict(
                    type='bool',
                    required=False,
                    default=True,
                ),
                days=dict(type='list',
                          required=False,
                          aliases=['schedule_days', 'days_of_week'],
                          choices=self.DAYS_OPTIONS),
                start=dict(type='int',
                           required=False,
                           default=0,
                           aliases=['start_time']),
                end=dict(type='int',
                         required=False,
                         default=24,
                         aliases=['end_time']),
                verbose=dict(type='bool', required=False, default=False),
                log_path=dict(type='str', required=False),
            ))

        self.module = AnsibleModule(
            argument_spec=argument_spec,
            supports_check_mode=True,
        )
        args = self.module.params
        self.asup = args['state'] == 'enabled'
        self.active = args['active']
        self.days = args['days']
        self.start = args['start']
        self.end = args['end']
        self.verbose = args['verbose']

        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

        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.start >= self.end:
            self.module.fail_json(
                msg="The value provided for the start time is invalid."
                " It must be less than the end time.")
        if self.start < 0 or self.start > 23:
            self.module.fail_json(
                msg=
                "The value provided for the start time is invalid. It must be between 0 and 23."
            )
        else:
            self.start = self.start * 60
        if self.end < 1 or self.end > 24:
            self.module.fail_json(
                msg=
                "The value provided for the end time is invalid. It must be between 1 and 24."
            )
        else:
            self.end = min(self.end * 60, 1439)

        if not self.days:
            self.days = self.DAYS_OPTIONS
Example #7
0
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                state=dict(type="str",
                           choices=["enable", "disable"],
                           aliases=["enable_interface"],
                           required=False),
                controller=dict(type="str", required=True, choices=["A", "B"]),
                name=dict(type="str", aliases=["port", "iface"]),
                channel=dict(type="int"),
                address=dict(type="str", required=False),
                subnet_mask=dict(type="str", required=False),
                gateway=dict(type="str", required=False),
                config_method=dict(type="str",
                                   required=False,
                                   choices=["dhcp", "static"]),
                dns_config_method=dict(type="str",
                                       required=False,
                                       choices=["dhcp", "static"]),
                dns_address=dict(type="str", required=False),
                dns_address_backup=dict(type="str", required=False),
                ntp_config_method=dict(type="str",
                                       required=False,
                                       choices=["disable", "dhcp", "static"]),
                ntp_address=dict(type="str", required=False),
                ntp_address_backup=dict(type="str", required=False),
                ssh=dict(type="bool", required=False),
                log_path=dict(type="str", required=False),
            ))

        required_if = [
            ["state", "enable", ["config_method"]],
            ["config_method", "static", ["address", "subnet_mask"]],
            ["dns_config_method", "static", ["dns_address"]],
            ["ntp_config_method", "static", ["ntp_address"]],
        ]

        mutually_exclusive = [
            ["name", "channel"],
        ]

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

        self.controller = args["controller"]
        self.name = args["name"]
        self.channel = args["channel"]

        self.config_method = args["config_method"]
        self.address = args["address"]
        self.subnet_mask = args["subnet_mask"]
        self.gateway = args["gateway"]
        self.enable_interface = None if args["state"] is None else args[
            "state"] == "enable"

        self.dns_config_method = args["dns_config_method"]
        self.dns_address = args["dns_address"]
        self.dns_address_backup = args["dns_address_backup"]

        self.ntp_config_method = args["ntp_config_method"]
        self.ntp_address = args["ntp_address"]
        self.ntp_address_backup = args["ntp_address_backup"]

        self.ssh = args["ssh"]

        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.retries = 0

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

        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 += '/'
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                state=dict(type='str',
                           required=False,
                           default='enabled',
                           choices=['enabled', 'disabled']),
                server=dict(
                    type='str',
                    required=False,
                ),
                sender=dict(
                    type='str',
                    required=False,
                ),
                contact=dict(
                    type='str',
                    required=False,
                ),
                recipients=dict(
                    type='list',
                    required=False,
                ),
                test=dict(
                    type='bool',
                    required=False,
                    default=False,
                ),
                log_path=dict(type='str', required=False),
            ))

        required_if = [[
            'state', 'enabled', ['server', 'sender', 'recipients']
        ]]

        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True,
                                    required_if=required_if)
        args = self.module.params
        self.alerts = args['state'] == 'enabled'
        self.server = args['server']
        self.sender = args['sender']
        self.contact = args['contact']
        self.recipients = args['recipients']
        self.test = args['test']

        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

        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 += '/'

        # Very basic validation on email addresses: [email protected]
        email = re.compile(r"[^@]+@[^@]+\.[^@]+")

        if self.sender and not email.match(self.sender):
            self.module.fail_json(
                msg="The sender (%s) provided is not a valid email address." %
                self.sender)

        if self.recipients is not None:
            for recipient in self.recipients:
                if not email.match(recipient):
                    self.module.fail_json(
                        msg=
                        "The recipient (%s) provided is not a valid email address."
                        % recipient)

            if len(self.recipients) < 1:
                self.module.fail_json(
                    msg="At least one recipient address must be specified.")
Example #9
0
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                state=dict(type='str',
                           default='present',
                           choices=['absent', 'present']),
                group=dict(type='str', required=False, aliases=['cluster']),
                ports=dict(type='list', required=False),
                force_port=dict(type='bool', default=False),
                name=dict(type='str', required=True, aliases=['label']),
                host_type=dict(type='str', aliases=['host_type_index']),
                log_path=dict(type='str', required=False),
            ))

        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True)
        self.check_mode = self.module.check_mode
        args = self.module.params
        self.group = args['group']
        self.ports = args['ports']
        self.force_port = args['force_port']
        self.name = args['name']
        self.state = args['state']
        self.ssid = args['ssid']
        self.url = args['api_url']
        self.user = args['api_username']
        self.pwd = args['api_password']
        self.certs = args['validate_certs']

        self.post_body = dict()
        self.all_hosts = list()
        self.host_obj = dict()
        self.newPorts = list()
        self.portsForUpdate = list()
        self.portsForRemoval = list()

        # Update host type with the corresponding index
        host_type = args['host_type_index']
        if host_type:
            host_type = host_type.lower()
            if host_type in [
                    key.lower() for key in list(self.HOST_TYPE_INDEXES.keys())
            ]:
                self.host_type_index = self.HOST_TYPE_INDEXES[host_type]
            elif host_type.isdigit():
                self.host_type_index = int(args['host_type_index'])
            else:
                self.module.fail_json(
                    msg=
                    "host_type must be either a host type name or host type index found integer"
                    " the documentation.")

        # logging setup
        self._logger = logging.getLogger(self.__class__.__name__)
        if args['log_path']:
            logging.basicConfig(
                level=logging.DEBUG,
                filename=args['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 += '/'

        # Ensure when state==present then host_type_index is defined
        if self.state == "present" and self.host_type_index is None:
            self.module.fail_json(
                msg=
                "Host_type_index is required when state=='present'. Array Id: [%s]"
                % self.ssid)

        # Fix port representation if they are provided with colons
        if self.ports is not None:
            for port in self.ports:
                port['label'] = port['label'].lower()
                port['type'] = port['type'].lower()
                port['port'] = port['port'].lower()

                # Determine whether address is 16-byte WWPN and, if so, remove
                if re.match(r'^(0x)?[0-9a-f]{16}$',
                            port['port'].replace(':', '')):
                    port['port'] = port['port'].replace(':',
                                                        '').replace('0x', '')
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                controller=dict(type='str', required=True, choices=['A', 'B']),
                name=dict(type='int', aliases=['channel']),
                state=dict(type='str',
                           required=False,
                           default='enabled',
                           choices=['enabled', 'disabled']),
                address=dict(type='str', required=False),
                subnet_mask=dict(type='str', required=False),
                gateway=dict(type='str', required=False),
                config_method=dict(type='str',
                                   required=False,
                                   default='dhcp',
                                   choices=['dhcp', 'static']),
                mtu=dict(type='int',
                         default=1500,
                         required=False,
                         aliases=['max_frame_size']),
                log_path=dict(type='str', required=False),
            ))

        required_if = [
            ["config_method", "static", ["address", "subnet_mask"]],
        ]

        self.module = AnsibleModule(
            argument_spec=argument_spec,
            supports_check_mode=True,
            required_if=required_if,
        )
        args = self.module.params
        self.controller = args['controller']
        self.name = args['name']
        self.mtu = args['mtu']
        self.state = args['state']
        self.address = args['address']
        self.subnet_mask = args['subnet_mask']
        self.gateway = args['gateway']
        self.config_method = args['config_method']

        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.mtu < 1500 or self.mtu > 9000:
            self.module.fail_json(
                msg=
                "The provided mtu is invalid, it must be > 1500 and < 9000 bytes."
            )

        if self.config_method == 'dhcp' and any(
            [self.address, self.subnet_mask, self.gateway]):
            self.module.fail_json(
                msg=
                'A config_method of dhcp is mutually exclusive with the address,'
                ' subnet_mask, and gateway options.')

        # A relatively primitive regex to validate that the input is formatted like a valid ip address
        address_regex = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')

        if self.address and not address_regex.match(self.address):
            self.module.fail_json(
                msg="An invalid ip address was provided for address.")

        if self.subnet_mask and not address_regex.match(self.subnet_mask):
            self.module.fail_json(
                msg="An invalid ip address was provided for subnet_mask.")

        if self.gateway and not address_regex.match(self.gateway):
            self.module.fail_json(
                msg="An invalid ip address was provided for gateway.")
Example #11
0
def main():
    argument_spec = eseries_host_argument_spec()
    argument_spec.update(
        dict(name=dict(required=True, type='str'),
             new_name=dict(required=False, type='str'),
             secondaryArrayId=dict(required=True, type='str'),
             syncIntervalMinutes=dict(required=False, default=10, type='int'),
             manualSync=dict(required=False, default=False, type='bool'),
             recoveryWarnThresholdMinutes=dict(required=False,
                                               default=20,
                                               type='int'),
             repoUtilizationWarnThreshold=dict(required=False,
                                               default=80,
                                               type='int'),
             interfaceType=dict(required=False,
                                choices=['fibre', 'iscsi'],
                                type='str'),
             state=dict(required=True, choices=['present', 'absent']),
             syncWarnThresholdMinutes=dict(required=False,
                                           default=10,
                                           type='int')))

    module = AnsibleModule(argument_spec=argument_spec)

    p = module.params

    ssid = p.pop('ssid')
    api_url = p.pop('api_url')
    user = p.pop('api_username')
    pwd = p.pop('api_password')
    new_name = p.pop('new_name')
    state = p.pop('state')

    if not api_url.endswith('/'):
        api_url += '/'

    name_exists, spec_matches, api_data, async_id = has_match(
        module, ssid, api_url, pwd, user, p)

    if state == 'present':
        if name_exists and spec_matches:
            module.exit_json(changed=False,
                             msg="Desired state met",
                             **api_data)
        elif name_exists and not spec_matches:
            results = update_async(module, ssid, api_url, pwd, user, p,
                                   new_name, async_id)
            module.exit_json(changed=True,
                             msg="Async mirror group updated",
                             async_id=async_id,
                             **results)
        elif not name_exists:
            results = create_async(module, ssid, api_url, user, pwd, p)
            module.exit_json(changed=True, **results)

    elif state == 'absent':
        if name_exists:
            remove_amg(module, ssid, api_url, pwd, user, async_id)
            module.exit_json(changed=True,
                             msg="Async mirror group removed.",
                             async_id=async_id)
        else:
            module.exit_json(changed=False,
                             msg="Async Mirror group: %s already absent" %
                             p['name'])
    def __init__(self):
        argument_spec = eseries_host_argument_spec()
        argument_spec.update(
            dict(
                state=dict(choices=["present", "absent"],
                           required=False,
                           default="present"),
                address=dict(type="str", required=False),
                port=dict(type="int", default=514, required=False),
                protocol=dict(choices=["tcp", "tls", "udp"],
                              default="udp",
                              required=False),
                components=dict(type="list",
                                required=False,
                                default=["auditLog"]),
                test=dict(type="bool", default=False, require=False),
                log_path=dict(type="str", required=False),
            ))

        required_if = [
            [
                "state", "present",
                ["address", "port", "protocol", "components"]
            ],
        ]

        mutually_exclusive = [
            ["test", "absent"],
        ]

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

        self.syslog = args["state"] in ["present"]
        self.address = args["address"]
        self.port = args["port"]
        self.protocol = args["protocol"]
        self.components = args["components"]
        self.test = args["test"]
        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.components.sort()

        self.check_mode = self.module.check_mode

        # logging setup
        log_path = args["log_path"]
        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 += '/'