def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict(settings=dict(type="dict", required=False, default={}), ) add_dss_connection_args(module_args) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) args = MakeNamespace(module.params) result = dict(changed=False, message="UNCHANGED", previous_settings=None, settings=None) client = None general_settings = None try: client = get_client_from_parsed_args(module) 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="{}\n\n{}\n\n{}".format( str(e), traceback.format_exc(), "".join(traceback.format_stack())))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( 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), ) add_dss_connection_args(module_args) 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)) result = dict( changed=False, message="UNCHANGED", ) try: client = get_client_from_parsed_args(module) 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="{}\n\n{}\n\n{}".format( str(e), traceback.format_exc(), "".join(traceback.format_stack())))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( 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), set_encrypted_fields_at_creation_only=dict(type="bool", default=False, required=False), # params=dict(type='dict', default={}, required=False), ) add_dss_connection_args(module_args) 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)) type = args.type result = dict( changed=False, message="UNCHANGED", ) try: client = get_client_from_parsed_args(module) 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"]) and not args.set_encrypted_fields_at_creation_only): for field in encrypted_fields_list: new_def_value = encrypted_fields["params"].get( field, None) 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"]): # no need to compare, encrypted fields change value if reset result["changed"] = True result["message"] = "MODIFIED" module.exit_json(**result) except Exception as e: module.fail_json(msg="{}\n\n{}\n\n{}".format( str(e), traceback.format_exc(), "".join(traceback.format_stack())))
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict( state=dict(type="str", required=False, default="present"), plugin_id=dict(type="str", required=True), zip_file=dict(type="str", required=False, default=None), git_repository_url=dict(type="str", required=False, default=None), git_checkout=dict(type="str", required=False, default="master"), git_subpath=dict(type="str", required=False, default=None), settings=dict(type="dict", required=False, default={}), force=dict(type="bool", required=False, default=False), install_code_env=dict(type="bool", required=False, default=True), ) add_dss_connection_args(module_args) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) args = MakeNamespace(module.params) result = dict(changed=False, message="UNCHANGED",) client = None exists = False create = False plugin = None create_code_env = False current_settings = {} try: client = get_client_from_parsed_args(module) plugins = client.list_plugins() plugin_dict = { plugin['id']: plugin for plugin in plugins } # Check existence if args.plugin_id in plugin_dict: exists = True if not exists and args.state == "present": create = True if exists: plugin = client.get_plugin(args.plugin_id) current_settings = copy.deepcopy(plugin.get_settings().get_raw()) # Prepare the result for dry-run mode new_settings = copy.deepcopy(current_settings) if args.settings is not None: update(new_settings, args.settings) result["changed"] = create or (exists and (args.state == "absent" or (args.settings is not None and new_settings != current_settings) or (create_code_env and "codeEnvName" not in current_settings))) if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" elif args.settings is not None: result["message"] = "MODIFIED" else: result["message"] = "UNMODIFIED" result["job_results"] = [] result["dss_plugin"] = { "id": args.plugin_id, } if exists: result["dss_plugin"]["settings"] = new_settings update(result["dss_plugin"], plugin_dict[args.plugin_id]) if module.check_mode: module.exit_json(**result) # Apply the changes if args.state == "present": plugin_desc = {} if not exists: future = None if args.zip_file is not None: future = client.install_plugin_from_archive(args.zip_file) elif args.git_repository_url is not None: future = client.install_plugin_from_git(args.git_repository_url, args.git_checkout, args.git_subpath) else: # Install from store future = client.install_plugin_from_store(args.plugin_id) result["job_results"].append(future.wait_for_result()) plugin_desc = result["job_results"][-1].get("pluginDesc") # Required to relist for the meta plugins = client.list_plugins() plugin_dict = { plugin['id']: plugin for plugin in plugins } plugin = client.get_plugin(args.plugin_id) update(result["dss_plugin"], plugin_dict[args.plugin_id]) elif args.force: future = None if args.zip_file is not None: future = plugin.update_from_zip(args.zip_file) elif args.git_repository_url is not None: future = plugin.update_from_git(args.git_repository_url, args.git_checkout, args.git_subpath) else: # Install from store future = plugin.update_from_store() result["job_results"].append(future.wait_for_result()) plugin_desc = result["job_results"][-1].get("pluginDesc") # Force refetch settings current_settings = copy.deepcopy(plugin.get_settings().get_raw()) new_settings = copy.deepcopy(current_settings) if args.settings is not None: update(new_settings, args.settings) if "codeEnvSpec" in plugin_desc and args.install_code_env: create_code_env = True result["dss_plugin"]["settings"] = new_settings code_env_install_result = None if args.state == "present" and create_code_env and "codeEnvName" not in new_settings: future = plugin.create_code_env() code_env_install_result = future.wait_for_result() new_settings["codeEnvName"] = code_env_install_result.get("envName") result["job_results"].append(code_env_install_result) if (args.settings is not None or code_env_install_result is not None) and args.state == "present" and new_settings != current_settings: settings_handle = plugin.get_settings() update(settings_handle.settings, new_settings) settings_handle.save() result["dss_plugin"]["settings"] = new_settings if args.state == "absent" and exists: future = plugin.delete(force=args.force) if future.job_id is not None: result["job_results"].append(future.wait_for_result()) module.exit_json(**result) except Exception as e: module.fail_json(msg="{}\n\n{}\n\n{}".format(str(e), traceback.format_exc(), "".join(traceback.format_stack())))
def run_module(): # define the available arguments/parameters that a user can pass to # the module # Fields that can be updated in design node: # * env.permissions, env.usableByAll, env.desc.owner # * env.specCondaEnvironment, env.specPackageList, env.externalCondaEnvName, env.desc.installCorePackages, # env.desc.installJupyterSupport, env.desc.yarnPythonBin # Fields that can be updated in automation node (where {version} is the updated version): # * env.permissions, env.usableByAll, env.owner # * env.{version}.specCondaEnvironment, env.{version}.specPackageList, env.{version}.externalCondaEnvName, # env.{version}.desc.installCorePackages, env.{version}.desc.installJupyterSupport, env.{version}.desc.yarnPythonBin # [ "version" { ] # permissions, usableByAll, owner, specCondaEnvironement, specPackageList, externalCondaEnvName # desc(installCorePackages,installJupyterSupport, yarnPythonbin) # [ } ] module_args = dict( 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), version=dict(type="str", required=False, default=None), core_packages=dict(type="bool", required=False, default=True), jupyter_support=dict(type="bool", required=False, default=True), update=dict(type="bool", required=False, default=True), permissions=dict(type="list", required=False, default=None), usable_by_all=dict(type="bool", required=False, default=None), owner=dict(type="str", required=False, default=None), conda_environment=dict(type="str", required=False, default=None), package_list=dict(type="list", required=False, default=None), external_conda_env_name=dict(type="str", required=False, default=None), python_interpreter=dict(type="str", required=False, default=None), desc=dict(type="dict", required=False, default=None), ) add_dss_connection_args(module_args) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) args = MakeNamespace(module.params) 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 = {} required_code_env_def = {} versioned_required_code_env_def = required_code_env_def if args.version is not None: required_code_env_def[args.version] = {"desc": {}} versioned_required_code_env_def = required_code_env_def[args.version] else: required_code_env_def["desc"] = {} if args.permissions is not None: required_code_env_def["permissions"] = args.permissions if args.usable_by_all is not None: required_code_env_def["usableByAll"] = args.usable_by_all if args.conda_environment is not None: versioned_required_code_env_def[ "specCondaEnvironment"] = args.conda_environment if args.package_list is not None: versioned_required_code_env_def["specPackageList"] = "\n".join( args.package_list) if args.external_conda_env_name is not None: versioned_required_code_env_def[ "externalCondaEnvName"] = args.external_conda_env_name if args.owner is not None: if args.deployment_mode in [ "DESIGN_MANAGED", "DESIGN_MANAGED", "PLUGIN_MANAGED", "PLUGIN_NON_MANAGED" ]: versioned_required_code_env_def["desc"]["owner"] = args.owner else: versioned_required_code_env_def["owner"] = args.owner if args.desc is not None: update(versioned_required_code_env_def["desc"], args.desc) if args.core_packages and "installCorePackages" not in versioned_required_code_env_def[ "desc"]: versioned_required_code_env_def["desc"][ "installCorePackages"] = args.core_packages if args.jupyter_support and "installJupyterSupport" not in versioned_required_code_env_def[ "desc"]: versioned_required_code_env_def["desc"][ "installJupyterSupport"] = args.jupyter_support update_packages = False try: client = get_client_from_parsed_args(module) 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() if args.deployment_mode is None: args.deployment_mode = code_env_def["deploymentMode"] if "NON_MANAGED" not in args.deployment_mode: if args.version is not None: if "specPackageList" in versioned_required_code_env_def and args.version in code_env_def and "specPackageList" in code_env_def[ args.version] and versioned_required_code_env_def[ "specPackageList"] != code_env_def[ args.version]["specPackageList"]: update_packages = True if "installJupyterSupport" in versioned_required_code_env_def[ "desc"] and "installJupyterSupport" in code_env_def[ args.version][ "desc"] and versioned_required_code_env_def[ "desc"][ "installJupyterSupport"] != code_env_def[ args.version]["desc"][ "installJupyterSupport"]: update_packages = True else: if "specPackageList" in required_code_env_def and "specPackageList" in code_env_def and required_code_env_def[ "specPackageList"] != code_env_def[ "specPackageList"]: update_packages = True if "installJupyterSupport" in required_code_env_def[ "desc"] and "installJupyterSupport" in code_env_def[ "desc"] and required_code_env_def["desc"][ "installJupyterSupport"] != code_env_def[ "desc"]["installJupyterSupport"]: update_packages = True new_code_env_def = copy.deepcopy(code_env_def) update(new_code_env_def, required_code_env_def) # Prepare the result for dry-run mode result["changed"] = create or (exists and args.state == "absent") or ( args.state == "present" and new_code_env_def != code_env_def) if result["changed"]: if create: result["message"] = "CREATED" elif exists: if args.state == "absent": result["message"] = "DELETED" else: if code_env_def != new_code_env_def: result["message"] = "MODIFIED" else: result["message"] = "UNMODIFIED" if module.check_mode: module.exit_json(**result) # Apply the changes if args.state == "present": if create: if args.deployment_mode is None: raise Exception( "The argument deployment_mode is mandatory to create a code env" ) if args.python_interpreter is not None: versioned_required_code_env_def[ "pythonInterpreter"] = args.python_interpreter code_env = client.create_code_env(args.lang, args.name, args.deployment_mode, required_code_env_def) code_env_def = code_env.get_definition() new_code_env_def = copy.deepcopy(code_env_def) update(new_code_env_def, required_code_env_def) if new_code_env_def != code_env_def: code_env.set_definition(new_code_env_def) if (args.update or create or update_packages ) and "NON_MANAGED" not in args.deployment_mode: code_env.update_packages() if args.jupyter_support: code_env.set_jupyter_support(args.jupyter_support) code_env_def = code_env.get_definition() result["dss_code_env"] = code_env_def if new_code_env_def != code_env_def: result["changed"] = True if args.state == "absent" and exists: if exists: code_env.delete() module.exit_json(**result) except Exception as e: module.fail_json(msg="{}\n\n{}\n\n{}".format( str(e), traceback.format_exc(), "".join(traceback.format_stack())))