def _create_project(module, api_instance): if module.params["conftest"]["enabled"]: rego_test(module) project_config = { "name": module.params["name"], "key": module.params["project_key"], } if module.params["environments"]: environments = [] for env in module.params["environments"]: environments.append(env) project_config["environments"] = environments if module.params["tags"] and module.params["tags"] is not None: project_config["tags"] = module.params["tags"] # if module.params['include_in_snippet_by_default'] and module.params['include_in_snippet_by_default'] is not None: # project_config['include_in_snippet_by_default'] = module.params['include_in_snippet_by_default'] project_body = launchdarkly_api.ProjectBody(**project_config) try: response, status, headers = api_instance.post_project_with_http_info( project_body=project_body) module.exit_json(changed=True, content=response.to_dict()) except ApiException as e: fail_exit(module, e)
def _fetch_flags(module, api_instance): try: if module.params.get("key"): if module.params.get("env"): response = api_instance.get_feature_flag( module.params["project_key"], module.params["key"], env=module.params["env"], ) else: response = api_instance.get_feature_flag( module.params["project_key"], module.params["key"] ) else: keys = ["project_key", "env", "summary", "archived", "tag"] filtered_keys = dict( (k, module.params[k]) for k in keys if k in module.params and module.params[k] is not None ) response = api_instance.get_feature_flags(**filtered_keys) return response.to_dict() except launchdarkly_api.rest.ApiException as e: if e.status == 404: return None else: fail_exit(module, e)
def _create_user_segment(module, api_instance): if module.params["conftest"]["enabled"]: rego_test(module) name = (module.params["name"] if module.params["name"] is not None else module.params["user_segment_key"]) user_segment_config = { "name": name, "key": module.params["user_segment_key"] } user_segment_config["description"] = (module.params["description"] if module.params.get("description") else "") user_segment_config["tags"] = (module.params["tags"] if module.params.get("tags") else []) user_segment_body = launchdarkly_api.UserSegmentBody(**user_segment_config) try: api_response = api_instance.post_user_segment( module.params["project_key"], module.params["environment_key"], user_segment_body, ) except ApiException as e: fail_exit(module, e) _configure_user_segment(module, api_instance, api_response, True)
def _delete_user_segment(module, api_instance): try: api_instance.delete_user_segment( module.params["project_key"], module.params["environment_key"], module.params["user_segment_key"], ) module.exit_json(changed=True, msg="successfully deleted user segment") except ApiException as e: fail_exit(module, e)
def _delete_flag(module, api_instance): feature_flag_config = { "project_key": module.params["project_key"], "feature_flag_key": module.params["key"], } try: api_response = api_instance.delete_feature_flag(**feature_flag_config) module.exit_json(changed=True, msg="feature flag deleted") except ApiException as e: fail_exit(module, e)
def _fetch_projects(module, api_instance): try: if module.params.get("project_key"): response = api_instance.get_project( module.params["project_key"]).to_dict() else: get_projects = api_instance.get_projects() projects = [proj.to_dict() for proj in get_projects.items] final_projects = [] if module.params.get("tags"): filter_projects = [ d for d in projects if len(set(d["tags"]).intersection(module.params["tags"])) ] if module.params.get("environment_tags"): try: filter_projects except NameError: filter_projects = None if filter_projects: env_projects = filter_projects else: env_projects = projects for i, proj in enumerate(env_projects): filtered_environments = [] for env in proj["environments"]: if module.params.get("environment_tags") and set( env["tags"]).intersection( module.params["environment_tags"]): filtered_environments.append(env) elif module.params.get("environment_tags"): continue else: filtered_environments = env env_projects[i]["environments"] = filtered_environments final_projects = env_projects else: final_projects = filter_projects get_projects = [ d for d in final_projects if len(d["environments"]) > 0 ] response = get_projects return response except launchdarkly_api.rest.ApiException as e: if e.status == 404: return None else: fail_exit(module, e)
def _configure_webhook(module, api_instance, webhook=None): patches = [] if webhook: if webhook.name == module.params["name"] or module.params["name"] is None: del module.params["name"] if webhook.url == module.params["url"] or module.params["url"] is None: del module.params["url"] if set(webhook.tags) == set(module.params["tags"]): del module.params["tags"] # Loop over statements comparing if module.params["statements"] is not None: if len(module.params["statements"]) < len(webhook.statements): oldStatements = len(webhook.statements) - 1 newStatements = len(module.params["statements"]) newIndex = newStatements - 1 i = 0 if newIndex < oldStatements: # iterating over statements for range to be inclusive for i in range(newStatements, len(webhook.statements)): patches.append( launchdarkly_api.PatchOperation( op="remove", path="/statements/%d" % i, value="needed_for_call", ) ) for idx, statement in enumerate(module.params["statements"]): if idx > len(webhook.statements) - 1: tmp_results = ["break"] break tmp_results = diff(statement, webhook.statements[idx]) statement_results = list(tmp_results) if len(statement_results) == 0: del module.params["statements"] for key in module.params: if key not in ["state", "api_key", "sign", "webhook_id"]: if module.params[key] is not None: patches.append(_parse_webhook_param(module, key)) if len(patches) > 0: try: api_response = api_instance.patch_webhook( module.params["webhook_id"], patch_delta=patches ) except ApiException as e: if e.status == 404: module.exit_json(failed=True, msg="webhook id not found") else: fail_exit(module, e) module.exit_json( msg="webhook successfully configured", webhook=api_response.to_dict() )
def _fetch_flag(module, api_instance): try: response = api_instance.get_feature_flag(module.params["project_key"], module.params["key"]) return response except ApiException as e: if e.status == 404: return None else: fail_exit(module, e) return None
def _delete_environment(module, api_instance): try: response, status, headers = api_instance.delete_environment_with_http_info( module.params["project_key"], module.params["environment_key"]) if status != 204: module.exit_json(failed=True, msg="Failed to delete enviroment status: %d" % status) module.exit_json(msg="successfully deleted environment") except ApiException as e: fail_exit(module, e)
def _fetch_project(module, api_instance): try: # Get an environment given a project and key. project = api_instance.get_project(module.params["project_key"]) return project except ApiException as e: if e.status == 404: return False else: fail_exit(module, e) return False
def _fetch_webhook(module, api_instance): if module.params["webhook_id"] is not None: try: # Get a webhook given an id. webhook = api_instance.get_webhook(module.params["webhook_id"]) return webhook except ApiException as e: if e.status == 404: return False else: fail_exit(module, e) else: return False
def _configure_environment(module, api_instance, environment=None): changed = False patches = [] if environment: if environment.name == module.params["name"]: del module.params["name"] if environment.color == module.params["color"]: del module.params["color"] if (environment.default_ttl == module.params["default_ttl"] or module.params["default_ttl"] is None): del module.params["default_ttl"] if environment.secure_mode == module.params["secure_mode"]: del module.params["secure_mode"] if environment.default_track_events == module.params[ "default_track_events"]: del module.params["default_track_events"] if set(environment.tags) == set(module.params["tags"]): del module.params["tags"] if environment.confirm_changes == module.params["confirm_changes"]: del module.params["confirm_changes"] if environment.require_comments == module.params["require_comments"]: del module.params["require_comments"] if len(module.params.keys()) <= 4: module.exit_json(changed=False, msg="environment unchanged") for key in module.params: if (key not in [ "state", "api_key", "environment_key", "project_key", "conftest" ] and module.params[key] is not None): patches.append(parse_env_param(module.params, key)) if len(patches) > 0: try: api_response = api_instance.patch_environment( module.params["project_key"], module.params["environment_key"], patch_delta=patches, ) except ApiException as e: fail_exit(module, e) module.exit_json( changed=True, msg="environment successfully configured", environment=api_response.to_dict(), ) module.exit_json(changed=False, msg="environment unchanged", environment=environment.to_dict())
def _fetch_user_segment(module, api_instance): try: # Get a user segment given a project, environment, and user_segment_key. user_segment = api_instance.get_user_segment( module.params["project_key"], module.params["environment_key"], module.params["user_segment_key"], ) return user_segment except ApiException as e: if e.status == 404: return False else: fail_exit(module, e) return False
def _fetch_feature_flag(module, api_instance): try: # Get an environment given a project and key. feature_flag = api_instance.get_feature_flag( module.params["project_key"], module.params["flag_key"], env=module.params["environment_key"], ) return feature_flag.environments[module.params["environment_key"]] except ApiException as e: if e.status == 404: raise AnsibleError( "Flag: %s does not exist in Project: %s" % (module.params["flag_key"], module.params["project_key"]) ) fail_exit(module, e)
def _create_flag(module, api_instance): # Variations can only be set at time of flag creation. if module.params["conftest"]["enabled"]: validate_params(module) if module.params["kind"] == "bool": variations = [ launchdarkly_api.Variation(value=True), launchdarkly_api.Variation(value=False), ] elif module.params["kind"] == "json": # No easy way to check isinstance json variations = _build_variations(module) elif module.params["kind"] == "str": if not all( isinstance(item, string_types) for item in module.params["variations"]): module.exit_json(msg="Variations need to all be strings") variations = _build_variations(module) elif module.params["kind"] == "number": if not all( isinstance(item, int) for item in module.params["variations"]): module.exit_json(msg="Variations need to all be integers") variations = _build_variations(module) feature_flag_config = { "key": module.params["key"], "variations": variations, "temporary": module.params["temporary"], "name": module.params["name"], } try: response, status, headers = api_instance.post_feature_flag_with_http_info( module.params["project_key"], feature_flag_config) except ApiException as e: err = json.loads(str(e.body)) if err["code"] == "key_exists": module.exit_json(msg="error: Key already exists") else: fail_exit(module, e) _configure_flag(module, api_instance, response) module.exit_json(msg="flag successfully created", content=api_response.to_dict())
def _configure_flag_sync(module, api_instance): results = [] max_targets = len(module.params["environment_targets"]) - 1 for idx, env in enumerate(module.params["environment_targets"]): source = {"key": module.params["environment_key"]} target = {"key": env} feature_flag_copy_body = {"source": source, "target": target} if module.params["included_actions"] is not None: feature_flag_copy_body["included_actions"] = module.params[ "included_actions"] if module.params["excluded_actions"] is not None: feature_flag_copy_body["excluded_actions"] = module.params[ "excluded_actions"] try: response, status, headers = api_instance.copy_feature_flag_with_http_info( module.params["project_key"], module.params["flag_key"], launchdarkly_api.FeatureFlagCopyBody(**feature_flag_copy_body), ) if idx == max_targets: # LD Returns a FeatureFlag Object containing all Environments. Only need last one. feature_flag = response.to_dict() except ApiException as e: if e.status == 429: time.sleep(reset_rate(e.headers["X-RateLimit-Reset"])) api_instance.copy_feature_flag_with_http_info( module.params["project_key"], module.params["flag_key"], launchdarkly_api.FeatureFlagCopyBody( **feature_flag_copy_body), ) else: fail_exit(module, e) module.exit_json(changed=True, msg="feature flags synced", feature_flag=feature_flag)
def _configure_project(module, api_instance, project=None, changed=False): if module.params["conftest"]["enabled"]: rego_test(module) patches = [] if project: if module.params["tags"] is None or set(project.tags) == set( module.params["tags"]): del module.params["tags"] if project.name == module.params["name"]: del module.params["name"] # Uncomment when attribute is added to project response # if project.include_in_snippet_by_default == module.params['include_in_snippet_by_default']: # del module.parmas['include_in_snippet_by_default'] for key in module.params: if module.params.get(key) and key not in [ "state", "api_key", "environments", "project_key", "conftest", ]: patches.append(_parse_project_param(module, key)) if len(patches) > 0: try: response, status, headers = api_instance.patch_project_with_http_info( module.params["project_key"], patch_delta=patches) changed = True except ApiException as e: fail_exit(module, e) try: response except NameError: response = project module.exit_json( changed=changed, msg="project successfully configured", content=response.to_dict(), )
def _create_webhook(module, api_instance): if module.params["state"] == "enabled": webhook_status = True else: webhook_status = False webhook_config = { "url": module.params["url"], "sign": module.params["sign"], "on": webhook_status, } if module.params.get("secret"): webhook_config["secret"] = module.params["secret"] webhook_config["name"] = ( module.params["name"] if module.params.get("name") else module.params["url"] ) if module.params["tags"]: webhook_config["tags"] = module.params["tags"] if module.params["statements"]: filtered_statements = [] for statement in module.params["statements"]: filtered_statements.append( dict( (launchdarkly_api.Statement.attribute_map[k], v) for k, v in statement.items() if v is not None ) ) webhook_config["statements"] = filtered_statements webhook_body = launchdarkly_api.WebhookBody(**webhook_config) try: api_response = api_instance.post_webhook(webhook_body) module.params["webhook_id"] = api_response.id except ApiException as e: fail_exit(module, e) module.exit_json( changed=True, msg="webhook created", webhook=api_response.to_dict() )
def _configure_flag(module, api_instance, feature_flag=None): patches = configure_flag(module.params, feature_flag) if len(patches) == 0: module.exit_json(changed=False, msg="feature flag unchanged") if module.params["comment"]: comment = module.params["comment"] else: comment = "Ansible generated operation." comments = dict(comment=comment, patch=patches) try: response, status, headers = api_instance.patch_feature_flag_with_http_info( module.params["project_key"], module.params["key"], comments) module.exit_json(changed=True, msg="feature flag updated", content=response.to_dict()) except ApiException as e: fail_exit(module, e)
def main(): module = AnsibleModule( argument_spec=dict( api_key=dict( required=True, type="str", no_log=True, fallback=(env_fallback, ["LAUNCHDARKLY_ACCESS_TOKEN"]), ), env=dict(type="str"), project_key=dict(type="str", required=True), key=dict(type="str"), summary=dict(type="bool"), archived=dict(type="bool"), tag=dict(type="str"), ) ) if not HAS_LD: module.fail_json( msg=missing_required_lib("launchdarkly_api"), exception=LD_IMP_ERR ) # Set up API configuration = configure_instance(module.params["api_key"]) api_instance = launchdarkly_api.FeatureFlagsApi( launchdarkly_api.ApiClient(configuration) ) try: feature_flags = fetch_flags(module.params, api_instance) except launchdarkly_api.rest.ApiException as e: fail_exit(module, e) if feature_flags.get("items"): flags = feature_flags["items"] else: flags = feature_flags module.exit_json(changed=True, feature_flags=flags)
def _create_environment(module, api_instance): environment_config = { "name": module.params["name"], "key": module.params["environment_key"], "color": module.params["color"], } if module.params["default_ttl"]: environment_config["defaultTtl"] = module.params["default_ttl"] environment_body = launchdarkly_api.EnvironmentPost(**environment_config) try: _, status, _ = api_instance.post_environment_with_http_info( project_key=module.params["project_key"], environment_body=environment_body) if status != 201: module.exit_json(failed=True, msg="failed to create environment, status: %d" % status) except ApiException as e: fail_exit(module, e) _configure_environment(module, api_instance)
def _configure_custom_role(module, api_instance): patches = [] for key in module.params: if (key not in ["state", "api_key", "key", "conftest"] and module.params[key] is not None): patches.append(_parse_custom_role_param(module, key)) if len(patches) > 0: try: api_response = api_instance.patch_custom_role(module.params["key"], patch_delta=patches) except ApiException as e: if e.status == 404: module.exit_json(failed=True, msg="custom role: %s not found" % module["key"]) else: fail_exit(module, e) module.exit_json(changed=True, msg="successfully updated custom role: %s" % api_response.key) else: module.exit_json(changed=False, msg="custom role unchanged")
def _delete_project(module, api_instance): try: api_instance.delete_project(module.params["project_key"]) module.exit_json(msg="successfully deleted project") except ApiException as e: fail_exit(module, e)
def _project_sync( module, src_proj, dest_proj, dest_env_api, src_user_sgmt, dest_user_sgmt, src_fflags, dest_fflags, ): src_project = src_proj.get_project(module.params["project_key"]).to_dict() name = module.params.get("name", src_project["name"]) dest_proj_body = dict(name=name, key=module.params["project_key_dest"], tags=src_project["tags"]) patch_envs = [] # Build the Environments inside of Project Body if module.params["environments_copy"]: dest_proj_body["environments"] = [] for env in src_project["environments"]: dest_proj_body["environments"].append( dict( name=env["name"], key=env["key"], color=env["color"], default_ttl=env["default_ttl"], )) patch_env = dict(key=env["key"]) if env["tags"]: patch_env["tags"] = env["tags"] if env["secure_mode"] is not False: patch_env["secure_mode"] = env["secure_mode"] if env["default_track_events"] is not False: patch_env["default_track_events"] = env["default_track_events"] if env["require_comments"] is not False: patch_env["require_comments"] = env["require_comments"] if env["confirm_changes"] is not False: patch_env["confirm_changes"] = env["confirm_changes"] patch_envs.append(patch_env) ld_proj = launchdarkly_api.ProjectBody(**dest_proj_body) try: response, status, headers = dest_proj.post_project_with_http_info( project_body=ld_proj) except ApiException as e: fail_exit(module, e) # Project Environment Processing patches = [] for env in patch_envs: for key in env: if key not in ["key"] and env[key] is not None: patches.append(parse_env_param(env, key)) if len(patches) > 0: try: api_response = dest_env_api.patch_environment( module.params["project_key_dest"], env["key"], patch_delta=patches) except ApiException as e: if status == 429: time.sleep(reset_rate(headers["X-RateLimit-Reset"])) # Retry dest_env_api.patch_environment( module.params["project_key_dest"], env["key"], patch_delta=patches, ) else: fail_exit(module, e) # Reset patches patches = [] # User Segment Processing if module.params["environments_copy"]: for env in src_project["environments"]: get_segments = src_user_sgmt.get_user_segments( module.params["project_key"], env["key"]).to_dict() patch_sgmts = [] for segment in get_segments["items"]: new_segment_body = dict(key=segment["key"], name=segment["name"]) if segment["description"]: new_segment_body["description"] = segment["description"] if segment["tags"]: new_segment_body["tags"] = segment["tags"] try: dest_user_sgmt.post_user_segment( module.params["project_key_dest"], env["key"], new_segment_body) except ApiException as e: if status == 429: time.sleep(reset_rate(headers["X-RateLimit-Reset"])) # Retry dest_user_sgmt.post_user_segment( module.params["project_key_dest"], env["key"], new_segment_body, ) else: fail_exit(module, e) patch_sgmt = dict(key=segment["key"]) if segment["included"] is not None: patch_sgmt["included"] = segment["included"] if segment["excluded"] is not None: patch_sgmt["excluded"] = segment["excluded"] if segment["rules"] is not None: patch_sgmt["rules"] = segment["rules"] patch_sgmts.append(patch_sgmt) for sgmt in patch_sgmts: patches = [] for key in sgmt: if key not in ["key"] and len(sgmt[key]) > 0: if key == "rules": for rule in sgmt["rules"]: patch = dict( path="/rules/-", op="add", value=launchdarkly_api.UserSegmentRule( **rule), ) patches.append( launchdarkly_api.PatchOperation(**patch)) del patch else: patches.append(parse_user_param(sgmt, key)) if len(patches) > 0: try: ( response, status, headers, ) = dest_user_sgmt.patch_user_segment_with_http_info( module.params["project_key_dest"], env["key"], sgmt["key"], patch_only=patches, ) except ApiException as e: if status == 429: time.sleep(reset_rate( headers["X-RateLimit-Reset"])) # Retry dest_user_sgmt.patch_user_segment_with_http_info( module.params["project_key_dest"], env["key"], sgmt["key"], patch_only=patches, ) else: fail_exit(module, e) # Reset patches del patches tag = module.params.get("flag_tag", None) src_ff = {} try: if tag: tag = ",".join(tag) src_ff = src_fflags.get_feature_flags(module.params["project_key"], summary=0, tag=tag).to_dict() else: src_ff = src_fflags.get_feature_flags(module.params["project_key"], summary=0).to_dict() except ApiException as e: if status == 429: time.sleep(reset_rate(headers["X-RateLimit-Reset"])) if tag: tag = ",".join(tag) src_ff = src_fflags.get_feature_flags( module.params["project_key"], summary=0, tag=tag).to_dict() else: src_ff = src_fflags.get_feature_flags( module.params["project_key"], summary=0).to_dict() for flag in src_ff["items"]: fflag_body = dict( name=flag["name"], key=flag["key"], description=flag["description"], variations=flag["variations"], temporary=flag["temporary"], tags=flag["tags"], include_in_snippet=flag["include_in_snippet"], ) fflag_body_mapped = dict( (launchdarkly_api.FeatureFlagBody.attribute_map[k], v) for k, v in fflag_body.items() if v is not None) try: response, status, headers = dest_fflags.post_feature_flag_with_http_info( module.params["project_key_dest"], fflag_body_mapped) except ApiException as e: if e.status == 429: time.sleep(reset_rate(headers["X-RateLimit-Reset"])) # Retry ( response, status, headers, ) = dest_fflags.post_feature_flag_with_http_info( module.params["project_key_dest"], fflag_body) else: fail_exit(module, e) if module.params["environments_copy"]: patches = [] for fenv_key in flag["environments"]: fflag_env = dict( on=flag["environments"][fenv_key]["on"], targets=flag["environments"][fenv_key]["targets"], off_variation=flag["environments"][fenv_key] ["off_variation"], track_events=flag["environments"][fenv_key] ["track_events"], prerequisites=flag["environments"][fenv_key] ["prerequisites"], fallthrough=flag["environments"][fenv_key]["fallthrough"], ) fflag_env_mapped = dict( (launchdarkly_api.FeatureFlagConfig.attribute_map[k], v) for k, v in fflag_env.items() if v is not None) path = "/environments/" + fenv_key + "/" for key in fflag_env_mapped: if fflag_env_mapped.get(key) is not None: patch = dict(path=path + key, op="replace", value=fflag_env_mapped[key]) patches.append( launchdarkly_api.PatchOperation(**patch)) del patch try: for rule in flag["environments"][fenv_key]["rules"]: new_rule = dict(clauses=rule["clauses"]) if rule["rollout"] is not None: new_rule["rollout"] = rule["rollout"] if rule["variation"] is not None: new_rule["variation"] = rule["variation"] patch = dict( path=path + "rules/-", op="add", value=launchdarkly_api.Rule(**new_rule), ) patches.append( launchdarkly_api.PatchOperation(**patch)) except KeyError: pass if len(patches) > 0: try: ( response, status, headers, ) = dest_fflags.patch_feature_flag_with_http_info( module.params["project_key_dest"], flag["key"], patch_comment=patches, ) except ApiException as e: if e.status == 429: time.sleep(reset_rate(headers["X-RateLimit-Reset"])) # Retry dest_fflags.patch_feature_flag_with_http_info( module.params["project_key_dest"], flag["key"], patch_comment=patches, ) else: fail_exit(module, e) # Reset patches del patches new_project = dest_proj.get_project( module.params["project_key_dest"]).to_dict() module.exit_json( changed=True, project=new_project, msg="Copied project: %s to project: %s" % (module.params["project_key"], module.params["project_key_dest"]), )
def _configure_user_segment(module, api_instance, api_response=None, ans_changed=False): name = (module.params["name"] if module.params["name"] is not None else module.params["user_segment_key"]) patches = [] user_segment = api_response if user_segment: if user_segment.name == name and module.params["name"]: del module.params["name"] if (user_segment.description == module.params["description"] and module.params["description"]): del module.params["description"] if set(user_segment.tags) == set(module.params["tags"]): del module.params["tags"] if (user_segment.included and module.params["included"] and set( user_segment.included) == set(module.params["included"])): del module.params["included"] if (user_segment.excluded and module.params["excluded"] and set( user_segment.excluded) == set(module.params["excluded"])): del module.params["excluded"] dict_segment = user_segment.to_dict() result = diff( dict_segment["rules"], module.params["rules"], ignore=set([ "kind", "maintainer_id", "tags", "api_key", "creation_date", "state", "goal_ids", "links", "maintainer", "id", "project_key", "comment", "key", "version", "user_segment_key", "conftest", ]), ) if len(list(result)) == 0: del module.params["rules"] for key in module.params: if key not in [ "state", "api_key", "environment_key", "project_key", "user_segment_key", "conftest", ]: if module.params[key] is not None: patches.append(parse_user_param(module.params, key)) if len(patches) > 0: try: response, status, headers = api_instance.patch_user_segment_with_http_info( module.params["project_key"], module.params["environment_key"], module.params["user_segment_key"], patch_only=patches, ) ans_changed = True segment = response msg = "user segment successfully configured" except ApiException as e: if e.status == 404: module.exit_json(failed=True, msg="user segment key not found") else: fail_exit(module, e) else: segment = user_segment msg = "segment unchanged" module.exit_json(changed=ans_changed, msg=msg, user_segment=to_native(segment.to_dict()))
def _delete_webhook(module, api_instance): try: api_instance.delete_webhook(module.params["webhook_id"]) module.exit_json(msg="successfully deleted webhook") except ApiException as e: fail_exit(module, e)
def _configure_user_sync(module, api_instance): user_segment = api_instance.get_user_segment( module.params["project_key"], module.params["environment_key"], module.params["user_segment_key"], ) new_segment = launchdarkly_api.UserSegmentBody( name=user_segment.name, key=user_segment.key, description=user_segment.description, tags=user_segment.tags, ) for idx, env in enumerate(module.params["environment_targets"]): patches = [] try: response, status, headers = api_instance.post_user_segment_with_http_info( module.params["project_key"], env, new_segment) except ApiException as e: if e.status == 409: ( response, status, headers, ) = api_instance.get_user_segment_with_http_info( module.params["project_key"], env, module.params["user_segment_key"]) if user_segment.name is not None and user_segment.name != response.name: patches.append( _patch_op("replace", "/name", user_segment.name)) if (user_segment.description is not None and user_segment.description != response.description): patches.append( _patch_op("replace", "/description", user_segment.description)) if user_segment.tags is not None and set( user_segment.tags) != set(response.tags): patches.append( _patch_op("replace", "/tags", user_segment.tags)) else: fail_exit(module, e) if (module.params["included_actions"] is None or ("updateTargets" in module.params["included_actions"] or "updateTargets" not in module.params["excluded_actions"]) and (set(response.included) != set(user_segment.included) or set(response.excluded) != set(user_segment.excluded))): patches.append( _patch_op("replace", "/included", user_segment.included)) patches.append( _patch_op("replace", "/excluded", user_segment.excluded)) if module.params["included_actions"] is None or ( "updateRules" in module.params["included_actions"] or "updateRules" not in module.params["excluded_actions"]): for rule in user_segment.rules: patches.append( launchdarkly_api.PatchOperation(op="add", path="/rules", value=user_segment.rules)) try: response, status, headers = api_instance.patch_user_segment_with_http_info( module.params["project_key"], env, user_segment.key, patches) except ApiException as e: if e.status == 404: module.exit_json( failed=True, msg="user segment key: %s not found" % module.params["user_segment_key"], ) else: fail_exit(module, e) module.exit_json(changed=True, msg="feature flags synced", user_segment=response.to_dict())
def _configure_flag(module, api_instance, feature_flag=None): patches = [] if feature_flag: if feature_flag.name == module.params["name"]: del module.params["name"] if feature_flag.description == module.params["description"]: del module.params["description"] if feature_flag.include_in_snippet == module.params[ "include_in_snippet"]: del module.params["include_in_snippet"] if feature_flag.temporary == module.params["temporary"]: del module.params["temporary"] if module.params["tags"] is not None and set(feature_flag.tags) == set( module.params["tags"]): del module.params["tags"] result = diff( feature_flag.to_dict(), module.params, ignore=set([ "kind", "maintainer_id", "tags", "api_key", "creation_date", "state", "goal_ids", "links", "maintainer", "id", "project_key", "comment", "key", "version", "custom_properties", "salt", "environments", ]), ) out_vars = list(result) if out_vars: changed = [ variation for effects in out_vars for variation in effects if variation in ["variations"] ] # TODO fix logic to pass in name and description for bool if len(changed) > 0 and module.params["variations"]: _patch_variations(module, feature_flag.variations, patches) del module.params["variations"] else: del module.params["variations"] if (feature_flag.maintainer_id == module.params["maintainer_id"] or module.params["maintainer_id"] is None): del module.params["maintainer_id"] for key in module.params: if (key not in [ "state", "api_key", "key", "environment_key", "project_key", "kind", "comment", "clone", "variations", "conftest", ] and module.params[key] is not None): patches.append(_parse_flag_param(module, key, key)) if len(patches) == 0: module.exit_json(changed=False, msg="feature flag unchanged") if module.params["comment"]: comment = module.params["comment"] else: comment = "Ansible generated operation." comments = dict(comment=comment, patch=patches) try: response, status, headers = api_instance.patch_feature_flag_with_http_info( module.params["project_key"], module.params["key"], comments) module.exit_json(changed=True, msg="feature flag updated", content=response.to_dict()) except ApiException as e: fail_exit(module, e)
def _delete_custom_role(module, api_instance): try: api_instance.delete_custom_role(module.params["key"]) module.exit_json(msg="successfully deleted custom role") except ApiException as e: fail_exit(module, e)