mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-21 03:09:04 +00:00
Reformat everything.
This commit is contained in:
parent
3f2213791a
commit
340ff8586d
1008 changed files with 61301 additions and 58309 deletions
|
|
@ -291,22 +291,26 @@ module = None
|
|||
|
||||
|
||||
def get_version(bin_path):
|
||||
extract_version = module.run_command([bin_path, 'version', '-json'])
|
||||
terraform_version = (json.loads(extract_version[1]))['terraform_version']
|
||||
extract_version = module.run_command([bin_path, "version", "-json"])
|
||||
terraform_version = (json.loads(extract_version[1]))["terraform_version"]
|
||||
return terraform_version
|
||||
|
||||
|
||||
def preflight_validation(bin_path, project_path, version, variables_args=None, plan_file=None, no_color=True):
|
||||
if project_path is None or '/' not in project_path:
|
||||
if project_path is None or "/" not in project_path:
|
||||
module.fail_json(msg="Path for Terraform project can not be None or ''.")
|
||||
if not os.path.exists(bin_path):
|
||||
module.fail_json(msg=f"Path for Terraform binary '{bin_path}' doesn't exist on this host - check the path and try again please.")
|
||||
module.fail_json(
|
||||
msg=f"Path for Terraform binary '{bin_path}' doesn't exist on this host - check the path and try again please."
|
||||
)
|
||||
if not os.path.isdir(project_path):
|
||||
module.fail_json(msg=f"Path for Terraform project '{project_path}' doesn't exist on this host - check the path and try again please.")
|
||||
cmd = [bin_path, 'validate']
|
||||
module.fail_json(
|
||||
msg=f"Path for Terraform project '{project_path}' doesn't exist on this host - check the path and try again please."
|
||||
)
|
||||
cmd = [bin_path, "validate"]
|
||||
if no_color:
|
||||
cmd.append('-no-color')
|
||||
if LooseVersion(version) < LooseVersion('0.15.0'):
|
||||
cmd.append("-no-color")
|
||||
if LooseVersion(version) < LooseVersion("0.15.0"):
|
||||
module.run_command(cmd + variables_args, check_rc=True, cwd=project_path)
|
||||
else:
|
||||
module.run_command(cmd, check_rc=True, cwd=project_path)
|
||||
|
|
@ -316,81 +320,92 @@ def _state_args(state_file):
|
|||
if not state_file:
|
||||
return []
|
||||
if not os.path.exists(state_file):
|
||||
module.warn(f'Could not find state_file "{state_file}", the process will not destroy any resources, please check your state file path.')
|
||||
return ['-state', state_file]
|
||||
module.warn(
|
||||
f'Could not find state_file "{state_file}", the process will not destroy any resources, please check your state file path.'
|
||||
)
|
||||
return ["-state", state_file]
|
||||
|
||||
|
||||
def init_plugins(bin_path, project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths, workspace, no_color=True):
|
||||
command = [bin_path, 'init', '-input=false']
|
||||
def init_plugins(
|
||||
bin_path,
|
||||
project_path,
|
||||
backend_config,
|
||||
backend_config_files,
|
||||
init_reconfigure,
|
||||
provider_upgrade,
|
||||
plugin_paths,
|
||||
workspace,
|
||||
no_color=True,
|
||||
):
|
||||
command = [bin_path, "init", "-input=false"]
|
||||
if no_color:
|
||||
command.append('-no-color')
|
||||
command.append("-no-color")
|
||||
if backend_config:
|
||||
for key, val in backend_config.items():
|
||||
command.extend([
|
||||
'-backend-config',
|
||||
f'{key}={val}'
|
||||
])
|
||||
command.extend(["-backend-config", f"{key}={val}"])
|
||||
if backend_config_files:
|
||||
for f in backend_config_files:
|
||||
command.extend(['-backend-config', f])
|
||||
command.extend(["-backend-config", f])
|
||||
if init_reconfigure:
|
||||
command.extend(['-reconfigure'])
|
||||
command.extend(["-reconfigure"])
|
||||
if provider_upgrade:
|
||||
command.extend(['-upgrade'])
|
||||
command.extend(["-upgrade"])
|
||||
if plugin_paths:
|
||||
for plugin_path in plugin_paths:
|
||||
command.extend(['-plugin-dir', plugin_path])
|
||||
rc, out, err = module.run_command(command, check_rc=True, cwd=project_path, environ_update={"TF_WORKSPACE": workspace})
|
||||
command.extend(["-plugin-dir", plugin_path])
|
||||
rc, out, err = module.run_command(
|
||||
command, check_rc=True, cwd=project_path, environ_update={"TF_WORKSPACE": workspace}
|
||||
)
|
||||
|
||||
|
||||
def get_workspace_context(bin_path, project_path, no_color=True):
|
||||
workspace_ctx = {"current": "default", "all": []}
|
||||
command = [bin_path, 'workspace', 'list']
|
||||
command = [bin_path, "workspace", "list"]
|
||||
if no_color:
|
||||
command.append('-no-color')
|
||||
command.append("-no-color")
|
||||
|
||||
rc, out, err = module.run_command(command, cwd=project_path)
|
||||
if rc != 0:
|
||||
module.warn(f"Failed to list Terraform workspaces:\n{err}")
|
||||
for item in out.split('\n'):
|
||||
for item in out.split("\n"):
|
||||
stripped_item = item.strip()
|
||||
if not stripped_item:
|
||||
continue
|
||||
elif stripped_item.startswith('* '):
|
||||
workspace_ctx["current"] = stripped_item.replace('* ', '')
|
||||
workspace_ctx["all"].append(stripped_item.replace('* ', ''))
|
||||
elif stripped_item.startswith("* "):
|
||||
workspace_ctx["current"] = stripped_item.replace("* ", "")
|
||||
workspace_ctx["all"].append(stripped_item.replace("* ", ""))
|
||||
else:
|
||||
workspace_ctx["all"].append(stripped_item)
|
||||
return workspace_ctx
|
||||
|
||||
|
||||
def _workspace_cmd(bin_path, project_path, action, workspace, no_color=True):
|
||||
command = [bin_path, 'workspace', action, workspace]
|
||||
command = [bin_path, "workspace", action, workspace]
|
||||
if no_color:
|
||||
command.append('-no-color')
|
||||
command.append("-no-color")
|
||||
rc, out, err = module.run_command(command, check_rc=True, cwd=project_path)
|
||||
return rc, out, err
|
||||
|
||||
|
||||
def create_workspace(bin_path, project_path, workspace, no_color=True):
|
||||
_workspace_cmd(bin_path, project_path, 'new', workspace, no_color)
|
||||
_workspace_cmd(bin_path, project_path, "new", workspace, no_color)
|
||||
|
||||
|
||||
def select_workspace(bin_path, project_path, workspace, no_color=True):
|
||||
_workspace_cmd(bin_path, project_path, 'select', workspace, no_color)
|
||||
_workspace_cmd(bin_path, project_path, "select", workspace, no_color)
|
||||
|
||||
|
||||
def remove_workspace(bin_path, project_path, workspace, no_color=True):
|
||||
_workspace_cmd(bin_path, project_path, 'delete', workspace, no_color)
|
||||
_workspace_cmd(bin_path, project_path, "delete", workspace, no_color)
|
||||
|
||||
|
||||
def build_plan(command, project_path, variables_args, state_file, targets, state, args, plan_path=None, no_color=True):
|
||||
if plan_path is None:
|
||||
f, plan_path = tempfile.mkstemp(suffix='.tfplan')
|
||||
f, plan_path = tempfile.mkstemp(suffix=".tfplan")
|
||||
|
||||
local_command = command[:]
|
||||
|
||||
plan_command = [command[0], 'plan']
|
||||
plan_command = [command[0], "plan"]
|
||||
|
||||
if state == "planned":
|
||||
for c in local_command[1:]:
|
||||
|
|
@ -406,13 +421,13 @@ def build_plan(command, project_path, variables_args, state_file, targets, state
|
|||
for a in args:
|
||||
plan_command.append(a)
|
||||
|
||||
plan_options = ['-input=false', '-detailed-exitcode', '-out', plan_path]
|
||||
plan_options = ["-input=false", "-detailed-exitcode", "-out", plan_path]
|
||||
if no_color:
|
||||
plan_options.insert(0, '-no-color')
|
||||
plan_options.insert(0, "-no-color")
|
||||
plan_command.extend(plan_options)
|
||||
|
||||
for t in targets:
|
||||
plan_command.extend(['-target', t])
|
||||
plan_command.extend(["-target", t])
|
||||
|
||||
plan_command.extend(_state_args(state_file))
|
||||
|
||||
|
|
@ -420,30 +435,34 @@ def build_plan(command, project_path, variables_args, state_file, targets, state
|
|||
|
||||
if rc == 0:
|
||||
# no changes
|
||||
return plan_path, False, out, err, plan_command if state == 'planned' else command
|
||||
return plan_path, False, out, err, plan_command if state == "planned" else command
|
||||
elif rc == 1:
|
||||
# failure to plan
|
||||
module.fail_json(
|
||||
msg=(f"Terraform plan could not be created\nSTDOUT: {out}\nSTDERR: {err}\n"
|
||||
f"COMMAND: {' '.join(plan_command)} {' '.join([shlex_quote(arg) for arg in variables_args])}")
|
||||
msg=(
|
||||
f"Terraform plan could not be created\nSTDOUT: {out}\nSTDERR: {err}\n"
|
||||
f"COMMAND: {' '.join(plan_command)} {' '.join([shlex_quote(arg) for arg in variables_args])}"
|
||||
)
|
||||
)
|
||||
elif rc == 2:
|
||||
# changes, but successful
|
||||
return plan_path, True, out, err, plan_command if state == 'planned' else command
|
||||
return plan_path, True, out, err, plan_command if state == "planned" else command
|
||||
|
||||
module.fail_json(msg=f"Terraform plan failed with unexpected exit code {rc}.\nSTDOUT: {out}\nSTDERR: {err}\n"
|
||||
f"COMMAND: {' '.join(plan_command)} {' '.join([shlex_quote(arg) for arg in variables_args])}")
|
||||
module.fail_json(
|
||||
msg=f"Terraform plan failed with unexpected exit code {rc}.\nSTDOUT: {out}\nSTDERR: {err}\n"
|
||||
f"COMMAND: {' '.join(plan_command)} {' '.join([shlex_quote(arg) for arg in variables_args])}"
|
||||
)
|
||||
|
||||
|
||||
def get_diff(diff_output):
|
||||
def get_tf_resource_address(e):
|
||||
return e['resource']
|
||||
return e["resource"]
|
||||
|
||||
diff_json_output = json.loads(diff_output)
|
||||
|
||||
# Ignore diff if resource_changes does not exists in tfplan
|
||||
if 'resource_changes' in diff_json_output:
|
||||
tf_reosource_changes = diff_json_output['resource_changes']
|
||||
if "resource_changes" in diff_json_output:
|
||||
tf_reosource_changes = diff_json_output["resource_changes"]
|
||||
else:
|
||||
module.warn("Cannot find resource_changes in terraform plan, diff/check ignored")
|
||||
return False, {}
|
||||
|
|
@ -452,20 +471,20 @@ def get_diff(diff_output):
|
|||
diff_before = []
|
||||
changed = False
|
||||
for item in tf_reosource_changes:
|
||||
item_change = item['change']
|
||||
tf_before_state = {'resource': item['address'], 'change': item['change']['before']}
|
||||
tf_after_state = {'resource': item['address'], 'change': item['change']['after']}
|
||||
item_change = item["change"]
|
||||
tf_before_state = {"resource": item["address"], "change": item["change"]["before"]}
|
||||
tf_after_state = {"resource": item["address"], "change": item["change"]["after"]}
|
||||
|
||||
if item_change['actions'] == ['update'] or item_change['actions'] == ['delete', 'create']:
|
||||
if item_change["actions"] == ["update"] or item_change["actions"] == ["delete", "create"]:
|
||||
diff_before.append(tf_before_state)
|
||||
diff_after.append(tf_after_state)
|
||||
changed = True
|
||||
|
||||
if item_change['actions'] == ['delete']:
|
||||
if item_change["actions"] == ["delete"]:
|
||||
diff_before.append(tf_before_state)
|
||||
changed = True
|
||||
|
||||
if item_change['actions'] == ['create']:
|
||||
if item_change["actions"] == ["create"]:
|
||||
diff_after.append(tf_after_state)
|
||||
changed = True
|
||||
|
||||
|
|
@ -473,8 +492,8 @@ def get_diff(diff_output):
|
|||
diff_after.sort(key=get_tf_resource_address)
|
||||
|
||||
return changed, dict(
|
||||
before=({'data': diff_before}),
|
||||
after=({'data': diff_after}),
|
||||
before=({"data": diff_before}),
|
||||
after=({"data": diff_after}),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -482,79 +501,89 @@ def main():
|
|||
global module
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
project_path=dict(required=True, type='path'),
|
||||
binary_path=dict(type='path'),
|
||||
plugin_paths=dict(type='list', elements='path'),
|
||||
workspace=dict(type='str', default='default'),
|
||||
purge_workspace=dict(type='bool', default=False),
|
||||
state=dict(default='present', choices=['present', 'absent', 'planned']),
|
||||
variables=dict(type='dict'),
|
||||
complex_vars=dict(type='bool', default=False),
|
||||
variables_files=dict(aliases=['variables_file'], type='list', elements='path'),
|
||||
plan_file=dict(type='path'),
|
||||
state_file=dict(type='path'),
|
||||
targets=dict(type='list', elements='str', default=[]),
|
||||
lock=dict(type='bool', default=True),
|
||||
lock_timeout=dict(type='int'),
|
||||
force_init=dict(type='bool', default=False),
|
||||
backend_config=dict(type='dict'),
|
||||
backend_config_files=dict(type='list', elements='path'),
|
||||
init_reconfigure=dict(type='bool', default=False),
|
||||
overwrite_init=dict(type='bool', default=True),
|
||||
check_destroy=dict(type='bool', default=False),
|
||||
parallelism=dict(type='int'),
|
||||
provider_upgrade=dict(type='bool', default=False),
|
||||
no_color=dict(type='bool', default=True),
|
||||
project_path=dict(required=True, type="path"),
|
||||
binary_path=dict(type="path"),
|
||||
plugin_paths=dict(type="list", elements="path"),
|
||||
workspace=dict(type="str", default="default"),
|
||||
purge_workspace=dict(type="bool", default=False),
|
||||
state=dict(default="present", choices=["present", "absent", "planned"]),
|
||||
variables=dict(type="dict"),
|
||||
complex_vars=dict(type="bool", default=False),
|
||||
variables_files=dict(aliases=["variables_file"], type="list", elements="path"),
|
||||
plan_file=dict(type="path"),
|
||||
state_file=dict(type="path"),
|
||||
targets=dict(type="list", elements="str", default=[]),
|
||||
lock=dict(type="bool", default=True),
|
||||
lock_timeout=dict(type="int"),
|
||||
force_init=dict(type="bool", default=False),
|
||||
backend_config=dict(type="dict"),
|
||||
backend_config_files=dict(type="list", elements="path"),
|
||||
init_reconfigure=dict(type="bool", default=False),
|
||||
overwrite_init=dict(type="bool", default=True),
|
||||
check_destroy=dict(type="bool", default=False),
|
||||
parallelism=dict(type="int"),
|
||||
provider_upgrade=dict(type="bool", default=False),
|
||||
no_color=dict(type="bool", default=True),
|
||||
),
|
||||
required_if=[('state', 'planned', ['plan_file'])],
|
||||
required_if=[("state", "planned", ["plan_file"])],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
project_path = module.params.get('project_path')
|
||||
bin_path = module.params.get('binary_path')
|
||||
plugin_paths = module.params.get('plugin_paths')
|
||||
workspace = module.params.get('workspace')
|
||||
purge_workspace = module.params.get('purge_workspace')
|
||||
state = module.params.get('state')
|
||||
variables = module.params.get('variables') or {}
|
||||
complex_vars = module.params.get('complex_vars')
|
||||
variables_files = module.params.get('variables_files')
|
||||
plan_file = module.params.get('plan_file')
|
||||
state_file = module.params.get('state_file')
|
||||
force_init = module.params.get('force_init')
|
||||
backend_config = module.params.get('backend_config')
|
||||
backend_config_files = module.params.get('backend_config_files')
|
||||
init_reconfigure = module.params.get('init_reconfigure')
|
||||
overwrite_init = module.params.get('overwrite_init')
|
||||
check_destroy = module.params.get('check_destroy')
|
||||
provider_upgrade = module.params.get('provider_upgrade')
|
||||
no_color = module.params.get('no_color')
|
||||
project_path = module.params.get("project_path")
|
||||
bin_path = module.params.get("binary_path")
|
||||
plugin_paths = module.params.get("plugin_paths")
|
||||
workspace = module.params.get("workspace")
|
||||
purge_workspace = module.params.get("purge_workspace")
|
||||
state = module.params.get("state")
|
||||
variables = module.params.get("variables") or {}
|
||||
complex_vars = module.params.get("complex_vars")
|
||||
variables_files = module.params.get("variables_files")
|
||||
plan_file = module.params.get("plan_file")
|
||||
state_file = module.params.get("state_file")
|
||||
force_init = module.params.get("force_init")
|
||||
backend_config = module.params.get("backend_config")
|
||||
backend_config_files = module.params.get("backend_config_files")
|
||||
init_reconfigure = module.params.get("init_reconfigure")
|
||||
overwrite_init = module.params.get("overwrite_init")
|
||||
check_destroy = module.params.get("check_destroy")
|
||||
provider_upgrade = module.params.get("provider_upgrade")
|
||||
no_color = module.params.get("no_color")
|
||||
|
||||
if bin_path is not None:
|
||||
command = [bin_path]
|
||||
else:
|
||||
command = [module.get_bin_path('terraform', required=True)]
|
||||
command = [module.get_bin_path("terraform", required=True)]
|
||||
|
||||
checked_version = get_version(command[0])
|
||||
|
||||
if LooseVersion(checked_version) < LooseVersion('0.15.0'):
|
||||
if LooseVersion(checked_version) < LooseVersion("0.15.0"):
|
||||
if no_color:
|
||||
DESTROY_ARGS = ('destroy', '-no-color', '-force')
|
||||
APPLY_ARGS = ('apply', '-no-color', '-input=false', '-auto-approve=true')
|
||||
DESTROY_ARGS = ("destroy", "-no-color", "-force")
|
||||
APPLY_ARGS = ("apply", "-no-color", "-input=false", "-auto-approve=true")
|
||||
else:
|
||||
DESTROY_ARGS = ('destroy', '-force')
|
||||
APPLY_ARGS = ('apply', '-input=false', '-auto-approve=true')
|
||||
DESTROY_ARGS = ("destroy", "-force")
|
||||
APPLY_ARGS = ("apply", "-input=false", "-auto-approve=true")
|
||||
else:
|
||||
if no_color:
|
||||
DESTROY_ARGS = ('destroy', '-no-color', '-auto-approve')
|
||||
APPLY_ARGS = ('apply', '-no-color', '-input=false', '-auto-approve')
|
||||
DESTROY_ARGS = ("destroy", "-no-color", "-auto-approve")
|
||||
APPLY_ARGS = ("apply", "-no-color", "-input=false", "-auto-approve")
|
||||
else:
|
||||
DESTROY_ARGS = ('destroy', '-auto-approve')
|
||||
APPLY_ARGS = ('apply', '-input=false', '-auto-approve')
|
||||
DESTROY_ARGS = ("destroy", "-auto-approve")
|
||||
APPLY_ARGS = ("apply", "-input=false", "-auto-approve")
|
||||
|
||||
if force_init:
|
||||
if overwrite_init or not os.path.isfile(os.path.join(project_path, ".terraform", "terraform.tfstate")):
|
||||
init_plugins(command[0], project_path, backend_config, backend_config_files, init_reconfigure, provider_upgrade, plugin_paths, workspace, no_color)
|
||||
init_plugins(
|
||||
command[0],
|
||||
project_path,
|
||||
backend_config,
|
||||
backend_config_files,
|
||||
init_reconfigure,
|
||||
provider_upgrade,
|
||||
plugin_paths,
|
||||
workspace,
|
||||
no_color,
|
||||
)
|
||||
|
||||
workspace_ctx = get_workspace_context(command[0], project_path, no_color)
|
||||
if workspace_ctx["current"] != workspace:
|
||||
|
|
@ -563,24 +592,24 @@ def main():
|
|||
else:
|
||||
select_workspace(command[0], project_path, workspace, no_color)
|
||||
|
||||
if state == 'present':
|
||||
if state == "present":
|
||||
command.extend(APPLY_ARGS)
|
||||
elif state == 'absent':
|
||||
elif state == "absent":
|
||||
command.extend(DESTROY_ARGS)
|
||||
|
||||
if state == 'present' and module.params.get('parallelism') is not None:
|
||||
if state == "present" and module.params.get("parallelism") is not None:
|
||||
command.append(f"-parallelism={module.params.get('parallelism')}")
|
||||
|
||||
def format_args(vars):
|
||||
if vars is None:
|
||||
return 'null'
|
||||
return "null"
|
||||
elif isinstance(vars, str):
|
||||
return '"{string}"'.format(string=vars.replace('\\', '\\\\').replace('"', '\\"')).replace('\n', '\\n')
|
||||
return '"{string}"'.format(string=vars.replace("\\", "\\\\").replace('"', '\\"')).replace("\n", "\\n")
|
||||
elif isinstance(vars, bool):
|
||||
if vars:
|
||||
return 'true'
|
||||
return "true"
|
||||
else:
|
||||
return 'false'
|
||||
return "false"
|
||||
return str(vars)
|
||||
|
||||
def process_complex_args(vars):
|
||||
|
|
@ -588,14 +617,16 @@ def main():
|
|||
if isinstance(vars, dict):
|
||||
for k, v in vars.items():
|
||||
if isinstance(v, dict):
|
||||
ret_out.append(f'{k}={{{process_complex_args(v)}}}')
|
||||
ret_out.append(f"{k}={{{process_complex_args(v)}}}")
|
||||
elif isinstance(v, list):
|
||||
ret_out.append(f"{k}={process_complex_args(v)}")
|
||||
elif isinstance(v, (int, float, str, bool)) or v is None:
|
||||
ret_out.append(f'{k}={format_args(v)}')
|
||||
ret_out.append(f"{k}={format_args(v)}")
|
||||
else:
|
||||
# only to handle anything unforeseen
|
||||
module.fail_json(msg="Supported types are, dictionaries, lists, strings, integers, boolean and float.")
|
||||
module.fail_json(
|
||||
msg="Supported types are, dictionaries, lists, strings, integers, boolean and float."
|
||||
)
|
||||
if isinstance(vars, list):
|
||||
l_out = []
|
||||
for item in vars:
|
||||
|
|
@ -607,7 +638,9 @@ def main():
|
|||
l_out.append(format_args(item))
|
||||
else:
|
||||
# only to handle anything unforeseen
|
||||
module.fail_json(msg="Supported types are, dictionaries, lists, strings, integers, boolean and float.")
|
||||
module.fail_json(
|
||||
msg="Supported types are, dictionaries, lists, strings, integers, boolean and float."
|
||||
)
|
||||
|
||||
ret_out.append(f"[{','.join(l_out)}]")
|
||||
return ",".join(ret_out)
|
||||
|
|
@ -616,136 +649,154 @@ def main():
|
|||
if complex_vars:
|
||||
for k, v in variables.items():
|
||||
if isinstance(v, dict):
|
||||
variables_args.extend([
|
||||
'-var',
|
||||
f'{k}={{{process_complex_args(v)}}}'
|
||||
])
|
||||
variables_args.extend(["-var", f"{k}={{{process_complex_args(v)}}}"])
|
||||
elif isinstance(v, list):
|
||||
variables_args.extend([
|
||||
'-var',
|
||||
f'{k}={process_complex_args(v)}'
|
||||
])
|
||||
variables_args.extend(["-var", f"{k}={process_complex_args(v)}"])
|
||||
# on the top-level we need to pass just the python string with necessary
|
||||
# terraform string escape sequences
|
||||
elif isinstance(v, str):
|
||||
variables_args.extend([
|
||||
'-var',
|
||||
f"{k}={v}"
|
||||
])
|
||||
variables_args.extend(["-var", f"{k}={v}"])
|
||||
else:
|
||||
variables_args.extend([
|
||||
'-var',
|
||||
f'{k}={format_args(v)}'
|
||||
])
|
||||
variables_args.extend(["-var", f"{k}={format_args(v)}"])
|
||||
else:
|
||||
for k, v in variables.items():
|
||||
variables_args.extend([
|
||||
'-var',
|
||||
f'{k}={v}'
|
||||
])
|
||||
variables_args.extend(["-var", f"{k}={v}"])
|
||||
|
||||
if variables_files:
|
||||
for f in variables_files:
|
||||
variables_args.extend(['-var-file', f])
|
||||
variables_args.extend(["-var-file", f])
|
||||
|
||||
preflight_validation(command[0], project_path, checked_version, variables_args, plan_file, no_color)
|
||||
|
||||
if module.params.get('lock') is not None:
|
||||
if module.params.get('lock'):
|
||||
command.append('-lock=true')
|
||||
if module.params.get("lock") is not None:
|
||||
if module.params.get("lock"):
|
||||
command.append("-lock=true")
|
||||
else:
|
||||
command.append('-lock=false')
|
||||
if module.params.get('lock_timeout') is not None:
|
||||
command.append("-lock=false")
|
||||
if module.params.get("lock_timeout") is not None:
|
||||
command.append(f"-lock-timeout={module.params.get('lock_timeout')}s")
|
||||
|
||||
for t in (module.params.get('targets') or []):
|
||||
command.extend(['-target', t])
|
||||
for t in module.params.get("targets") or []:
|
||||
command.extend(["-target", t])
|
||||
|
||||
# we aren't sure if this plan will result in changes, so assume yes
|
||||
needs_application, changed = True, False
|
||||
|
||||
out, err = '', ''
|
||||
out, err = "", ""
|
||||
|
||||
if state == 'absent':
|
||||
if state == "absent":
|
||||
command.extend(variables_args)
|
||||
elif state == 'present' and plan_file:
|
||||
elif state == "present" and plan_file:
|
||||
if any([os.path.isfile(f"{project_path}/{plan_file}"), os.path.isfile(plan_file)]):
|
||||
command.append(plan_file)
|
||||
else:
|
||||
module.fail_json(msg=f'Could not find plan_file "{plan_file}", check the path and try again.')
|
||||
else:
|
||||
plan_file, needs_application, out, err, command = build_plan(command, project_path, variables_args, state_file,
|
||||
module.params.get('targets'), state, APPLY_ARGS, plan_file, no_color)
|
||||
if state == 'present' and check_destroy and '- destroy' in out:
|
||||
module.fail_json(msg="Aborting command because it would destroy some resources. "
|
||||
"Consider switching the 'check_destroy' to false to suppress this error")
|
||||
plan_file, needs_application, out, err, command = build_plan(
|
||||
command,
|
||||
project_path,
|
||||
variables_args,
|
||||
state_file,
|
||||
module.params.get("targets"),
|
||||
state,
|
||||
APPLY_ARGS,
|
||||
plan_file,
|
||||
no_color,
|
||||
)
|
||||
if state == "present" and check_destroy and "- destroy" in out:
|
||||
module.fail_json(
|
||||
msg="Aborting command because it would destroy some resources. "
|
||||
"Consider switching the 'check_destroy' to false to suppress this error"
|
||||
)
|
||||
command.append(plan_file)
|
||||
|
||||
result_diff = dict()
|
||||
if module._diff or module.check_mode:
|
||||
if state == 'absent':
|
||||
plan_absent_args = ['-destroy']
|
||||
plan_file, needs_application, out, err, command = build_plan(command, project_path, variables_args, state_file,
|
||||
module.params.get('targets'), state, plan_absent_args, plan_file, no_color)
|
||||
diff_command = [command[0], 'show', '-json', plan_file]
|
||||
if state == "absent":
|
||||
plan_absent_args = ["-destroy"]
|
||||
plan_file, needs_application, out, err, command = build_plan(
|
||||
command,
|
||||
project_path,
|
||||
variables_args,
|
||||
state_file,
|
||||
module.params.get("targets"),
|
||||
state,
|
||||
plan_absent_args,
|
||||
plan_file,
|
||||
no_color,
|
||||
)
|
||||
diff_command = [command[0], "show", "-json", plan_file]
|
||||
rc, diff_output, err = module.run_command(diff_command, check_rc=False, cwd=project_path)
|
||||
changed, result_diff = get_diff(diff_output)
|
||||
if rc != 0:
|
||||
if workspace_ctx["current"] != workspace:
|
||||
select_workspace(command[0], project_path, workspace_ctx["current"], no_color)
|
||||
module.fail_json(msg=err.rstrip(), rc=rc, stdout=out,
|
||||
stdout_lines=out.splitlines(), stderr=err,
|
||||
stderr_lines=err.splitlines(),
|
||||
cmd=' '.join(command))
|
||||
module.fail_json(
|
||||
msg=err.rstrip(),
|
||||
rc=rc,
|
||||
stdout=out,
|
||||
stdout_lines=out.splitlines(),
|
||||
stderr=err,
|
||||
stderr_lines=err.splitlines(),
|
||||
cmd=" ".join(command),
|
||||
)
|
||||
|
||||
if needs_application and not module.check_mode and state != 'planned':
|
||||
if needs_application and not module.check_mode and state != "planned":
|
||||
rc, out, err = module.run_command(command, check_rc=False, cwd=project_path)
|
||||
if rc != 0:
|
||||
if workspace_ctx["current"] != workspace:
|
||||
select_workspace(command[0], project_path, workspace_ctx["current"], no_color)
|
||||
module.fail_json(msg=err.rstrip(), rc=rc, stdout=out,
|
||||
stdout_lines=out.splitlines(), stderr=err,
|
||||
stderr_lines=err.splitlines(),
|
||||
cmd=' '.join(command))
|
||||
module.fail_json(
|
||||
msg=err.rstrip(),
|
||||
rc=rc,
|
||||
stdout=out,
|
||||
stdout_lines=out.splitlines(),
|
||||
stderr=err,
|
||||
stderr_lines=err.splitlines(),
|
||||
cmd=" ".join(command),
|
||||
)
|
||||
# checks out to decide if changes were made during execution
|
||||
if ' 0 added, 0 changed' not in out and not state == "absent" or ' 0 destroyed' not in out:
|
||||
if " 0 added, 0 changed" not in out and not state == "absent" or " 0 destroyed" not in out:
|
||||
changed = True
|
||||
|
||||
if no_color:
|
||||
outputs_command = [command[0], 'output', '-no-color', '-json'] + _state_args(state_file)
|
||||
outputs_command = [command[0], "output", "-no-color", "-json"] + _state_args(state_file)
|
||||
else:
|
||||
outputs_command = [command[0], 'output', '-json'] + _state_args(state_file)
|
||||
outputs_command = [command[0], "output", "-json"] + _state_args(state_file)
|
||||
|
||||
rc, outputs_text, outputs_err = module.run_command(outputs_command, cwd=project_path)
|
||||
outputs = {}
|
||||
if rc == 1:
|
||||
module.warn(f"Could not get Terraform outputs. This usually means none have been defined.\nstdout: {outputs_text}\nstderr: {outputs_err}")
|
||||
module.warn(
|
||||
f"Could not get Terraform outputs. This usually means none have been defined.\nstdout: {outputs_text}\nstderr: {outputs_err}"
|
||||
)
|
||||
elif rc != 0:
|
||||
module.fail_json(
|
||||
msg=f"Failure when getting Terraform outputs. Exited {rc}.\nstdout: {outputs_text}\nstderr: {outputs_err}",
|
||||
command=' '.join(outputs_command))
|
||||
command=" ".join(outputs_command),
|
||||
)
|
||||
else:
|
||||
outputs = json.loads(outputs_text)
|
||||
|
||||
# Restore the Terraform workspace found when running the module
|
||||
if workspace_ctx["current"] != workspace:
|
||||
select_workspace(command[0], project_path, workspace_ctx["current"], no_color)
|
||||
if state == 'absent' and workspace != 'default' and purge_workspace is True:
|
||||
if state == "absent" and workspace != "default" and purge_workspace is True:
|
||||
remove_workspace(command[0], project_path, workspace, no_color)
|
||||
|
||||
result = {
|
||||
'state': state,
|
||||
'workspace': workspace,
|
||||
'outputs': outputs,
|
||||
'stdout': out,
|
||||
'stderr': err,
|
||||
'command': ' '.join(command),
|
||||
'changed': changed,
|
||||
'diff': result_diff,
|
||||
"state": state,
|
||||
"workspace": workspace,
|
||||
"outputs": outputs,
|
||||
"stdout": out,
|
||||
"stderr": err,
|
||||
"command": " ".join(command),
|
||||
"changed": changed,
|
||||
"diff": result_diff,
|
||||
}
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue