Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI(cv_deploy): Enhance logic and readability of cv_deploy molecule scenario #5034

Open
wants to merge 6 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 34 additions & 19 deletions ansible_collections/arista/avd/molecule/cv_deploy/cc_false.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- name: Converge - cv_run_change_control = false
- name: "{{ test_id | upper }} Converge - cv_run_change_control = false"
hosts: SITE1_FABRIC
connection: local
gather_facts: false
Expand All @@ -12,46 +12,56 @@
structured_dir: "{{ playbook_dir }}/intended/structured_configs/test_configs"
intended_tag_device: avd-ci-leaf1
intended_tags: "{{ lookup('file', structured_dir ~ '/' ~ intended_tag_device ~ '.yml')| from_yaml }}"
test_id: "force-ws-true_run-cc-false"
cv_common_pattern: "avd-cv-deploy_{{ test_id }}"

tasks:
- name: Generate random string
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"
- name: "{{ test_id | upper }} Banner"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.debug:
msg:
- "{{ ('#' * (31 + test_id | length))[:100] }}"
- "### STARTING MOLECULE TEST {{ test_id[:69] | upper }} ###"
- "{{ ('#' * (31 + test_id | length))[:100] }}"

- name: Set facts
ansible.builtin.set_fact:
cv_workspace_name: avd-cv-deploy-{{ r }}
cv_workspace_description: sample description
cv_change_control_name: cc_cv_deploy-{{ r }}
cv_change_control_description: sample description
cv_register_detailed_results: true
- name: "{{ test_id | upper }} Generate random string"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be best to set this as a play var all the way at the top? So we have a single ID per execution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree! Before this unique r was the only way to distinguish results of the different tests. Now all tests have unique names and having them share the same execution ID makes more sense.
I tried to implement it natively with molecule but faced issues here and there. Ended up implementing via externally-fed env which will be generated as a part of the CI pipeline.

New naming convention example (from last manual run):

avd_cv-deploy_scenario-cleanup_tg1b_cleanup
avd_cv-deploy_force-ws-true_run-cc-false_tg1b_cleanup
avd_cv-deploy_force-ws-true_run-cc-false_tg1b_converge
avd_cv-deploy_inactive-device_force-ws-false_tg1b_cleanup
avd_cv-deploy_inactive-device_force-ws-false_tg1b_converge
avd_cv-deploy_inactive-device_force-ws-true_tg1b_cleanup
avd_cv-deploy_inactive-device_force-ws-true_tg1b_converge
avd-cv-deploy_submit-ws-false_tg1b_cleanup
avd-cv-deploy_submit-ws-false_tg1b_converge
avd_cv-deploy_force-ws-true_run-cc-true_tg1b_cleanup
avd_cv-deploy_force-ws-true_run-cc-true_tg1b_converge

Same consistency is implemented in other scenarios that rely on cv_deploy


- name: Provision with cv_run_change_control = false
- name: "{{ test_id | upper }} Provision with cv_run_change_control = false"
tags: ["{{ test_id }}"]
run_once: true
delegate_to: localhost
ansible.builtin.import_role:
name: arista.avd.cv_deploy
vars:
cv_submit_workspace: true
cv_run_change_control: false
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"
cv_register_detailed_results: true
cv_submit_workspace_force: true

- name: Display CVP result
- name: "{{ test_id | upper }} Display CVP result"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.debug:
msg: '{{ cv_deploy_results }}'

- name: Check CVP returns
- name: "{{ test_id | upper }} Check CVP returns"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
# Change control
- cv_deploy_results.change_control.requested_state == "pending approval"
- cv_deploy_results.change_control.requested_state == cv_deploy_results.change_control.state

- name: Cleanup orphan CC
- name: "{{ test_id | upper }} Cleanup orphan CC"
tags: ["{{ test_id }}"]
run_once: true
ansible.legacy.uri:
url: https://{{ cv_server }}/api/resources/changecontrol/v1/ChangeControlConfig?key.id={{ cv_deploy_results.change_control.id }}
Expand All @@ -72,14 +82,19 @@
ignore_errors: true
when: cv_deploy_results.change_control.state | lower in ['pending approval', 'approved']

- name: Cleanup
- name: "{{ test_id | upper }} Cleanup"
tags: ["{{ test_id }}"]
run_once: true
delegate_to: localhost
ansible.builtin.import_role:
name: arista.avd.cv_deploy
vars:
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_register_detailed_results: true
eos_config_dir: "{{ playbook_dir }}/intended/configs/base_configs"
structured_dir: "{{ playbook_dir }}/intended/structured_configs/base_configs"
cv_submit_workspace: true
cv_submit_workspace_force: true
cv_run_change_control: true
43 changes: 31 additions & 12 deletions ansible_collections/arista/avd/molecule/cv_deploy/cleanup.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- name: Cleanup - Configuration deployment with CVP
- name: "{{ test_id | upper }} Cleanup - Configuration deployment with CVP"
hosts: SITE1_FABRIC
connection: local
gather_facts: false
Expand All @@ -10,29 +10,48 @@
cv_skip_missing_devices: true
eos_config_dir: "{{ playbook_dir }}/intended/configs/base_configs"
structured_dir: "{{ playbook_dir }}/intended/structured_configs/base_configs"
test_id: "global-scenario-cleanup"
cv_common_pattern: "avd-cv-deploy_{{ test_id }}"

tasks:
- name: Generate random string
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"
- name: "{{ test_id | upper }} Banner"
# Force task to run even if we used tags matching specific tests
tags: ["always"]
run_once: true
ansible.builtin.debug:
msg:
- "{{ ('#' * (17 + test_id | length))[:100] }}"
- "### STARTING {{ test_id[:83] | upper }} ###"
- "{{ ('#' * (17 + test_id | length))[:100] }}"

- name: Set facts
ansible.builtin.set_fact:
cv_workspace_name: avd-cv-deploy-cleanup-{{ r }}
cv_workspace_description: sample description
cv_change_control_name: cc_cv_deploy-cleanup-{{ r }}
cv_change_control_description: sample description
cv_register_detailed_results: true
- name: "{{ test_id | upper }} Generate random string"
# Force task to run even if we used tags matching specific tests
tags: ["always"]
run_once: true
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"

- name: Cleanup
- name: "{{ test_id | upper }} Cleanup"
# Force task to run even if we used tags matching specific tests
tags: ["always"]
run_once: true
delegate_to: localhost
ansible.builtin.import_role:
name: arista.avd.cv_deploy
vars:
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_register_detailed_results: true
cv_submit_workspace: true
cv_submit_workspace_force: true
cv_run_change_control: true
cv_strict_tags: true

- name: "{{ test_id | upper }} Display CVP result"
# Force task to run even if we used tags matching specific tests
tags: ["always"]
run_once: true
ansible.builtin.debug:
msg: '{{ cv_deploy_results }}'
86 changes: 56 additions & 30 deletions ansible_collections/arista/avd/molecule/cv_deploy/cv_deploy.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
- name: Converge - Configuration deployment with CVP
- name: "{{ test_id | upper }} Converge - Configuration deployment with CVP"
hosts: SITE1_FABRIC
connection: local
gather_facts: false
Expand All @@ -12,48 +12,55 @@
structured_dir: "{{ playbook_dir }}/intended/structured_configs/test_configs"
intended_tag_device: avd-ci-leaf1
intended_tags: "{{ lookup('file', structured_dir ~ '/' ~ intended_tag_device ~ '.yml')| from_yaml }}"
test_id: "force-ws-true_run-cc-true"
cv_common_pattern: "avd-cv-deploy_{{ test_id }}"

tasks:
- name: Generate random string
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"
- name: "{{ test_id | upper }} Banner"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.debug:
msg:
- "{{ ('#' * (31 + test_id | length))[:100] }}"
- "### STARTING MOLECULE TEST {{ test_id[:69] | upper }} ###"
- "{{ ('#' * (31 + test_id | length))[:100] }}"

- name: Set facts
ansible.builtin.set_fact:
cv_workspace_name: avd-cv-deploy-{{ r }}
cv_workspace_description: sample description
cv_change_control_name: cc_cv_deploy-{{ r }}
cv_change_control_description: sample description
cv_register_detailed_results: true
- name: "{{ test_id | upper }} Generate random string"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
r: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=4') }}"

###########################
######## cv_deploy ########
###########################
- name: Provision CVP with AVD configuration
- name: "{{ test_id | upper }} Provision CVP with AVD configuration"
tags: ["{{ test_id }}"]
run_once: true
delegate_to: localhost
ansible.builtin.import_role:
name: arista.avd.cv_deploy
vars:
cv_submit_workspace: true
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"
cv_register_detailed_results: true
cv_submit_workspace_force: true
cv_run_change_control: true
cv_register_detailed_results: true

- name: Display CVP result
- name: "{{ test_id | upper }} Display CVP result"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.debug:
msg: '{{ cv_deploy_results }}'

- name: Check CVP returns
- name: "{{ test_id | upper }} Check CVP returns"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
# workspace
- cv_deploy_results.workspace.name == cv_workspace_name
- cv_deploy_results.workspace.state == "submitted"
- cv_deploy_results.workspace.description == cv_workspace_description
- cv_deploy_results.workspace.state
# errors and warnings
- cv_deploy_results.errors == []
Expand All @@ -65,78 +72,97 @@
- cv_deploy_results.change_control.name == cv_change_control_name
- cv_deploy_results.change_control.requested_state == "completed"
- cv_deploy_results.change_control.description == cv_change_control_description
vars:
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_converge"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_converge') | upper }}"

- name: Check tags from output
- name: "{{ test_id | upper }} Check tags from output"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
- item.0.label == item.1.label
- item.0.value == item.1.value
loop: "{{ cv_deploy_results.deployed_device_tags | zip(cv_deploy_results.device_tags) | list }}"

- name: Extract all device tags from structured configs
- name: "{{ test_id | upper }} Extract all device tags from structured configs"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
expected_device_tags: "{{ intended_tags.metadata.cv_tags.device_tags }}"
output_device_tags: "{{ cv_deploy_results.deployed_device_tags }}"

- name: Check output device tags == intended device tags
- name: "{{ test_id | upper }} Check output device tags == intended device tags"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
- item.0.name == item.1.label
- item.0.value == item.1.value
loop: "{{ expected_device_tags | zip(output_device_tags) | list }}"

- name: Extract all interface tags from role output
- name: "{{ test_id | upper }} Extract all interface tags from role output"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
output_interface_tags: "{{ cv_deploy_results.deployed_interface_tags }}"

- name: Extract all interface tags from structured configs
- name: "{{ test_id | upper }} Extract all interface tags from structured configs"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
expected_interface_tags: "{{ expected_interface_tags | default([]) + [item.tags | list | first | combine({'interface': item.interface})] }}"
loop: "{{ intended_tags.metadata.cv_tags.interface_tags }}"
loop_control:
label: "{{ item.interface }}"

- name: Check output interface tags == intended interface tags
- name: "{{ test_id | upper }} Check output interface tags == intended interface tags"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
- item.0.name == item.1.label
- item.0.value == item.1.value
loop: "{{ expected_interface_tags | zip(output_interface_tags) | list }}"

- name: Convert unstructed data into yaml
- name: "{{ test_id | upper }} Convert unstructed data into yaml"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
deivces_structure: '{{ cv_deploy_results.deployed_configs | from_yaml }}'
output_devices: []

- name: Extract devices from output
- name: "{{ test_id | upper }} Extract devices from output"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.set_fact:
output_devices: "{{ output_devices + [item.device.hostname] }}"
loop: "{{ deivces_structure }}"
loop_control:
label: "{{ item.configlet_name }}"

- name: Check output devices == intended devices
- name: "{{ test_id | upper }} Check output devices == intended devices"
tags: ["{{ test_id }}"]
run_once: true
ansible.builtin.assert:
that:
- output_devices == cv_devices

- name: Cleanup
- name: "{{ test_id | upper }} Cleanup"
tags: ["{{ test_id }}"]
run_once: true
delegate_to: localhost
ansible.builtin.import_role:
name: arista.avd.cv_deploy
vars:
cv_workspace_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_workspace_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_change_control_name: "{{ cv_common_pattern }}_{{ r }}_cleanup"
cv_change_control_description: "{{ (cv_common_pattern + '_' + r + '_cleanup') | upper }}"
cv_register_detailed_results: true
eos_config_dir: "{{ playbook_dir }}/intended/configs/base_configs"
structured_dir: "{{ playbook_dir }}/intended/structured_configs/base_configs"
cv_submit_workspace: true
cv_submit_workspace_force: true
cv_run_change_control: true
Loading
Loading