diff --git a/changelogs/fragments/1197_gitlab_project_variable.yml b/changelogs/fragments/1197_gitlab_project_variable.yml new file mode 100644 index 0000000000..e95d6b95da --- /dev/null +++ b/changelogs/fragments/1197_gitlab_project_variable.yml @@ -0,0 +1,2 @@ +minor_changes: +- gitlab_project_variable - add support for ``environment_scope`` on projects variables (https://github.com/ansible-collections/community.general/pull/1197). diff --git a/plugins/modules/source_control/gitlab/gitlab_project_variable.py b/plugins/modules/source_control/gitlab/gitlab_project_variable.py index 9803f76bc8..2ca788a194 100644 --- a/plugins/modules/source_control/gitlab/gitlab_project_variable.py +++ b/plugins/modules/source_control/gitlab/gitlab_project_variable.py @@ -54,6 +54,7 @@ options: - Support for masked values requires GitLab >= 11.10. - A I(value) must be a string or a number. - Field I(variable_type) must be a string with either C(env_var), which is the default, or C(file). + - Field I(environment_scope) must be a string defined by scope environment. - When a value is masked, it must be in Base64 and have a length of at least 8 characters. See GitLab documentation on acceptable values for a masked variable (https://docs.gitlab.com/ce/ci/variables/#masked-variables). default: {} @@ -85,6 +86,7 @@ EXAMPLES = ''' masked: true protected: true variable_type: env_var + environment_scope: '*' - name: Delete one variable community.general.gitlab_project_variable: @@ -164,27 +166,36 @@ class GitlabProjectVariables(object): vars_page = self.project.variables.list(page=page_nb) return variables - def create_variable(self, key, value, masked, protected, variable_type): + def create_variable(self, key, value, masked, protected, variable_type, environment_scope): if self._module.check_mode: return - return self.project.variables.create({"key": key, "value": value, - "masked": masked, "protected": protected, - "variable_type": variable_type}) + var = { + "key": key, "value": value, + "masked": masked, "protected": protected, + "variable_type": variable_type + } + if environment_scope is not None: + var["environment_scope"] = environment_scope + return self.project.variables.create(var) - def update_variable(self, key, var, value, masked, protected, variable_type): - if var.value == value and var.protected == protected and var.masked == masked and var.variable_type == variable_type: + def update_variable(self, key, var, value, masked, protected, variable_type, environment_scope): + if (var.value == value and var.protected == protected and var.masked == masked + and var.variable_type == variable_type + and (var.environment_scope == environment_scope or environment_scope is None)): return False if self._module.check_mode: return True - if var.protected == protected and var.masked == masked and var.variable_type == variable_type: + if (var.protected == protected and var.masked == masked + and var.variable_type == variable_type + and (var.environment_scope == environment_scope or environment_scope is None)): var.value = value var.save() return True self.delete_variable(key) - self.create_variable(key, value, masked, protected, variable_type) + self.create_variable(key, value, masked, protected, variable_type, environment_scope) return True def delete_variable(self, key): @@ -208,11 +219,13 @@ def native_python_main(this_gitlab, purge, var_list, state, module): masked = False protected = False variable_type = 'env_var' + environment_scope = None elif isinstance(var_list[key], dict): value = var_list[key].get('value') masked = var_list[key].get('masked', False) protected = var_list[key].get('protected', False) variable_type = var_list[key].get('variable_type', 'env_var') + environment_scope = var_list[key].get('environment_scope') else: module.fail_json(msg="value must be of type string, integer or dict") @@ -225,7 +238,8 @@ def native_python_main(this_gitlab, purge, var_list, state, module): gitlab_keys[index], value, masked, protected, - variable_type) + variable_type, + environment_scope) change = single_change or change if single_change: return_value['updated'].append(key) @@ -238,7 +252,7 @@ def native_python_main(this_gitlab, purge, var_list, state, module): return_value['removed'].append(key) elif key not in existing_variables and state == 'present': - this_gitlab.create_variable(key, value, masked, protected, variable_type) + this_gitlab.create_variable(key, value, masked, protected, variable_type, environment_scope) change = True return_value['added'].append(key) diff --git a/tests/integration/targets/gitlab_project_variable/tasks/main.yml b/tests/integration/targets/gitlab_project_variable/tasks/main.yml index 2b29619f45..0c1535fd30 100644 --- a/tests/integration/targets/gitlab_project_variable/tasks/main.yml +++ b/tests/integration/targets/gitlab_project_variable/tasks/main.yml @@ -218,6 +218,36 @@ that: - gitlab_project_variable_state is not changed +- name: change environment scope + gitlab_project_variable: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + project: "{{ gitlab_project_name }}" + vars: + ACCESS_KEY_ID: + environment_scope: testing + register: gitlab_project_variable_state + +- name: state must be changed + assert: + that: + - gitlab_project_variable_state is changed + +- name: apply again the environment scope change + gitlab_project_variable: + api_url: "{{ gitlab_host }}" + api_token: "{{ gitlab_login_token }}" + project: "{{ gitlab_project_name }}" + vars: + ACCESS_KEY_ID: + environment_scope: testing + register: gitlab_project_variable_state + +- name: state must not be changed + assert: + that: + - gitlab_project_variable_state is not changed + - name: purge all variables at the beginning gitlab_project_variable: api_url: "{{ gitlab_host }}"