diff --git a/jenkins/ci.suse.de/pipelines/openstack-ardana.Jenkinsfile b/jenkins/ci.suse.de/pipelines/openstack-ardana.Jenkinsfile index 490e660d72..50bba8a6df 100644 --- a/jenkins/ci.suse.de/pipelines/openstack-ardana.Jenkinsfile +++ b/jenkins/ci.suse.de/pipelines/openstack-ardana.Jenkinsfile @@ -213,6 +213,17 @@ pipeline { } } + stage('Prepare Ardana') { + steps { + script { + ardana_lib.ansible_playbook('ardana-init') + } + script { + ardana_lib.ansible_playbook('ardana-lint') + } + } + } + stage('Deploy cloud') { when { expression { deploy_cloud == 'true' } diff --git a/scripts/jenkins/ardana/ansible/ardana-init.yml b/scripts/jenkins/ardana/ansible/ardana-init.yml new file mode 100644 index 0000000000..87a04938dc --- /dev/null +++ b/scripts/jenkins/ardana/ansible/ardana-init.yml @@ -0,0 +1,39 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +--- + +- name: Configure ardana + hosts: "{{ ardana_env }}" + remote_user: ardana + gather_facts: True + + tasks: + - block: + - name: Remove versioned features from input model when not enabled + replace: + path: "{{ input_model_path }}/data/control_plane.yml" + regexp: '(.*{{ item }}.*)' + replace: '#\1' + when: not versioned_features[item].enabled + delegate_to: localhost + loop: + - manila + - freezer + - heat-api-cloudwatch + + - include_role: + name: ardana_init diff --git a/scripts/jenkins/ardana/ansible/ardana-lint.yml b/scripts/jenkins/ardana/ansible/ardana-lint.yml new file mode 100644 index 0000000000..0e829f6c18 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/ardana-lint.yml @@ -0,0 +1,27 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +--- + +- name: Run lint on ardana + hosts: "{{ ardana_env }}" + remote_user: ardana + gather_facts: True + + tasks: + - block: + - include_role: + name: ardana_lint diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/defaults/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_deploy/defaults/main.yml index 232240e782..ae07f5cc7b 100644 --- a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/defaults/main.yml +++ b/scripts/jenkins/ardana/ansible/roles/ardana_deploy/defaults/main.yml @@ -18,10 +18,6 @@ ardana_openstack_path: "~/openstack/ardana/ansible" ardana_scratch_path: "~/scratch/ansible/next/ardana/ansible" -ardana_openstack_playbooks: - - "config-processor-run.yml -e encrypt='' -e rekey=''" - - "ready-deployment.yml" - ardana_scratch_playbooks: - play: "ardana-ssh-keyscan.yml" when: "{{ is_physical_deploy and when_cloud9 }}" @@ -29,3 +25,4 @@ ardana_scratch_playbooks: when: "{{ is_physical_deploy }}" - play: "site.yml" - play: "ardana-cloud-configure.yml" + diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/main.yml index a003fd68cf..174909bd7e 100644 --- a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/main.yml +++ b/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/main.yml @@ -15,67 +15,6 @@ # --- -- name: Run ardana-init - command: "ardana-init" - environment: - ARDANA_INIT_AUTO: 1 - -- name: Copy ardana input model - copy: - src: "{{ input_model_path }}/" - dest: "~/openstack/my_cloud/definition" - register: input_model - -- name: Change VRRP offset - replace: - path: "~/openstack/ardana/ansible/roles/keepalived/defaults/main.yml" - regexp: "keepalived_vrrp_offset: 0" - replace: "keepalived_vrrp_offset: {{ vrrp_offset }}" - register: vrrp - when: is_physical_deploy - -- name: Commit changes - shell: | - git add -A - git commit -m 'Add input model' - args: - chdir: "{{ ardana_openstack_path }}" - when: input_model.changed or vrrp.changed - -- include_tasks: setup_ses_config.yml - when: ses_enabled - -- name: Run playbooks from "{{ ardana_openstack_path }}" - command: "ansible-playbook -i hosts/localhost {{ item }}" - args: - chdir: "{{ ardana_openstack_path }}" - loop: "{{ ardana_openstack_playbooks }}" - register: ansible_openstack_plays - when: not (ansible_openstack_plays | default({})) is failed - -- include_tasks: setup_rhel_repo.yml - when: rhel_enabled - -- include_tasks: reimage_nodes.yml - when: is_physical_deploy - -- name: Import Devel:Cloud:X key when cloudsource is staging or devel - shell: "ansible {{ item }} resources" - args: - chdir: "{{ ardana_scratch_path }}" - environment: - ANSIBLE_HOST_KEY_CHECKING: False - ANSIBLE_SSH_ARGS: '-o UserKnownHostsFile=/dev/null' - loop: - - '-m copy -a "src=`find /srv/www/*/x86_64/repos/*Cloud* -name content.key` dest=/tmp/"' - - '-b -a "rpm --import /tmp/content.key"' - when: "'staging' in cloudsource or 'devel' in cloudsource" - -- include_tasks: setup_mu_repos.yml - when: - - not update_after_deploy - - maint_updates_list | length - - name: Run playbooks from "{{ ardana_scratch_path }}" command: "ansible-playbook {{ item.play }}" args: diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_init/defaults/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/defaults/main.yml new file mode 100644 index 0000000000..79e3ad617a --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_init/defaults/main.yml @@ -0,0 +1,23 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +--- + +ardana_openstack_path: "~/openstack/ardana/ansible" +ardana_scratch_path: "~/scratch/ansible/next/ardana/ansible" + +ardana_openstack_playbooks: + - "config-processor-run.yml -e encrypt='' -e rekey=''" + - "ready-deployment.yml" diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/main.yml new file mode 100644 index 0000000000..34fb525d7e --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/main.yml @@ -0,0 +1,77 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +--- + +- name: Run ardana-init + command: "ardana-init" + environment: + ARDANA_INIT_AUTO: 1 + +- name: Copy ardana input model + copy: + src: "{{ input_model_path }}/" + dest: "~/openstack/my_cloud/definition" + register: input_model + +- name: Change VRRP offset + replace: + path: "~/openstack/ardana/ansible/roles/keepalived/defaults/main.yml" + regexp: "keepalived_vrrp_offset: 0" + replace: "keepalived_vrrp_offset: {{ vrrp_offset }}" + register: vrrp + when: is_physical_deploy + +- name: Commit changes + shell: | + git add -A + git commit -m 'Add input model' + args: + chdir: "{{ ardana_openstack_path }}" + when: input_model.changed or vrrp.changed + +- include_tasks: setup_ses_config.yml + when: ses_enabled + +- name: Run playbooks from "{{ ardana_openstack_path }}" + command: "ansible-playbook -i hosts/localhost {{ item }}" + args: + chdir: "{{ ardana_openstack_path }}" + loop: "{{ ardana_openstack_playbooks }}" + register: ansible_openstack_plays + when: not (ansible_openstack_plays | default({})) is failed + +- include_tasks: setup_rhel_repo.yml + when: rhel_enabled + +- include_tasks: reimage_nodes.yml + when: is_physical_deploy + +- name: Import Devel:Cloud:X key when cloudsource is staging or devel + shell: "ansible {{ item }} resources" + args: + chdir: "{{ ardana_scratch_path }}" + environment: + ANSIBLE_HOST_KEY_CHECKING: False + ANSIBLE_SSH_ARGS: '-o UserKnownHostsFile=/dev/null' + loop: + - '-m copy -a "src=`find /srv/www/*/x86_64/repos/*Cloud* -name content.key` dest=/tmp/"' + - '-b -a "rpm --import /tmp/content.key"' + when: "'staging' in cloudsource or 'devel' in cloudsource" + +- include_tasks: setup_mu_repos.yml + when: + - not update_after_deploy + - maint_updates_list | length diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/reimage_nodes.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/reimage_nodes.yml similarity index 100% rename from scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/reimage_nodes.yml rename to scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/reimage_nodes.yml diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_mu_repos.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_mu_repos.yml similarity index 100% rename from scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_mu_repos.yml rename to scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_mu_repos.yml diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_rhel_repo.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_rhel_repo.yml similarity index 100% rename from scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_rhel_repo.yml rename to scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_rhel_repo.yml diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_ses_config.yml b/scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_ses_config.yml similarity index 100% rename from scripts/jenkins/ardana/ansible/roles/ardana_deploy/tasks/setup_ses_config.yml rename to scripts/jenkins/ardana/ansible/roles/ardana_init/tasks/setup_ses_config.yml diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/defaults/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_lint/defaults/main.yml new file mode 100644 index 0000000000..9326ea4668 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/defaults/main.yml @@ -0,0 +1,22 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +--- + +lint_venv: "/tmp/ansible-lint" +ardana_scratch_path: "/var/lib/ardana/scratch/ansible/next/ardana/ansible" +lint_params: '-p -x templating,resources,ANSIBLE0002 -r {{ lint_venv }}/lint-rules -r {{ lint_venv }}/lib/python2.7/site-packages/ansiblelint/rules' + +lint_path: "{{ ardana_scratch_path }}" diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/__init__.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_action_name_should_match_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_action_name_should_match_rule.py new file mode 100644 index 0000000000..6ff02c8a4d --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_action_name_should_match_rule.py @@ -0,0 +1,52 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import os +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaActionNameShouldMatchRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0006' + shortdesc = 'Action name should match $role | $task | description' + description = 'Action name should match $role | $task | description' + tags = ['formatting'] + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + if 'name' in task: + filename = file['path'] + # ignore handlers + if 'handlers' in filename: + return False + if 'role' in filename: + task_name = os.path.splitext(os.path.basename(filename))[0] + dirs = filename.split('/') + role = dirs[len(dirs) - 3] + return not task['name'].startswith("%s | %s" % (role, + task_name)) + return False + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_action_name_should_match_rule(ArdanaActionNameShouldMatchRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_arrays_multiline_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_arrays_multiline_rule.py new file mode 100644 index 0000000000..ba2017392c --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_arrays_multiline_rule.py @@ -0,0 +1,56 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaArraysMultilineRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0004' + shortdesc = 'Arrays should use the multi-line array syntax' + description = ('Arrays should use the multi-line array syntax.\n' + 'Incorrect:\n' + ' my_array: -foo -bar -buzz\n' + 'Incorrect:\n' + ' my_array:\n' + ' - foo - bar - buzz\n' + 'Correct:\n' + ' my_array:\n' + ' - foo\n' + ' - bar\n' + ' - buzz') + tags = ['formatting'] + pattern_strings = [ + '\w+:\s*-', + '^(\s+-\s*\w+){2,}$'] + patterns = '|'.join(pattern_strings) + pattern = re.compile(patterns) + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return self.pattern.search(line) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_arrays_multiline_rule(ArdanaArraysMultilineRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_exclude_vim_directives_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_exclude_vim_directives_rule.py new file mode 100644 index 0000000000..e1fb8e4ad5 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_exclude_vim_directives_rule.py @@ -0,0 +1,40 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaExcludeVimDirectivesRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0013' + shortdesc = 'Exclude vim directives.' + description = 'Vim directives should not be included.' + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return '# vim:' in line + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_exclude_vim_directives_rule(ArdanaExcludeVimDirectivesRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_forbidden_commands_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_forbidden_commands_rule.py new file mode 100644 index 0000000000..5935d1001f --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_forbidden_commands_rule.py @@ -0,0 +1,44 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaForbiddenCommandsRule(AnsibleLintRule): + id = "ARDANAANSIBLE0001" + shortdesc = "Forbid pip usage in Ardana" + description = "'pip' usage is forbidden in Ardana" + tags = ["forbidden"] + + _modules = ["pip"] + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + if task["action"]["module"] in self._modules: + message = "{0} usage is forbidden" + return message.format(task["action"]["module"]) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_forbidden_commands_rule(ArdanaForbiddenCommandsRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_followed_by_space_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_followed_by_space_rule.py new file mode 100644 index 0000000000..9362131717 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_followed_by_space_rule.py @@ -0,0 +1,51 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaHyphenFollowedBySpaceRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0017' + shortdesc = 'WARNING Element hyphen should be followed by a space.' + description = ('WARNING Element hyphen should be followed by a single ' + 'space. \n' + 'Incorrect:\n' + ' -foo\n' + 'Incorrect:\n' + ' - foo\n' + 'Correct:\n' + ' - foo\n' + 'Note: This is a WARNING only as there are cases where' + ' this syntax cannot be avoided.') + tags = ['formatting', 'warning'] + pattern = re.compile('^\s*(-(|\s{2,})\w+)+') + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return self.pattern.search(line) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_hyphen_followed_by_space_rule(ArdanaHyphenFollowedBySpaceRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_on_same_line_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_on_same_line_rule.py new file mode 100644 index 0000000000..f7c07ae099 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_hyphen_on_same_line_rule.py @@ -0,0 +1,40 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaHyphenOnSameLineRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0012' + shortdesc = 'Hyphen should be on same line as element.' + description = 'Hyphen should be on same line as element.' + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return line.strip() == '-' + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_hyphen_on_same_line_rule(ArdanaHyphenOnSameLineRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_indents_x_two_spaces_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_indents_x_two_spaces_rule.py new file mode 100644 index 0000000000..9309960cc5 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_indents_x_two_spaces_rule.py @@ -0,0 +1,37 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaIndentsXTwoSpacesRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0002' + shortdesc = 'Indents must be a multiple of two spaces.' + description = 'Indents must be a multiple of two spaces.' + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + leading_spaces = len(line) - len(line.lstrip(' ')) + return leading_spaces % 2 + + +class ardana_indents_x_two_spaces_rule(ArdanaIndentsXTwoSpacesRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_line_length_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_line_length_rule.py new file mode 100644 index 0000000000..3058e3e467 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_line_length_rule.py @@ -0,0 +1,41 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaLineLengthRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0003' + shortdesc = 'WARNING - Line length > 80 chars' + description = 'Attempt to keep all lines shorter than 80 characters ' + \ + 'wide.\nBreak long lines using YAML Line continuation.' + tags = ['formatting', 'warning'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return len(line) > 80 + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_line_length_rule(ArdanaLineLengthRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_lowercase_variables_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_lowercase_variables_rule.py new file mode 100644 index 0000000000..44e304e0aa --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_lowercase_variables_rule.py @@ -0,0 +1,81 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaLowercaseVariablesRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0007' + shortdesc = ('Variables must match pattern, be lowercase or' + ' be derived from a function') + description = ('Variables must follow one of the patterns:\n' + ' anycase.advertises_anycase.lowercase\n' + ' anycase.consumes_anycase.lowercase\n' + ' anycase.vars.lowercase\n' + ' lowercase\n' + 'All variables in role tasks must be lowercase.\n' + 'CP variables must be aliased in defaults/main.yml\n' + 'If a function is being used to generate a variable\n' + 'it is exempt from these rules.') + tags = ['formatting'] + variables = re.compile(r"{{ ([^}]+?)(\s*\|[^}]+)* }}") + up = "[A-Z_0-9]*" + lo = "[a-z_0-9]*" + subscript = "(?:\[[^]]+\])?" + either = "(?:%s|%s)" % (up, lo) + lo_sub = lo + subscript + many_lo_sub = '(?:%s\.)*%s' % (lo_sub, lo_sub) + pattern_strings = [ + '%s\.advertises\.%s' % (either, many_lo_sub), + '%s\.consumes_%s\.%s' % (either, either, many_lo_sub), + '%s\.vars\.(%s)' % (either, lo_sub), + '%sverb_hosts\.(%s)' % (either, lo_sub), + many_lo_sub] + patterns = '|'.join(pattern_strings) + pattern = re.compile("^%s$" % patterns) + functions = '[a-z]+\(.*?\)' + function = re.compile(functions) + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + role = 'roles' in file['path'] + for variable in self.variables.finditer(line): + matches_patterns = self.pattern.match(variable.group(1)) + if role: + if self.function.match(variable.group(1)): + return False + if variable.group(1) != variable.group(1).lower(): + if matches_patterns: + return "CP vars must be aliased in defaults/main.yml" + else: + return True + else: + if not matches_patterns: + return True + return False + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_lowercase_variables_rule(ArdanaLowercaseVariablesRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_mode_octal_or_symbolic_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_mode_octal_or_symbolic_rule.py new file mode 100644 index 0000000000..e234ce07b3 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_mode_octal_or_symbolic_rule.py @@ -0,0 +1,90 @@ +# +# (c) Copyright 2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017-2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaModeOctalOrSymbolicRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0011' + shortdesc = 'mode must be symbolic, variable or a 4-digit octal' + description = ('mode must be specified for file, copy and template tasks, ' + 'and it must be either symbolic (e.g. "u=rw,g=r,o=r"), ' + 'a variable (e.g. "{{ mode }}"), ' + 'a 4-digit octal (e.g. 0700, "0700"), ' + 'or a 5-digit octal (e.g. 01770) if sticky bit is set') + tags = ['formatting'] + _commands = ['file', 'copy', 'template'] + _ignore_states = ['absent', 'link'] + + @staticmethod + def validate_mode(mode): + def is_octal_string(string): + return re.match('^0[0-7]+', string) + + def is_valid_octal_mode(string): + if len(string) == 4: + return re.match('^0[0-7]?[0-7]?[0-7]?$', string) + else: + # If this is not a 4-digit octal, we are assuming user + # is specifying the sticky bit. + # The second number must be 1 for sticky bit + return re.match('^01[0-7]?[0-7]?[0-7]?$', string) + + def is_valid_symbolic_mode(string): + parts = string.split(',') + for part in parts: + # NOTE(gyee): This should match the most popular symbolic + # representations out there. 't' matches sticky bit and 'X' + # matches special execute bit. See + # https://en.wikipedia.org/wiki/Chmod + if not re.match('^[ugoa]*[+-=]?[rwxXt]+$', part): + return False + return True + + if is_octal_string(mode): + return not is_valid_octal_mode(mode) + else: + return not is_valid_symbolic_mode(mode) + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + action = task["action"] + if action["module"] in self._commands: + if action.get("state") in self._ignore_states: + return False + if "mode" not in action: + return True + mode = action.get("mode") + if isinstance(mode, int): + mode = "%04o" % mode + if not isinstance(mode, str): + return True + if mode.startswith("{{"): + return False + return self.validate_mode(mode) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_mode_octal_or_symbolic_rule(ArdanaModeOctalOrSymbolicRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_no_spaces_inside_square_brackets.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_no_spaces_inside_square_brackets.py new file mode 100644 index 0000000000..c4fe3ff689 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_no_spaces_inside_square_brackets.py @@ -0,0 +1,42 @@ +# +# (c) Copyright 2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaNoSpacesInSquareBrackets(AnsibleLintRule): + id = 'ARDANAANSIBLE0018' + shortdesc = 'Avoid white space inside square brackets' + description = ('General convention is not to use spaces inside ' + 'the square brackets.') + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return re.search("\[ | \]", line) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_no_spaces_inside_square_brackets(ArdanaNoSpacesInSquareBrackets): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_noqa.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_noqa.py new file mode 100644 index 0000000000..fdd4fb63e9 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_noqa.py @@ -0,0 +1,55 @@ +# +# (c) Copyright 2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import collections +import re + +from ansiblelint import AnsibleLintRule + + +_NOQA = collections.defaultdict(lambda: False) + + +def skip_match(file, line=None): + """Support noqa line comments and blocks (noqa-on / noqa-off). + + The block markers must be on their own lines to maximise clarity and + minimise any risk of accidents. + """ + global _NOQA + filename = file.get('path') + noqa = _NOQA[filename] + # matchtask rules don't have a line to check + if not line: + return noqa + if re.match('\s*#\s+noqa-on', line): + _NOQA[filename] = True + return True + elif re.match('\s*#\s+noqa-off', line): + _NOQA[filename] = False + return True + elif re.search('#\s+noqa', line): + return True + return noqa + + +# ansible-lint falls over if any file in this dir doesn't contain a rule +class ardana_noqa(AnsibleLintRule): + id = 'noqa' + shortdesc = 'noqa' + description = 'noqa' + tags = [] diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_reg_vars_end_in_result_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_reg_vars_end_in_result_rule.py new file mode 100644 index 0000000000..e0936c94b2 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_reg_vars_end_in_result_rule.py @@ -0,0 +1,56 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaRegVarsEndInResultRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0009' + shortdesc = ('Registered variables must end in _result ' + 'unless prefixed with ardana_notify') + description = ('Registered variables must end in _result\n' + '\te.g. foo_result\n' + 'or be prefixed with "ardana_notify_"\n' + '\te.g. ardana_notify_foo') + tags = ['formatting'] + + @staticmethod + def validate_variable(var): + return (not var.endswith('_result') and + not var.startswith('ardana_notify_')) + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + if 'register' in task: + if isinstance(task['register'], list): + for item in task['register']: + if self.validate_variable(item): + return True + return False + else: + return self.validate_variable(task['register']) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_reg_vars_end_in_result_rule(ArdanaRegVarsEndInResultRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_spaces_around_variables_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_spaces_around_variables_rule.py new file mode 100644 index 0000000000..ce9bba1473 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_spaces_around_variables_rule.py @@ -0,0 +1,41 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaSpacesAroundVariablesRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0008' + shortdesc = 'Missing spaces around variable name' + description = 'Use spaces around variable names e.g. "{{ variable }}"' + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return re.search("{{[^ ]|[^ ]}}", line) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_spaces_around_variables_rule(ArdanaSpacesAroundVariablesRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_shell_command_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_shell_command_rule.py new file mode 100644 index 0000000000..65ae2510e1 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_shell_command_rule.py @@ -0,0 +1,45 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaSudoInShellCommandRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0014' + shortdesc = 'Using sudo in shell command' + description = 'Using sudo while executing a command' + tags = ['formatting'] + + _commands = ['command', 'shell'] + _modules = {'sudo': 'sudo'} + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + if task["action"]["module"] in self._commands: + executable = task["action"]["module_arguments"][0] + return executable in self._modules + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_sudo_in_shell_command_rule(ArdanaSudoInShellCommandRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_top_level_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_top_level_rule.py new file mode 100644 index 0000000000..21b4be14dc --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_in_top_level_rule.py @@ -0,0 +1,43 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +# only need to look for 'become' as sudo is deprecated so +# an error will be generated to catch use of sudo +class ArdanaSudoInTopLevelRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0016' + shortdesc = 'WARNING - become in a top level play affects performance.' + description = 'Using become in a top level play affects performance.' + tags = ['formatting', 'warning'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + if 'roles/' not in file['path']: + return 'become: yes' in line + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_sudo_in_top_level_rule(ArdanaSudoInTopLevelRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_is_deprecated_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_is_deprecated_rule.py new file mode 100644 index 0000000000..5c2ba6f9d7 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_sudo_is_deprecated_rule.py @@ -0,0 +1,40 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaSudoIsDeprecatedRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0015' + shortdesc = 'sudo is deprecated - use "become"' + description = 'As of 1.9 "become" supersedes the the old sudo/su.' + tags = ['formatting'] + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + return 'sudo:' in line + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_sudo_is_deprecated_rule(ArdanaSudoIsDeprecatedRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_unnamed_task_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_unnamed_task_rule.py new file mode 100644 index 0000000000..19b591760d --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_unnamed_task_rule.py @@ -0,0 +1,40 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaUnnamedTaskRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0005' + shortdesc = 'Unnamed Task' + description = 'All actions must have a name.' + tags = ['formatting'] + + def matchtask(self, file, task): + if sys.modules['ardana_noqa'].skip_match(file): + return False + return 'name' not in task + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_unnamed_task_rule(ArdanaUnnamedTaskRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_use_key_value_syntax_rule.py b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_use_key_value_syntax_rule.py new file mode 100644 index 0000000000..4fa35af506 --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/files/lint-rules/ardana_use_key_value_syntax_rule.py @@ -0,0 +1,49 @@ +# +# (c) Copyright 2015-2016 Hewlett Packard Enterprise Development LP +# (c) Copyright 2017 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import re +import sys + +from ansiblelint import AnsibleLintRule + + +class ArdanaUseKeyValueSyntaxRule(AnsibleLintRule): + id = 'ARDANAANSIBLE0010' + shortdesc = 'WARNING Use key(colon) value syntax for yaml dictionaries' + description = ('Use key: value syntax.\n' + 'Correct:\n' + ' key: value\n' + 'Incorrect:\n' + ' key=value' + 'Note: This is a WARNING only as there are cases where' + ' this syntax cannot be avoided.') + tags = ['formatting', 'warning'] + pattern = re.compile(r'\s*["\']?\w+["\']?\s*=(?!=)') + + def match(self, file, line): + if sys.modules['ardana_noqa'].skip_match(file, line): + return False + if '=' in line: + return self.pattern.match(line) + + +# ansible-lint expects the filename and class name to match +# Python style expects filenames to be all lowercase +# Python style expects classnames to be CamelCase +# Resolution: trick ansible lint with this class +class ardana_use_key_value_syntax_rule(ArdanaUseKeyValueSyntaxRule): + pass diff --git a/scripts/jenkins/ardana/ansible/roles/ardana_lint/tasks/main.yml b/scripts/jenkins/ardana/ansible/roles/ardana_lint/tasks/main.yml new file mode 100644 index 0000000000..90c7fd873e --- /dev/null +++ b/scripts/jenkins/ardana/ansible/roles/ardana_lint/tasks/main.yml @@ -0,0 +1,48 @@ +# +# (c) Copyright 2018 SUSE LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +--- +- block: + - name: Install ansible-lint + pip: + name: 'ansible-lint==2.1.3' + virtualenv: '{{ lint_venv }}' + virtualenv_site_packages: true + extra_args: --no-deps + + - name: Install Ardana linting rules + synchronize: + delete: true + src: lint-rules + dest: "{{ lint_venv }}/lint-rules" + + - name: Find ansible files under "{{ lint_path }}" + command: > + find "{{ lint_path }}" -type f + -name _ardana-base*yml -or -name client*yml -or + -name *ceilometer*.yml -or -name *FND-AP2*.yml -or + -name *FND-CLU*.yml -or -name *glance*.yml -or + -name *heat*.yml -or -name *magnum*.yml -or + -name *monasca-transform*.yml -or -name *nova*.yml -or + -name *percona*.yml -or -name *rabbitmq*.yml -or + -name *spark*.yml -or -name *tls*.yml + register: _lint_files + #TODO: run on all yml files. The current file list is copied from + # ardana-dev-tools, and any other files are not yet expected to pass linting. + failed_when: _lint_files | length == 0 + # Fail if no files were found + + - name: Run ansible-lint on the files found + command: "{{ lint_venv }}/bin/ansible-lint {{ lint_params }} {{ _lint_files.stdout }}"