def get_sempv2_version_map_key(self, semp_version):
     if semp_version <= SolaceUtils.create_version("2.13"):
         return '<=2.13'
     elif semp_version >= SolaceUtils.create_version("2.14"):
         return '>=2.14'
     raise SolaceInternalError(
         f"sempv2_version: {semp_version} not supported")
Exemple #2
0
 def __init__(self, module: AnsibleModule):
     SolaceUtils.module_fail_on_import_error(
         module, SOLACE_API_HAS_IMPORT_ERROR,
         SOLACE_API_IMPORT_ERR_TRACEBACK)
     self.module = module
     self.safe_for_path_array = None
     return
 def _update_func_sempv1(self, ldap_profile_name, settings, delta_settings,
                         op):
     if not settings:
         return None
     combined_resps = {}
     # iterate over settings.keys and send 1 update after the other
     for key, val in settings.items():
         if val:
             if key == 'search' and isinstance(val, dict):
                 # iterate through sarch
                 for skey, sval in val.items():
                     _resp = self._send_sempv1_update(
                         ldap_profile_name, key, {skey: sval}, op)
                     _call_log = {
                         self.sempv1_api.getNextCallKey(): {
                             key: {
                                 skey: sval,
                                 'response': _resp
                             }
                         }
                     }
                     combined_resps = SolaceUtils.merge_dicts_recursive(
                         combined_resps, _call_log)
             else:
                 _resp = self._send_sempv1_update(ldap_profile_name, key,
                                                  val, op)
                 _call_log = {
                     self.sempv1_api.getNextCallKey(): {
                         key: val,
                         'response': _resp
                     }
                 }
                 combined_resps = SolaceUtils.merge_dicts_recursive(
                     combined_resps, _call_log)
     return combined_resps
Exemple #4
0
 def __init__(self, module: AnsibleModule):
     SolaceUtils.module_fail_on_import_error(
         module, SOLACE_TASK_HAS_IMPORT_ERROR, SOLACE_TASK_ERR_TRACEBACK)
     self.module = module
     self.changed = False
     self.result = SolaceUtils.create_result()
     return
Exemple #5
0
 def normalize_new_settings(self, new_settings) -> dict:
     # solace cloud and self-hosted broker return the same types
     if new_settings:
         SolaceUtils.type_conversion(new_settings, False)
         if self.get_config().is_solace_cloud():
             new_settings = self._normalize_new_settings_solace_cloud(
                 new_settings)
     return new_settings
Exemple #6
0
 def get_sempv2_version(self, config: SolaceTaskBrokerConfig):
     resp = self.make_get_request(config,
                                  [SolaceSempV2Api.API_BASE_SEMPV2_CONFIG] +
                                  ["about", "api"],
                                  query_params=None)
     raw_api_version = SolaceUtils.get_key(resp, "sempVersion")
     # format: 2.21
     try:
         v = SolaceUtils.create_version(raw_api_version)
     except SolaceInternalError as e:
         raise SolaceInternalError(
             f"sempv2 version parsing failed: {raw_api_version}") from e
     return raw_api_version, v
Exemple #7
0
 def get_sempv1_version(self, config: SolaceTaskBrokerConfig):
     rpc_xml = "<rpc><show><service></service></show></rpc>"
     resp = self.make_post_request(config, rpc_xml,
                                   SolaceTaskOps.OP_READ_SEMP_VERSION)
     rpc_reply = resp['rpc-reply']
     raw_api_version = SolaceUtils.get_key(rpc_reply, "@semp-version")
     # format: soltr/9_9VMR
     s = raw_api_version[6:9].replace('_', '.')
     try:
         v = SolaceUtils.create_version(s)
     except SolaceInternalError as e:
         raise SolaceInternalError(
             f"sempv1 version parsing failed: {raw_api_version}") from e
     return raw_api_version, v
Exemple #8
0
 def get_remoteFormattedHostInventory(
         self,
         solace_cloud_service_facts: SolaceCloudBrokerFacts,
         search_dict: dict,
         remote_host_inventory: dict,
         remote_host_inventory_hostname: str,
         host_entry: str,
         api_token: str = None,
         meta: dict = None):
     remote_host_inventory_params = solace_cloud_service_facts.get_field(
         remote_host_inventory, remote_host_inventory_hostname)
     if not remote_host_inventory_params:
         raise SolaceParamsValidationError(
             "remote_host_inventory_hostname",
             remote_host_inventory_hostname,
             f"not found in remote_host_inventory: {remote_host_inventory}")
     _field, broker_inventory = self.get_formattedHostInventory(
         solace_cloud_service_facts, search_dict, host_entry, api_token,
         meta)
     del broker_inventory['all']['hosts'][host_entry]['ansible_connection']
     remote_inventory = {
         'all': {
             'hosts': {
                 host_entry: remote_host_inventory_params
             }
         }
     }
     inventory = SolaceUtils.merge_dicts_recursive(remote_inventory,
                                                   broker_inventory)
     return 'remoteFormattedHostInventory', inventory
 def update_func(self, vpn_name, replay_log_name, settings=None, delta_settings=None):
     # PATCH /msgVpns/{msgVpnName}/replayLogs/{replayLogName}
     # solace cloud complains about using the exact types
     converted_settings = SolaceUtils.deep_dict_convert_strs_to_types(
         settings)
     path_array = [SolaceSempV2Api.API_BASE_SEMPV2_CONFIG,
                   'msgVpns', vpn_name, 'replayLogs', replay_log_name]
     return self.sempv2_api.make_patch_request(self.get_config(), path_array, converted_settings)
 def check_min_sempv1_supported_version(self):
     min_sempv1_version = SolaceUtils.create_version(
         self.MIN_SEMP_V1_VERSION)
     raw_api_version, version = self.sempv1_api.get_sempv1_version(
         self.get_config())
     if version < min_sempv1_version:
         raise SolaceSempv1VersionNotSupportedError(
             self.get_module()._name, f"{version}({raw_api_version})",
             min_sempv1_version)
Exemple #11
0
 def assert_min_sempv2_version_supported(self):
     if self.MIN_SEMP_V2_VERSION_STR is not None:
         sempv2_api = SolaceSempV2Api(self.get_module())
         _version_str, version = sempv2_api.get_sempv2_version(
             self.get_config())
         min_sempv2_version = SolaceUtils.create_version(
             self.MIN_SEMP_V2_VERSION_STR)
         if version < min_sempv2_version:
             raise SolaceMinSempv2VersionSupportedError(
                 self.get_module()._name, f"{version}", min_sempv2_version)
 def validate_params(self):
     params = self.get_module().params
     name = params.get('name', None)
     if self.get_config().is_solace_cloud() and name != 'default':
         raise SolaceParamsValidationError(
             'name', name,
             "ldap profile name for Solace Cloud must be 'default'.")
     invalid_chars = '-'
     if SolaceUtils.stringContainsAnyChars(name, invalid_chars):
         raise SolaceParamsValidationError(
             'name', name,
             f"contains 1 or more invalid chars from set: '{invalid_chars}'"
         )
 def _send_sempv1_update(self, ldap_profile_name, key, val, op):
     _rpc_update_dict = {'authentication': {'ldap-profile': {key: val}}}
     _rpc_dict = {
         'authentication': {
             'ldap-profile': {
                 'profile-name': ldap_profile_name
             }
         }
     }
     rpc_dict = SolaceUtils.merge_dicts_recursive(_rpc_dict,
                                                  _rpc_update_dict)
     return self.sempv1_api.make_post_request(
         self.get_config(),
         self.sempv1_api.convertDict2Sempv1RpcXmlString(rpc_dict), op)
Exemple #14
0
 def do_task(self):
     self.validate_params()
     args = self.get_args()
     new_settings = self.get_new_settings()
     _current_settings = self.get_func(*args)
     current_settings = self.normalize_current_settings(_current_settings,
                                                        new_settings)
     new_state = self.get_module().params['state']
     # delete if exists
     if new_state == 'absent':
         if current_settings is None:
             return None, self.create_result(rc=0, changed=False)
         result = self.create_result(rc=0, changed=True)
         if not self.get_module().check_mode:
             result['response'] = self.delete_func(*args)
         return None, result
     # create if not exist
     if new_state == 'present' and current_settings is None:
         result = self.create_result(rc=0, changed=True)
         if not self.get_module().check_mode:
             args.append(new_settings)
             result['response'] = self.create_func(*args)
         return None, result
     # update if any changes
     if new_state == 'present' and current_settings is not None:
         update_settings = None
         if new_settings is not None:
             update_settings = SolaceUtils.deep_dict_diff(
                 new_settings, current_settings)
         if not update_settings:
             result = self.create_result(rc=0, changed=False)
             result['response'] = current_settings
             return None, result
         if update_settings:
             result = self.create_result(rc=0, changed=True)
             if not self.get_module().check_mode:
                 # sending all settings to update ==> no missing together or required check necessary
                 args.append(new_settings)
                 args.append(update_settings)
                 result['response'] = self.update_func(*args)
         return None, result
     return self.do_task_extension(args, new_state, new_settings, current_settings)
Exemple #15
0
 def log_http_roundtrip(resp):
     if not solace_sys.ENABLE_LOGGING:
         return
     request_body = SolaceApi.get_http_request_body(resp)
     resp_body = SolaceUtils.parse_response_text(resp.text)
     log = {
         'request': {
             'method': resp.request.method,
             'url': resp.request.url,
             'headers':
             SolaceApi._get_http_masked_headers(resp.request.headers),
             'body': request_body
         },
         'response': {
             'status_code': resp.status_code,
             'reason': resp.reason,
             'url': resp.url,
             'headers': dict(resp.headers),
             'body': resp_body
         }
     }
     logging.debug("\n%s", json.dumps(log, indent=2))
     return
 def __init__(self, module):
     SolaceUtils.module_fail_on_import_error(
         module, SOLACE_GET_AVAILABLE_HAS_IMPORT_ERROR,
         SOLACE_GET_AVAILABLE_ERR_TRACEBACK)
     super().__init__(module)
    def __init__(self, module: AnsibleModule):
        super().__init__(module)
        is_secure = module.params['secure_connection']
        host = module.params['host']
        port = module.params['port']
        self.broker_url = ('https' if is_secure else 'http') + \
            '://' + host + ':' + str(port)
        self.timeout = float(module.params['timeout'])
        self.validate_certs = bool(module.params['validate_certs'])
        self.x_broker = module.params.get('x_broker', None)
        solace_cloud_api_token = module.params.get('solace_cloud_api_token',
                                                   None)
        solace_cloud_service_id = module.params.get('solace_cloud_service_id',
                                                    None)
        # either both are provided or none
        ok = ((solace_cloud_api_token and solace_cloud_service_id)
              or (not solace_cloud_api_token and not solace_cloud_service_id))
        if not ok:
            result = SolaceUtils.create_result(rc=1)
            msg = f"must provide either both or none for Solace Cloud: solace_cloud_api_token={solace_cloud_api_token}, solace_cloud_service_id={solace_cloud_service_id}."
            module.fail_json(msg=msg, **result)
        if ok and solace_cloud_api_token and solace_cloud_service_id:
            self.solace_cloud_config = dict(api_token=solace_cloud_api_token,
                                            service_id=solace_cloud_service_id)
        else:
            self.solace_cloud_config = None

        self.solace_cloud_auth = None
        if self.solace_cloud_config is not None:
            self.solace_cloud_auth = BearerAuth(
                self.solace_cloud_config['api_token'])

        self.semp_auth = (module.params['username'], module.params['password'])

        # reverse proxy
        self.reverse_proxy = module.params.get('reverse_proxy', None)
        if self.reverse_proxy:
            if self.solace_cloud_config:
                result = SolaceUtils.create_result(rc=1)
                msg = "No support for reverse proxy for Solace Cloud, remove 'reverse_proxy' from module arguments."
                module.fail_json(msg=msg, **result)
            semp_base_path = self.reverse_proxy.get('semp_base_path', None)
            if semp_base_path:
                self.broker_url += '/' + semp_base_path
            use_basic_auth = self.reverse_proxy.get('use_basic_auth', False)
            if not use_basic_auth:
                self.semp_auth = None
            _reverse_proxy_headers = self.reverse_proxy.get('headers', None)
            if _reverse_proxy_headers:
                _reverse_proxy_headers_include_x_asc_module = _reverse_proxy_headers.get(
                    'x-asc-module', False)
                if not isinstance(_reverse_proxy_headers_include_x_asc_module,
                                  bool):
                    result = SolaceUtils.create_result(rc=1)
                    msg = f"argument: 'reverse_proxy.headers.x-asc-module={_reverse_proxy_headers_include_x_asc_module}, is not of type 'bool'; use True/False or yes/no"
                    module.fail_json(msg=msg, **result)
                _reverse_proxy_headers_include_x_asc_module_op = _reverse_proxy_headers.get(
                    'x-asc-module-op', False)
                if not isinstance(
                        _reverse_proxy_headers_include_x_asc_module_op, bool):
                    result = SolaceUtils.create_result(rc=1)
                    msg = f"argument: 'reverse_proxy.headers.x-asc-module-op={_reverse_proxy_headers_include_x_asc_module_op}, is not of type 'bool'; use True/False or yes/no"
                    module.fail_json(msg=msg, **result)
                self.reverse_proxy['headers'][
                    'x-asc-module'] = _reverse_proxy_headers_include_x_asc_module
                self.reverse_proxy['headers'][
                    'x-asc-module-op'] = _reverse_proxy_headers_include_x_asc_module_op
        return
Exemple #18
0
 def convertDict2Sempv1RpcXmlString(self, d) -> str:
     rpc_elem = SolaceUtils.convertDict2XmlElem('rpc', d)
     return ET.tostring(rpc_elem, encoding='utf-8').decode('utf-8')
Exemple #19
0
 def handle_bad_response(self, resp, module_op):
     _resp = dict(status_code=resp.status_code, reason=resp.reason)
     _resp.update({'body': SolaceUtils.parse_response_text(resp.text)})
     raise SolaceApiError(resp, _resp, self.get_module()._name, module_op)
 def validate_params(self):
     topic = self.get_module().params['name']
     if SolaceUtils.doesStringContainAnyWhitespaces(topic):
         raise SolaceParamsValidationError(
             'topic', topic, "must not contain any whitespace")
     return super().validate_params()
Exemple #21
0
 def normalize_new_settings(self, new_settings) -> dict:
     if new_settings:
         SolaceUtils.type_conversion(new_settings, False)
     return new_settings
Exemple #22
0
 def handle_bad_response(self, resp, module_op):
     _resp = dict(status_code=resp.status_code,
                  reason=resp.reason if resp.reason else None)
     if resp.text:
         _resp.update(dict(body=SolaceUtils.parse_response_text(resp.text)))
     raise SolaceApiError(resp, _resp, self.get_module()._name, module_op)
Exemple #23
0
 def normalize_new_settings(self, new_settings) -> dict:
     if new_settings:
         SolaceUtils.type_conversion(new_settings,
                                     self.get_config().is_solace_cloud())
     return new_settings
Exemple #24
0
 def _remove_solace_cloud_keys(self, settings):
     _settings = SolaceUtils.deep_copy(settings)
     for key in self.SOLACE_CLOUD_SETTINGS.keys():
         _settings.pop(key, None)
     return _settings
Exemple #25
0
 def create_result(self, rc=0, changed=False) -> dict:
     return SolaceUtils.create_result(rc, changed)
Exemple #26
0
 def validate_key(self, key):
     if SolaceUtils.doesStringContainAnyWhitespaces(key):
         raise SolaceParamsValidationError(
             'name', key, "must not contain any whitespace")