def run(self, progress_callback): client = DSSClient('http://localhost:%s' % os.environ.get('DKU_BACKEND_PORT'), internal_ticket = os.environ.get('DKU_API_TICKET')) rt = ResultTable() rt.set_name("Killed sessions") rt.add_column("session_id", "Session id", "STRING") rt.add_column("notebook_project", "Notebook project key", "STRING") rt.add_column("notebook_project", "Notebook name", "STRING") simulate = self.config.get('simulate', True) max_idle = float(self.config.get('maxIdleTimeHours', 0)) max_age = float(self.config.get('maxSessionAgeHours', 0)) dont_kill_busy = self.config.get('dontKillBusyKernels', True) dont_kill_connected = self.config.get('dontKillConnectedKernels', True) now = get_epochtime_ms() logging.info("Listing notebooks max_age_ms=%s max_idle_ms=%s" % (max_age * 1000 * 3600, max_idle * 1000 * 3600)) for nbk in client.list_running_notebooks(): state = nbk.get_state() for session in state["activeSessions"]: logging.info("Check kill of %s session_age=%s kernel_idle=%s" % ( session, (now - session["sessionStartTime"]), (now - session["kernelLastActivityTime"]))) kill = False if max_age > 0 and (now - session["sessionStartTime"]) > max_age * 1000 * 3600: logging.info( " -> Will kill on max_age") kill = True if max_idle > 0 and (now - session["kernelLastActivityTime"]) > max_idle * 1000 * 3600: logging.info( " -> Will kill on max_idle") kill = True if dont_kill_busy and session["kernelExecutionState"] == "busy": logging.info(" -> Don't kill (busy)") kill = False if dont_kill_connected and session["kernelConnections"] > 0: logging.info(" -> Don't kill (connected)") kill = False if kill: logging.info("Unloading session %s" % session["sessionId"]) rt.add_record([session["sessionId"], session.get("projectKey", "?"), session.get("notebookName", "?")]) if not simulate: nbk.unload(session["sessionId"]) else: logging.info("Don't kill %s" % session["sessionId"]) return rt
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), settings=dict(type='dict', required=False, default={}), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) args = MakeNamespace(module.params) api_key = args.api_key if args.api_key is not None else args.connect_to.get( "api_key", None) if api_key is None: module.fail_json( msg= "Missing an API Key, either from 'api_key' or 'connect_to' parameters" .format(args.state)) port = args.port if args.port is not None else args.connect_to.get( "port", "80") host = args.host result = dict(changed=False, message='UNCHANGED', previous_settings=None, settings=None) client = None general_settings = None try: client = DSSClient("http://{}:{}".format(args.host, port), api_key=api_key) general_settings = client.get_general_settings() current_values = extract_keys(general_settings.settings, args.settings) # Prepare the result for dry-run mode result["previous_settings"] = current_values result["dss_general_settings"] = general_settings.settings result["changed"] = (current_values != args.settings) if result["changed"]: result["message"] = "MODIFIED" if module.check_mode: module.exit_json(**result) # Apply the changes update(general_settings.settings, args.settings) general_settings.save() module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(type(e).__name__, str(e)))
class MyRunnable(Runnable): def __init__(self, project_key, config, plugin_config): self.project_key = project_key self.config = config self.plugin_config = plugin_config self.client = DSSClient('http://localhost:%s' % os.environ.get('DKU_BACKEND_PORT'), internal_ticket = os.environ.get('DKU_API_TICKET')) def get_progress_target(self): return None def run(self, progress_callback): included = self.config.get('includedTags', '') excluded = self.config.get('excludedTags', '') included_or = self.config.get('includedTagsCombine', 'OR') == 'OR' excluded_or = self.config.get('excludedTagsCombine', 'OR') == 'OR' included_set = set(included.split(',')) excluded_set = set(excluded.split(',')) project = self.client.get_project(self.project_key) to_delete = [] for dataset in project.list_datasets(): tags = dataset.get('tags', []) included = apply(tags, included_set, included_or) excluded = apply(tags, excluded_set, excluded_or) if included and not excluded: to_delete.append(dataset) rt = ResultTable() rt.set_name("Delete datasets by tag") simulate = self.config.get('simulate', True) rt.add_column("dataset", simulate and "Dataset to delete" or "Deleted dataset", "LOCAL_DATASET_WITH_TYPE") if not simulate: rt.add_column("result", "Result", "STRING") if not simulate: for dataset in to_delete: try: project.get_dataset(dataset.get('name')).delete(drop_data=self.config.get("drop_data", True)) rt.add_record(["%s:%s" % (dataset.get("type"), dataset.get("name")), "SUCCESS"]) except Exception as e: rt.add_record(["%s:%s" % (dataset.get("type"), dataset.get("name")), "FAILED: %s" % str(e)]) return rt else: rows = [] for dataset in to_delete: rt.add_record(["%s:%s" % (dataset.get("type"), dataset.get("name"))]) return rt
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), state=dict(type='str', required=False, default="present"), id=dict(type='str', required=True), stage=dict(type='str', required=True), type=dict(type='str', required=True), api_nodes=dict(type='list', required=True), permissions=dict(type='list', required=False, default=[]), carbonapi_url=dict(type='str', required=False, default=None), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) args = MakeNamespace(module.params) api_key = args.api_key if args.api_key is not None else args.connect_to.get( "api_key", None) if api_key is None: module.fail_json( msg= "Missing an API Key, either from 'api_key' or 'connect_to' parameters" .format(args.state)) port = args.port if args.port is not None else args.connect_to.get( "port", "80") host = args.host result = dict( changed=False, message='UNCHANGED', id=args.id, ) client = None exists = True create = False infra = None try: client = DSSClient("http://{}:{}".format(args.host, port), api_key=api_key) api_deployer = client.get_apideployer() infras_status = api_deployer.list_infras(as_objects=False) infras_id = [] for infra_status in infras_status: infras_id.append(infra_status["infraBasicInfo"]["id"]) exists = args.id in infras_id if not exists and args.state == "present": create = True result["changed"] = create or (exists and args.state == "absent") if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" elif current != new_def: result["message"] = "MODIFIED" # Prepare the result for dry-run mode if module.check_mode: module.exit_json(**result) # Apply the changes if args.state == "present": if create: infra = api_deployer.create_infra(args.id, args.stage, args.type) else: infra = api_deployer.get_infra(args.id) infra_settings = infra.get_settings() previous_settings = copy.deepcopy(infra_settings.get_raw()) # Remove all / push all infra_settings.get_raw()["permissions"] = args.permissions infra_settings.get_raw()["apiNodes"] = [] for api_node in args.api_nodes: infra_settings.add_apinode( api_node["url"], api_node["admin_api_key"], api_node.get("graphite_prefix", None)) if args.carbonapi_url is not None: infra_settings.get_raw().update({ "carbonAPISettings": { "carbonAPIURL": args.carbonapi_url } }) infra_settings.save() if infra_settings.get_raw( ) != previous_settings and not result["changed"]: result["changed"] = True result["message"] = "MODIFIED" if args.state == "absent" and exits: # TODO implement pass module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(type(e).__name__, str(e)))
def __init__(self, project_key, config, plugin_config): self.project_key = project_key self.config = config self.plugin_config = plugin_config self.client = DSSClient('http://localhost:%s' % os.environ.get('DKU_BACKEND_PORT'), internal_ticket = os.environ.get('DKU_API_TICKET'))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), name=dict(type='str', required=True), state=dict(type='str', required=False, default="present"), postgresql_host=dict(type='str', default=None, required=False), postgresql_port=dict(type='str', default=None, required=False), user=dict(type='str', default=None, required=False), password=dict(type='str', required=False, no_log=True), database=dict(type='str', default=None, required=False), additional_args=dict(type='dict', default={}, required=False), ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) args = MakeNamespace(module.params) if args.state not in ["present","absent"]: module.fail_json(msg="Invalid value '{}' for argument state : must be either 'present' or 'absent'".format(args.source_type)) api_key = args.api_key if args.api_key is not None else args.connect_to.get("api_key",None) if api_key is None: module.fail_json(msg="Missing an API Key, either from 'api_key' or 'connect_to' parameters".format(args.state)) port = args.port if args.port is not None else args.connect_to.get("port","80") host = args.host result = dict( changed=False, message='UNCHANGED', ) try: client = DSSClient("http://{}:{}".format(args.host, port),api_key=api_key) exists = True create = False connection = client.get_connection(args.name) current_def = None try: current_def = connection.get_definition() except DataikuException as e: #if e.message.startswith("com.dataiku.dip.server.controllers.NotFoundException"): if str(e) == "java.lang.IllegalArgumentException: Connection '{}' does not exist".format(args.name): exists = False if args.state == "present": create = True else: raise except Exception as e: raise current_def = None encrypted_password_before_change = None if exists: result["previous_group_def"] = current_def = connection.get_definition() # Check this is the same type if current_def["type"] != connection_template["type"]: module.fail_json(msg="Connection '{}' already exists but is of type '{}'".format(args.name,current_def["type"])) return # Remove some values from the current def encrypted_password_before_change = current_def["params"].get("password",None) if encrypted_password_before_change is not None: del current_def["params"]["password"] else: if args.state == "present": for mandatory_create_param in ["user", "password", "database", "postgresql_host"]: if module.params[mandatory_create_param] is None: module.fail_json(msg="Connection '{}' does not exist and cannot be created without the '{}' parameter".format(args.name,mandatory_create_param)) # Build the new definition new_def = copy.deepcopy(current_def) if exists else connection_template # Used for modification # Apply every attribute except the password for now new_def["name"] = args.name if args.database is not None: new_def["params"]["db"] = args.database if args.user is not None: new_def["params"]["user"] = args.user if args.postgresql_host is not None: new_def["params"]["host"] = args.postgresql_host if args.postgresql_port is not None: new_def["params"]["port"] = args.postgresql_port # Bonus args update(new_def, args.additional_args) # Prepare the result for dry-run mode result["changed"] = create or (exists and args.state == "absent") or (exists and current_def != new_def) if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" elif current_def != new_def: result["message"] = "MODIFIED" if args.state == "present": result["connection_def"] = new_def if module.check_mode: module.exit_json(**result) ## Apply the changes if result["changed"] or (args.password is not None and exists): if create: new_def["params"]["password"] = args.password params = { "db": args.database, "user": args.user, "password": args.password, "host": args.postgresql_host, } if args.postgresql_port is not None: params["port"] = args.postgresql_port connection = client.create_connection(args.name, connection_template["type"], params) connection.set_definition(new_def) # 2nd call to apply additional parameters elif exists: if args.state == "absent": connection.delete() elif current_def != new_def or args.password is not None: if args.password is not None: new_def["params"]["password"] = args.password else: new_def["params"]["password"] = encrypted_password_before_change result["message"] = str(connection.set_definition(new_def)) if args.password is not None: # Get again the definition to test again the encrypted pass new_def_after_submit = connection.get_definition() if encrypted_password_before_change != new_def_after_submit["params"]["password"]: result["changed"] = True result["message"] = "MODIFIED" module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(type(e).__name__,str(e)))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), name=dict(type='str', required=True), state=dict(type='str', required=False, default="present"), type=dict(type='str', required=True), connection_args=dict(type='dict', default={}, required=False), #params=dict(type='dict', default={}, required=False), ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) args = MakeNamespace(module.params) if args.state not in ["present","absent"]: module.fail_json(msg="Invalid value '{}' for argument state : must be either 'present' or 'absent'".format(args.source_type)) api_key = args.api_key if args.api_key is not None else args.connect_to.get("api_key",None) if api_key is None: module.fail_json(msg="Missing an API Key, either from 'api_key' or 'connect_to' parameters".format(args.state)) port = args.port if args.port is not None else args.connect_to.get("port","80") host = args.host type = args.type result = dict( changed=False, message='UNCHANGED', ) try: client = DSSClient("http://{}:{}".format(args.host, port),api_key=api_key) exists = True create = False connection = client.get_connection(args.name) current_def = None try: current_def = connection.get_definition() except DataikuException as e: #if e.message.startswith("com.dataiku.dip.server.controllers.NotFoundException"): if str(e) == "java.lang.IllegalArgumentException: Connection '{}' does not exist".format(args.name): exists = False if args.state == "present": create = True else: raise except Exception as e: raise current_def = None encrypted_fields_before_change = {"params":{}} if exists: result["previous_group_def"] = current_def = connection.get_definition() # Check this is the same type if current_def["type"] != type: module.fail_json(msg="Connection '{}' already exists but is of type '{}'".format(args.name,current_def["type"])) return # Remove some values from the current def for field in encrypted_fields_list: encrypted_field_before_change = current_def["params"].get(field,None) if encrypted_field_before_change is not None: encrypted_fields_before_change["params"][field] = encrypted_field_before_change del current_def["params"][field] else: if args.state == "present": #for mandatory_create_param in ["user", "password", "database", "postgresql_host"]: #if module.params[mandatory_create_param] is None: #module.fail_json(msg="Connection '{}' does not exist and cannot be created without the '{}' parameter".format(args.name,mandatory_create_param)) pass # Build the new definition new_def = copy.deepcopy(current_def) if exists else connection_template # Used for modification # Apply every attribute except the password for now new_def["name"] = args.name update(new_def, args.connection_args) # Extract args that may be encrypted encrypted_fields = {"params":{}} for field in encrypted_fields_list: value = new_def["params"].get(field,None) if value is not None: encrypted_fields["params"][field] = value del new_def["params"][field] # Prepare the result for dry-run mode result["changed"] = create or (exists and args.state == "absent") or (exists and current_def != new_def) if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" elif current_def != new_def: result["message"] = "MODIFIED" if args.state == "present": result["connection_def"] = new_def if module.check_mode: module.exit_json(**result) ## Apply the changes if result["changed"] or (0 < len(encrypted_fields["params"]) and exists): if create: update(new_def, encrypted_fields) connection = client.create_connection(args.name, type, new_def["params"]) def_after_creation = connection.get_definition() update(def_after_creation,new_def) connection.set_definition(def_after_creation) # 2nd call to apply additional parameters elif exists: if args.state == "absent": connection.delete() elif current_def != new_def or 0 < len(encrypted_fields["params"]): #for field in encrypted_fields_list: #new_def_value = encrypted_fields.get(field, None) ## TODO: Bugfix about password here #del new_def["params"][field] ##if new_def_value is not None: ##new_def["params"][field] = new_def_value ##else: ##new_def["params"][field] = encrypted_fields_before_change.get(field) result["message"] = str(connection.set_definition(new_def)) #if 0 < len(encrypted_fields["params"]): ## Get again the definition to test again the encrypted fields #new_def_after_submit = connection.get_definition() #encrypted_fields_after_change = {"params":{}} #for field in encrypted_fields_list: #value = new_def_after_submit.get(field,None) #if value is not None: #encrypted_fields_after_change["params"][field] = value #if encrypted_fields_before_change != encrypted_fields_after_change: #result["changed"] = True #result["message"] = "MODIFIED" module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(pytypefunc(e).__name__,str(e)))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), login=dict(type='str', required=True), password=dict(type='str', required=False, default=None, no_log=True), set_password_at_creation_only=dict(type='bool', required=False, default=True), email=dict(type='str', required=False, default=None), display_name=dict(type='str', required=False, default=None), groups=dict(type='list', required=False, default=None), profile=dict(type='str', required=False, default=None), source_type=dict(type='str', required=False, default="LOCAL"), state=dict(type='str', required=False, default="present"), ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) args = MakeNamespace(module.params) if args.state not in ["present","absent"]: module.fail_json(msg="Invalid value '{}' for argument state : must be either 'present' or 'absent'".format(args.state)) api_key = args.api_key if args.api_key is not None else args.connect_to.get("api_key",None) if api_key is None: module.fail_json(msg="Missing an API Key, either from 'api_key' or 'connect_to' parameters".format(args.state)) port = args.port if args.port is not None else args.connect_to.get("port","80") host = args.host result = dict( changed=False, message='UNCHANGED', ) client = DSSClient("http://{}:{}".format(args.host, port),api_key=api_key) user = DSSUser(client, args.login) try: user_exists = True create_user = False current_user = None try: current_user = user.get_definition() except DataikuException as e: if e.message.startswith("com.dataiku.dip.server.controllers.NotFoundException"): user_exists = False if args.state == "present": create_user = True else: raise except: raise # Manage errors if args.source_type not in ["LOCAL","LDAP","LOCAL_NO_AUTH"]: module.fail_json(msg="Invalid value '{}' for source_type : must be either 'LOCAL', 'LDAP' or 'LOCAL_NO_AUTH'".format(args.source_type)) if args.password is None and create_user and args.source_type not in ['LDAP','LOCAL_NO_AUTH']: module.fail_json(msg="The 'password' parameter is missing but is mandatory to create new local user '{}'.".format(args.login)) if args.display_name is None and create_user: #module.fail_json(msg="The 'display_name' parameter is missing but is mandatory to create new user '{}'.".format(args.login)) # TODO: shall we fail here or use a default to login ? args.display_name = module.params["display_name"] = args.login if args.groups is None and create_user: args.groups = module.params["groups"] = ["readers"] # Build the new user definition # TODO: be careful that the key names changes between creation and edition new_user_def = copy.deepcopy(current_user) if user_exists else {} # Used for modification result["previous_user_def"] = copy.deepcopy(new_user_def) for key, api_param in [("email","email"),("display_name","displayName"),("profile","userProfile"),("groups","groups"),("source_type","sourceType")]: if module.params.get(key,None) is not None: value = module.params[key] if isinstance(value,six.string_types): value = value.decode("UTF-8") new_user_def[key if create_user else api_param] = value if user_exists and args.password is not None and not args.set_password_at_creation_only: new_user_def["password"] = args.password # Sort groups list before comparison as they should be considered sets new_user_def.get("groups",[]).sort() if user_exists: current_user.get("groups",[]).sort() # Prepare the result for dry-run mode result["changed"] = create_user or (user_exists and args.state == "absent") or (user_exists and current_user != new_user_def) if result["changed"]: if create_user: result["message"] = "CREATED" elif user_exists: if args.state == "absent": result["message"] = "DELETED" elif current_user != new_user_def: result["message"] = "MODIFIED" # Can be useful to register info from a playbook and act on it if args.state == "present": result["user_def"] = new_user_def if module.check_mode: module.exit_json(**result) # Apply the changes if result["changed"]: if create_user: create_excluded_keys = ["email"] create_excluded_values = {} for create_excluded_key in create_excluded_keys: if new_user_def.get(create_excluded_key,None) is not None: create_excluded_values[create_excluded_key] = new_user_def[create_excluded_key] del new_user_def[create_excluded_key] new_user = client.create_user(args.login, args.password, **new_user_def) if module.params.get("email",None) is not None: new_user_def_mod = new_user.get_definition() new_user_def_mod.update(create_excluded_values) new_user.set_definition(new_user_def_mod) elif user_exists: if args.state == "absent": user.delete() elif current_user != new_user_def: result["message"] = str(user.set_definition(new_user_def)) module.exit_json(**result) except Exception as e: module.fail_json(msg=str(e))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), name=dict(type='str', required=True), description=dict(type='str', required=False, default=None), source_type=dict(type='str', required=False, default=None), state=dict(type='str', required=False, default="present"), admin=dict(type='bool', required=False, default=None), ldap_group_names=dict(type='list', required=False, default=None), may_create_authenticated_connections=dict(type='bool', required=False, default=None), may_create_code_envs=dict(type='bool', required=False, default=None), may_create_projects=dict(type='bool', required=False, default=None), may_develop_plugins=dict(type='bool', required=False, default=None), may_edit_lib_folders=dict(type='bool', required=False, default=None), may_manage_code_envs=dict(type='bool', required=False, default=None), may_manage_u_d_m=dict(type='bool', required=False, default=None), may_view_indexed_hive_connections=dict(type='bool', required=False, default=None), may_write_safe_code=dict(type='bool', required=False, default=True), may_write_unsafe_code=dict(type='bool', required=False, default=None), ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) args = MakeNamespace(module.params) if args.state not in ["present","absent"]: module.fail_json(msg="Invalid value '{}' for argument state : must be either 'present' or 'absent'".format(args.source_type)) if args.source_type not in [None,"LOCAL","LDAP","SAAS"]: module.fail_json(msg="Invalid value '{}' for source_type : must be either 'LOCAL', 'LDAP' or 'SAAS'".format(args.state)) api_key = args.api_key if args.api_key is not None else args.connect_to.get("api_key",None) if api_key is None: module.fail_json(msg="Missing an API Key, either from 'api_key' or 'connect_to' parameters".format(args.state)) port = args.port if args.port is not None else args.connect_to.get("port","80") host = args.host result = dict( changed=False, message='UNCHANGED', ) client = DSSClient("http://{}:{}".format(args.host, port),api_key=api_key) group = DSSGroup(client, args.name) try: exists = True create = False current = None try: current = group.get_definition() except DataikuException as e: if e.message.startswith("com.dataiku.dip.server.controllers.NotFoundException"): exists = False if args.state == "present": create = True else: raise except: raise # Sort groups list before comparison as they should be considered sets if exists: current["ldapGroupNames"]= ",".join(sorted(current.get("ldapGroupNames","").split(","))) result["previous_group_def"] = current # Build the new user definition new_def = copy.deepcopy(current) if exists else {} # Used for modification # Transform to camel case dict_args = {} if args.ldap_group_names is not None: dict_args["ldapGroupNames"] = ",".join(sorted(args.ldap_group_names)) for key, value in module.params.items(): if key not in ["connect_to","host","port","api_key","state","ldap_group_names"] and value is not None: camelKey = re.sub(r'_[a-z]', lambda x : x.group()[1:].upper(), key) dict_args[camelKey] = value new_def.update(dict_args) # Prepare the result for dry-run mode result["changed"] = create or (exists and args.state == "absent") or (exists and current != new_def) if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" elif current != new_def: result["message"] = "MODIFIED" if args.state == "present": result["group_def"] = new_def if module.check_mode: module.exit_json(**result) # Apply the changes if result["changed"]: if create: new_group = client.create_group(args.name, description = new_def.get("description",None), source_type=new_def.get("source_type","LOCAL")) # 2nd request mandatory for capabilites TODO: fix the API if "mayWriteSafeCode" not in new_def.keys(): new_def["mayWriteSafeCode"] = True new_group.set_definition(new_def) result["group_def"] = new_group.get_definition() elif exists: if args.state == "absent": group.delete() elif current != new_def: result["message"] = str(group.set_definition(new_def)) module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(type(e).__name__,str(e)))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( connect_to=dict(type='dict', required=False, default={}, no_log=True), host=dict(type='str', required=False, default="127.0.0.1"), port=dict(type='str', required=False, default=None), api_key=dict(type='str', required=False, default=None), state=dict(type='str', required=False, default="present"), name=dict(type='str', required=True), lang=dict(type='str', required=True), deployment_mode=dict(type='str', required=False, default=None), jupyter_support=dict(type='bool', required=False, default=None), update=dict(type='bool', required=False, default=True), desc=dict(type='dict', required=False, default=None), ) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True ) args = MakeNamespace(module.params) api_key = args.api_key if args.api_key is not None else args.connect_to.get("api_key",None) if api_key is None: module.fail_json(msg="Missing an API Key, either from 'api_key' or 'connect_to' parameters".format(args.state)) port = args.port if args.port is not None else args.connect_to.get("port","80") host = args.host if args.lang not in ["PYTHON","R"]: module.fail_json(msg="The lang attribute has invalid value '{}'. Must be either 'PYTHON' or 'R'.".format(args.lang)) result = dict( changed=False, message='UNCHANGED', ) client = None exists = False create = False code_env = None code_env_def = {} try: client = DSSClient("http://{}:{}".format(args.host, port),api_key=api_key) code_envs = client.list_code_envs() # Check existence for env in code_envs: if env["envName"] == args.name and env["envLang"] == args.lang: exists=True break if not exists and args.state == "present": create = True if exists: code_env = client.get_code_env(args.lang, args.name) code_env_def = code_env.get_definition() # Prepare the result for dry-run mode result["changed"] = create or (exists and args.state == "absent") if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" else: result["message"] = "UNMODIFIED" if module.check_mode: module.exit_json(**result) # Apply the changes if args.state == "present": previous_code_env_def = copy.deepcopy(code_env_def) if create: if args.deployment_mode is None: raise Exception("The argument deployment_mode is mandatory to create a code env") code_env = client.create_code_env(args.lang,args.name,args.deployment_mode,args.desc) code_env_def = code_env.get_definition() if args.desc is not None: update(code_env_def, args.desc) if args.jupyter_support is not None: code_env.set_jupyter_support(args.jupyter_support) code_env_def = code_env.get_definition() result["dss_code_env"] = code_env_def if previous_code_env_def != code_env_def: if args.update and not create: code_env.update_packages() result["changed"] = True result["message"] = "MODIFIED" if args.state == "absent" and exits: if exists: code_env.delete() result["message"] = "DELETED" module.exit_json(**result) except Exception as e: module.fail_json(msg="{}: {}".format(type(e).__name__,str(e)))