From d8c9a84075499330ff8dbdadf7de7ce91492aeda Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 4 Apr 2024 18:46:46 +0200 Subject: [PATCH 01/20] Add support for Azure deployment --- README.md | 30 +-- ...s_20_12.yml => aws_deploy_controllers.yml} | 2 +- ...y_edges_20_12.yml => aws_deploy_edges.yml} | 2 +- ...g_20_12.yml => aws_sdwan_config_20_12.yml} | 10 +- ...g_20_13.yml => aws_sdwan_config_20_13.yml} | 9 +- ...rdown_20_12.yml => aws_teardown_20_12.yml} | 2 +- ..._edges.yml => aws_teardown_only_edges.yml} | 2 +- playbooks/azure_deploy_controllers.yml | 12 + playbooks/azure_deploy_edges.yml | 11 + playbooks/azure_sdwan_config.yml | 112 +++++++++ playbooks/azure_teardown.yml | 24 ++ playbooks/deploy_controllers_20_13.yml | 9 - playbooks/teardown_20_13.yml | 10 - requirements.txt | 60 ++--- .../aws_wait_for_instances_readiness.yml | 15 -- roles/aws_controllers/tasks/main.yml | 16 +- .../templates/userdata_vbond.j2 | 8 +- .../templates/userdata_vmanage.j2 | 9 +- .../templates/userdata_vsmart.j2 | 8 +- .../aws_wait_for_instances_readiness.yml | 15 -- roles/aws_edges/tasks/main.yml | 21 +- .../defaults/main.yml | 3 - .../aws_network_infrastructure/tasks/main.yml | 4 +- roles/azure/tasks/main.yml | 46 ---- roles/azure_controllers/defaults/main.yml | 88 +++++++ roles/azure_controllers/handlers/main.yml | 6 + roles/azure_controllers/meta/main.yml | 3 + .../tasks/azure_vbond_vm.yml | 177 ++++++++++++++ .../tasks/azure_vmanage_vm.yml | 170 +++++++++++++ .../tasks/azure_vsmart_vm.yml | 164 +++++++++++++ .../tasks/generate_deployment_facts.yml | 10 +- roles/azure_controllers/tasks/main.yml | 93 +++++++ .../templates/userdata_vbond.j2 | 89 +++++++ .../templates/userdata_vmanage.j2 | 108 ++++++++ .../templates/userdata_vsmart.j2 | 87 +++++++ roles/azure_controllers/vars/main.yml | 14 ++ roles/azure_edges/defaults/main.yml | 68 ++++++ roles/azure_edges/handlers/main.yml | 6 + roles/azure_edges/meta/main.yml | 3 + roles/azure_edges/tasks/azure_cedge_vm.yml | 163 ++++++++++++ roles/azure_edges/tasks/main.yml | 71 ++++++ roles/azure_edges/templates/userdata_cedge.j2 | 231 ++++++++++++++++++ roles/azure_edges/vars/main.yml | 12 + .../defaults/main.yml | 40 +++ .../meta/main.yml | 3 + .../tasks/azure_network_infrastructure.yml | 81 ++++++ .../tasks/main.yml | 23 ++ .../vars/main.yml | 8 + roles/azure_teardown/defaults/main.yml | 20 ++ roles/azure_teardown/meta/main.yml | 3 + roles/azure_teardown/tasks/az_teardown_rg.yml | 7 + roles/azure_teardown/tasks/main.yml | 10 + ....yml => aws_required_vars_controllers.yml} | 0 ..._edges.yml => aws_required_vars_edges.yml} | 0 ..._required_vars_network_infrastructure.yml} | 0 .../defaults/az_required_vars_controllers.yml | 13 + .../defaults/az_required_vars_edges.yml | 17 ++ ...z_required_vars_network_infrastructure.yml | 10 + roles/common/tasks/az_existing_instances.yml | 59 +++++ roles/common/tasks/az_user_session_probe.yml | 19 ++ .../generate_deployment_facts_controllers.yml | 42 ++++ .../generate_deployment_facts_edges.yml} | 0 ...d_variables.yml => required_variables.yml} | 0 roles/common/tasks/wait_for_ssh_readiness.yml | 16 ++ roles/template_cloudinit/defaults/main.yml | 50 ++++ roles/template_cloudinit/meta/main.yml | 1 + .../tasks/aws_vbond_cloudinit.yml | 17 ++ .../tasks/aws_vmanage_cloudinit.yml | 16 ++ .../tasks/aws_vsmart_ec2_instance.yml | 180 ++++++++++++++ roles/template_cloudinit/tasks/main.yml | 61 +++++ .../templates/userdata_vbond.j2 | 81 ++++++ .../templates/userdata_vmanage.j2 | 105 ++++++++ .../templates/userdata_vsmart.j2 | 79 ++++++ roles/template_cloudinit/vars/main.yml | 18 ++ 74 files changed, 2789 insertions(+), 193 deletions(-) rename playbooks/{deploy_controllers_20_12.yml => aws_deploy_controllers.yml} (82%) rename playbooks/{deploy_edges_20_12.yml => aws_deploy_edges.yml} (81%) rename playbooks/{sdwan_config_20_12.yml => aws_sdwan_config_20_12.yml} (91%) rename playbooks/{sdwan_config_20_13.yml => aws_sdwan_config_20_13.yml} (91%) rename playbooks/{teardown_20_12.yml => aws_teardown_20_12.yml} (75%) rename playbooks/{teardown_only_edges.yml => aws_teardown_only_edges.yml} (83%) create mode 100644 playbooks/azure_deploy_controllers.yml create mode 100644 playbooks/azure_deploy_edges.yml create mode 100644 playbooks/azure_sdwan_config.yml create mode 100644 playbooks/azure_teardown.yml delete mode 100644 playbooks/deploy_controllers_20_13.yml delete mode 100644 playbooks/teardown_20_13.yml delete mode 100644 roles/aws_controllers/tasks/aws_wait_for_instances_readiness.yml delete mode 100644 roles/aws_edges/tasks/aws_wait_for_instances_readiness.yml delete mode 100644 roles/azure/tasks/main.yml create mode 100644 roles/azure_controllers/defaults/main.yml create mode 100644 roles/azure_controllers/handlers/main.yml create mode 100644 roles/azure_controllers/meta/main.yml create mode 100644 roles/azure_controllers/tasks/azure_vbond_vm.yml create mode 100644 roles/azure_controllers/tasks/azure_vmanage_vm.yml create mode 100644 roles/azure_controllers/tasks/azure_vsmart_vm.yml rename roles/{aws_controllers => azure_controllers}/tasks/generate_deployment_facts.yml (82%) create mode 100644 roles/azure_controllers/tasks/main.yml create mode 100644 roles/azure_controllers/templates/userdata_vbond.j2 create mode 100644 roles/azure_controllers/templates/userdata_vmanage.j2 create mode 100644 roles/azure_controllers/templates/userdata_vsmart.j2 create mode 100644 roles/azure_controllers/vars/main.yml create mode 100644 roles/azure_edges/defaults/main.yml create mode 100644 roles/azure_edges/handlers/main.yml create mode 100644 roles/azure_edges/meta/main.yml create mode 100644 roles/azure_edges/tasks/azure_cedge_vm.yml create mode 100644 roles/azure_edges/tasks/main.yml create mode 100644 roles/azure_edges/templates/userdata_cedge.j2 create mode 100644 roles/azure_edges/vars/main.yml create mode 100644 roles/azure_network_infrastructure/defaults/main.yml create mode 100644 roles/azure_network_infrastructure/meta/main.yml create mode 100644 roles/azure_network_infrastructure/tasks/azure_network_infrastructure.yml create mode 100644 roles/azure_network_infrastructure/tasks/main.yml create mode 100644 roles/azure_network_infrastructure/vars/main.yml create mode 100644 roles/azure_teardown/defaults/main.yml create mode 100644 roles/azure_teardown/meta/main.yml create mode 100644 roles/azure_teardown/tasks/az_teardown_rg.yml create mode 100644 roles/azure_teardown/tasks/main.yml rename roles/common/defaults/{required_vars_controllers.yml => aws_required_vars_controllers.yml} (100%) rename roles/common/defaults/{required_vars_edges.yml => aws_required_vars_edges.yml} (100%) rename roles/common/defaults/{required_vars_network_infrastructure.yml => aws_required_vars_network_infrastructure.yml} (100%) create mode 100644 roles/common/defaults/az_required_vars_controllers.yml create mode 100644 roles/common/defaults/az_required_vars_edges.yml create mode 100644 roles/common/defaults/az_required_vars_network_infrastructure.yml create mode 100644 roles/common/tasks/az_existing_instances.yml create mode 100644 roles/common/tasks/az_user_session_probe.yml create mode 100644 roles/common/tasks/generate_deployment_facts_controllers.yml rename roles/{aws_edges/tasks/generate_deployment_facts.yml => common/tasks/generate_deployment_facts_edges.yml} (100%) rename roles/common/tasks/{aws_required_variables.yml => required_variables.yml} (100%) create mode 100644 roles/common/tasks/wait_for_ssh_readiness.yml create mode 100644 roles/template_cloudinit/defaults/main.yml create mode 100644 roles/template_cloudinit/meta/main.yml create mode 100644 roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml create mode 100644 roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml create mode 100644 roles/template_cloudinit/tasks/aws_vsmart_ec2_instance.yml create mode 100644 roles/template_cloudinit/tasks/main.yml create mode 100644 roles/template_cloudinit/templates/userdata_vbond.j2 create mode 100644 roles/template_cloudinit/templates/userdata_vmanage.j2 create mode 100644 roles/template_cloudinit/templates/userdata_vsmart.j2 create mode 100644 roles/template_cloudinit/vars/main.yml diff --git a/README.md b/README.md index c2e17e6..7567d41 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Path of this output file customizable via `results_dir` `results_path_controller Current coverage: - [x] Deployment on AWS +- [x] Deployment on Azure - [x] Deployment of: - [x] vManage - [x] vBond @@ -49,16 +50,16 @@ Current coverage: - [x] cEdge - [x] Local installation via Ansible Galaxy - [x] Installation via git repository link +- [x] Migration to CiscoDevNet/Cisco Open Future Goals: - [ ] Provide AWX (web-based user interface) -- [ ] Migrate to CiscoDevNet/Cisco Open - [ ] Share roles via Ansible Galaxy -- [ ] Deployment on Azure - [ ] Deployment on GCP - [ ] Support for cluster deployment - [ ] Enhance cloud-init configuration (complex bringup) +- [ ] Separate roles for cloudinit templating --- @@ -80,18 +81,18 @@ Before you begin, ensure you have met the following requirements: In `requirements.yml` inside your project add: ```yml -- name: git@github.com:cisco-open/ansible-collection-sdwan-deployment.git +- name: git@sdwan-git.cisco.com:sdwan-tools/cisco.sdwan_deployment.git type: git version: main ``` -Note: If you are not using full ansible installation, you might install also aws.collection by adding: +Note: If you are not using full ansible installation, you might install also `aws.collection` and `azure.azcollection` by adding: ```yml -- name: amazon.aws - version: 6.5.0 -- name: azure.azcollection - version: 1.19.0 + - name: amazon.aws + version: 6.5.0 + - name: azure.azcollection + version: 1.19.0 ``` to `requirements.yml` inside your project. @@ -116,9 +117,9 @@ pip install -r requirements.txt There are configuration files which has been initially filled with values: -- `.playbooks/sdwan_config_20_12.yml` +- `.playbooks/aws_sdwan_config_20_12.yml` -- `.playbooks/sdwan_config_20_13.yml` +- `.playbooks/aws_sdwan_config_20_13.yml` Both files are supplemented by config from `roles/aws_*/vars/example_main.yml` and defaults from `roles/aws_*/defaults/main.yml` @@ -133,13 +134,13 @@ NOTE: You can call the variables file any name, but remember to choose one optio - aws_network_infrastructure - aws_controllers vars_files: - - ./playbooks/sdwan_config_20_12.yml + - ./playbooks/aws_sdwan_config_20_12.yml ``` - or pass the variables by directly including your configuration file with: ```bash -ansible-playbook playbooks/deploy_controllers_20_12.yml -e "@./playbooks/sdwan_config_20_12.yml" +ansible-playbook playbooks/aws_deploy_controllers_20_12.yml -e "@./playbooks/aws_sdwan_config_20_12.yml" ``` (notice @ that suggest we are reffering to the file) @@ -222,8 +223,9 @@ If vManage is not starting NMS service: ## Compatibility -We are supporting python3.8 currently. -Ansible-lint is 6.11 +Note that azure collection python requirements include package `uamqp` which can generate wheel issues. +For MacOS you need to install cmake: `brew install cmake` and: `pip install cmake`. +Then install working `uamqp` package (which is below `v1.6.9`) with: `pip install uamqp==1.6.8`. --- diff --git a/playbooks/deploy_controllers_20_12.yml b/playbooks/aws_deploy_controllers.yml similarity index 82% rename from playbooks/deploy_controllers_20_12.yml rename to playbooks/aws_deploy_controllers.yml index 4342b4e..3c2d2f0 100644 --- a/playbooks/deploy_controllers_20_12.yml +++ b/playbooks/aws_deploy_controllers.yml @@ -6,4 +6,4 @@ - aws_network_infrastructure - aws_controllers vars_files: - ./sdwan_config_20_12.yml + ./aws_sdwan_config_20_12.yml diff --git a/playbooks/deploy_edges_20_12.yml b/playbooks/aws_deploy_edges.yml similarity index 81% rename from playbooks/deploy_edges_20_12.yml rename to playbooks/aws_deploy_edges.yml index 20bedeb..8d20e60 100644 --- a/playbooks/deploy_edges_20_12.yml +++ b/playbooks/aws_deploy_edges.yml @@ -6,4 +6,4 @@ roles: - aws_edges vars_files: - ./sdwan_config_20_12.yml + ./aws_sdwan_config_20_12.yml diff --git a/playbooks/sdwan_config_20_12.yml b/playbooks/aws_sdwan_config_20_12.yml similarity index 91% rename from playbooks/sdwan_config_20_12.yml rename to playbooks/aws_sdwan_config_20_12.yml index 8e95509..5bc9971 100644 --- a/playbooks/sdwan_config_20_12.yml +++ b/playbooks/aws_sdwan_config_20_12.yml @@ -6,7 +6,14 @@ organization_name: null - +# aws_allowed_subnets is list of subnets, that are allowed to access your instances via security group in AWS +# See https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html to learn more +# +# example configuration is: +# aws_allowed_subnets: +# - 15.15.0.0/16 +# - 10.10.0.0/16 +aws_allowed_subnets: null ##################################### # General AWS configuration # @@ -51,6 +58,7 @@ aws_key_name: null + ########################################## # SD-WAN Instances configuration # ########################################## diff --git a/playbooks/sdwan_config_20_13.yml b/playbooks/aws_sdwan_config_20_13.yml similarity index 91% rename from playbooks/sdwan_config_20_13.yml rename to playbooks/aws_sdwan_config_20_13.yml index 389a855..19b3aa2 100644 --- a/playbooks/sdwan_config_20_13.yml +++ b/playbooks/aws_sdwan_config_20_13.yml @@ -6,7 +6,14 @@ organization_name: null - +# aws_allowed_subnets is list of subnets, that are allowed to access your instances via security group in AWS +# See https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html to learn more +# +# example configuration is: +# aws_allowed_subnets: +# - 15.15.0.0/16 +# - 10.10.0.0/16 +aws_allowed_subnets: null ##################################### # General AWS configuration # diff --git a/playbooks/teardown_20_12.yml b/playbooks/aws_teardown_20_12.yml similarity index 75% rename from playbooks/teardown_20_12.yml rename to playbooks/aws_teardown_20_12.yml index 165c275..d25af0a 100644 --- a/playbooks/teardown_20_12.yml +++ b/playbooks/aws_teardown_20_12.yml @@ -1,5 +1,5 @@ --- -- name: Teardown Cisco SD-WAN versions 20.13 on AWS +- name: Teardown Cisco SD-WAN versions 20.12 on AWS hosts: localhost gather_facts: false roles: diff --git a/playbooks/teardown_only_edges.yml b/playbooks/aws_teardown_only_edges.yml similarity index 83% rename from playbooks/teardown_only_edges.yml rename to playbooks/aws_teardown_only_edges.yml index 0ad21cc..8ba9c42 100644 --- a/playbooks/teardown_only_edges.yml +++ b/playbooks/aws_teardown_only_edges.yml @@ -6,5 +6,5 @@ roles: - aws_teardown vars_files: - - ./sdwan_config.yml + - ./aws_sdwan_config_20_12.yml - ./specific_edges_to_teardown.yml diff --git a/playbooks/azure_deploy_controllers.yml b/playbooks/azure_deploy_controllers.yml new file mode 100644 index 0000000..99e04d0 --- /dev/null +++ b/playbooks/azure_deploy_controllers.yml @@ -0,0 +1,12 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- +- name: Deploy Cisco SD-WAN controllers on Azure + hosts: localhost + gather_facts: false + vars_files: + ./azure_sdwan_config.yml + roles: + - azure_network_infrastructure + - azure_controllers diff --git a/playbooks/azure_deploy_edges.yml b/playbooks/azure_deploy_edges.yml new file mode 100644 index 0000000..e70a159 --- /dev/null +++ b/playbooks/azure_deploy_edges.yml @@ -0,0 +1,11 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- +- name: Deploy Cisco SD-WAN cEedge devices on Azure + hosts: localhost + gather_facts: false + vars_files: + ./azure_sdwan_config.yml + roles: + - azure_edges diff --git a/playbooks/azure_sdwan_config.yml b/playbooks/azure_sdwan_config.yml new file mode 100644 index 0000000..702353f --- /dev/null +++ b/playbooks/azure_sdwan_config.yml @@ -0,0 +1,112 @@ +--- + +####################################### +# Required configuration data # +####################################### + +organization_name: null + + +####################################### +# General Azure configuration # +####################################### + +az_location: null +az_resources_prefix: "{{ organization_name }}" + + +# example configuration is: +# aws_allowed_subnets: +# - 15.15.0.0/16 +# - 10.10.0.0/16 +aws_allowed_subnets: null + + +############################### +# Controllers # +############################### + +# vManage +az_vmanage_image_vhd_source: null +az_vmanage_vm_size: "Standard_F16s_v2" + +site_id_vmanage: 100 + +vmanage_instances: + - hostname: "{{ az_resources_prefix }}-vManage" + system_ip: 192.168.1.1 + site_id: "{{ site_id_vmanage }}" + + +# vBond +az_vbond_image_vhd_source: null +site_id_vbond: 200 + +vbond_instances: + - hostname: "{{ az_resources_prefix }}-vBond" + system_ip: 192.168.3.1 + site_id: "{{ site_id_vbond }}" + + +# vSmart +az_vsmart_image_vhd_source: null +az_vsmart_vm_size: "Standard_F4s_v2" + +site_id_vsmart: 300 + +vsmart_instances: + - hostname: "{{ az_resources_prefix }}-vSmart" + system_ip: 192.168.2.1 + site_id: "{{ site_id_vsmart }}" + + +################################ +# Edge devices # +################################ + +# cedge C8000K +az_cedge_vm_size: "Standard_D2_v2" + +az_cedge_image_offer: "cisco-c8000v-byol" +az_cedge_image_publisher: "cisco" +az_cedge_image_sku: "17_13_01a-byol" +az_cedge_image_version: "17.13.0120231222" + + +# edge_instances: [] + +# If no edge instances configured, they will be automatically created +# based on the PnP Portal information. +# See `deployment_edges_config` to inspect result + + +edge_instances: +- hostname: acich-az-cedge-1 + otp: cc29db740f344f4b9968982d47d35768 + site_id: '1001' + system_ip: 192.168.101.1 + uuid: C8K-43B1056C-147C-35EF-154F-EACACA81D8DC + vbond: 137.135.122.118 +- hostname: acich-az-cedge-2 + otp: 511946c2f8374ea493a6733e75231be7 + site_id: '1002' + system_ip: 192.168.102.1 + uuid: C8K-7EFB9954-74EA-8985-80B4-39AA14D12573 + vbond: 137.135.122.118 +- hostname: acich-az-cedge-3 + otp: 3540b073b37d40458b90af6b587ca370 + site_id: '1003' + system_ip: 192.168.103.1 + uuid: C8K-A6139414-8C6C-BB10-BD15-17BBB772E569 + vbond: 137.135.122.118 + +########################################## +# Reusable deployment facts # +########################################## + +results_dir: "{{ playbook_dir }}/results" +results_path_controllers: "{{ results_dir }}/controllers.yml" +results_path_edges: "{{ results_dir }}/edges.yml" + +# Required by role: cisco.catalystwan.sync_pnp_edges +deployment_edges_config: "{{ results_dir }}/edges_from_pnp_bootstrap.yml" diff --git a/playbooks/azure_teardown.yml b/playbooks/azure_teardown.yml new file mode 100644 index 0000000..6675462 --- /dev/null +++ b/playbooks/azure_teardown.yml @@ -0,0 +1,24 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# +# 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. +# +# SPDX-License-Identifier: Apache-2.0 + +--- +- name: Teardown Cisco SD-WAN resources on Azure + hosts: localhost + gather_facts: false + vars_files: + ./azure_sdwan_config.yml + roles: + - azure_teardown diff --git a/playbooks/deploy_controllers_20_13.yml b/playbooks/deploy_controllers_20_13.yml deleted file mode 100644 index 74b5dfd..0000000 --- a/playbooks/deploy_controllers_20_13.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -- name: Deploy Cisco SD-WAN versions 20.13 on AWS - hosts: localhost - roles: - - aws_network_infrastructure - - aws_controllers - vars_files: - ./sdwan_config_20_13.yml diff --git a/playbooks/teardown_20_13.yml b/playbooks/teardown_20_13.yml deleted file mode 100644 index 7a5fd70..0000000 --- a/playbooks/teardown_20_13.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- name: Teardown Cisco SD-WAN versions 20.13 on AWS - hosts: localhost - gather_facts: false - roles: - - aws_teardown - vars_files: - - ./sdwan_config_20_13.yml - # - ./specific_edges_to_teardown.yml diff --git a/requirements.txt b/requirements.txt index f410acc..10950b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,15 @@ adal==1.2.7 -aiohttp==3.9.3 -aiosignal==1.3.1 ansible==8.7.0 ansible-core==2.15.9 -anyio==4.3.0 applicationinsights==0.11.10 argcomplete==1.12.3 -async-timeout==4.0.3 -attrs==23.2.0 azure-cli-core==2.34.0 azure-cli-telemetry==1.0.6 azure-common==1.1.11 azure-containerregistry==1.1.0 azure-core==1.28.0 -azure-identity==1.14.0 +azure-graphrbac==0.61.1 +azure-identity==1.7.0 azure-iot-hub==2.6.1 azure-keyvault==4.2.0 azure-keyvault-certificates==4.7.0 @@ -61,75 +57,55 @@ azure-mgmt-web==6.1.0 azure-nspkg==2.0.0 azure-storage-blob==12.11.0 bcrypt==4.1.2 -boto3==1.34.55 -botocore==1.34.55 +boto3==1.34.69 +botocore==1.34.69 certifi==2024.2.2 cffi==1.16.0 +cfgv==3.4.0 charset-normalizer==3.3.2 cryptography==42.0.5 -Deprecated==1.2.14 -exceptiongroup==1.2.0 -frozenlist==1.4.1 -h11==0.14.0 -h2==4.1.0 -hpack==4.0.0 -httpcore==1.0.4 -httpx==0.27.0 +distlib==0.3.8 +filelock==3.13.3 humanfriendly==10.0 -hyperframe==6.0.1 +identify==2.5.35 idna==3.6 -importlib-metadata==6.11.0 importlib-resources==5.0.7 isodate==0.6.1 Jinja2==3.1.3 jmespath==1.0.1 knack==0.9.0 MarkupSafe==2.1.5 -microsoft-kiota-abstractions==1.3.1 -microsoft-kiota-authentication-azure==1.0.0 -microsoft-kiota-http==1.3.1 -microsoft-kiota-serialization-json==1.1.0 -microsoft-kiota-serialization-text==1.0.0 -msal==1.27.0 +msal==1.23.0 msal-extensions==0.3.1 -msgraph-core==1.0.0 -msgraph-sdk==1.0.0 msrest==0.7.1 msrestazure==0.6.4 -multidict==6.0.5 +netaddr==1.2.1 +nodeenv==1.8.0 oauthlib==3.2.2 -opentelemetry-api==1.23.0 -opentelemetry-sdk==1.23.0 -opentelemetry-semantic-conventions==0.44b0 packaging==21.3 paramiko==2.12.0 -pendulum==3.0.0 pkginfo==1.10.0 +platformdirs==4.2.0 portalocker==1.7.1 +pre-commit==3.7.0 psutil==5.9.8 pycparser==2.21 Pygments==2.17.2 PyJWT==2.8.0 PyNaCl==1.5.0 -pyOpenSSL==24.0.0 -pyparsing==3.1.1 +pyOpenSSL==24.1.0 +pyparsing==3.1.2 PySocks==1.7.1 python-dateutil==2.9.0.post0 PyYAML==6.0.1 requests==2.31.0 -requests-oauthlib==1.3.1 +requests-oauthlib==2.0.0 resolvelib==1.0.1 -s3transfer==0.10.0 +s3transfer==0.10.1 six==1.16.0 -sniffio==1.3.1 -std-uritemplate==0.0.54 tabulate==0.9.0 -time-machine==2.14.0 typing_extensions==4.10.0 -tzdata==2024.1 uamqp==1.6.8 urllib3==1.26.18 -wrapt==1.16.0 +virtualenv==20.25.1 xmltodict==0.13.0 -yarl==1.9.4 -zipp==3.17.0 diff --git a/roles/aws_controllers/tasks/aws_wait_for_instances_readiness.yml b/roles/aws_controllers/tasks/aws_wait_for_instances_readiness.yml deleted file mode 100644 index a98824b..0000000 --- a/roles/aws_controllers/tasks/aws_wait_for_instances_readiness.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -- name: Wait for vManage ssh server 600 seconds, start checking after 60 seconds - ansible.builtin.wait_for: - delay: 60 - timeout: 600 - state: started - host: "{{ instance_item.mgmt_public_ip }}" - port: 22 - loop: "{{ deployment_facts.vmanage_instances }}" - loop_control: - loop_var: instance_item diff --git a/roles/aws_controllers/tasks/main.yml b/roles/aws_controllers/tasks/main.yml index 9e96fc6..4ed60be 100644 --- a/roles/aws_controllers/tasks/main.yml +++ b/roles/aws_controllers/tasks/main.yml @@ -40,8 +40,8 @@ - name: Assert all required variables for AWS controllers deployment ansible.builtin.include_role: name: common - tasks_from: aws_required_variables - defaults_from: required_vars_controllers.yml + tasks_from: required_variables + defaults_from: aws_required_vars_controllers.yml - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: @@ -102,9 +102,17 @@ when: vsmart_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) - name: Extract deployment facts - ansible.builtin.include_tasks: generate_deployment_facts.yml + ansible.builtin.include_role: + name: common + tasks_from: generate_deployment_facts_controllers.yml when: deployment_facts.vbond_instances | length > 0 or deployment_facts.vmanage_instances | length > 0 or deployment_facts.vsmart_instances | length > 0 - name: Check reachability of vManage instance with SSH probe - ansible.builtin.include_tasks: aws_wait_for_instances_readiness.yml + ansible.builtin.include_role: + name: common + tasks_from: wait_for_ssh_readiness + vars: + ssh_readiness_delay: 60 + ssh_readiness_timeout: 600 + ssh_readiness_instances: "{{ deployment_facts.vmanage_instances }}" when: vmanage_instances is defined and deployment_facts.vmanage_instances | length > 0 diff --git a/roles/aws_controllers/templates/userdata_vbond.j2 b/roles/aws_controllers/templates/userdata_vbond.j2 index 56d509c..c383742 100644 --- a/roles/aws_controllers/templates/userdata_vbond.j2 +++ b/roles/aws_controllers/templates/userdata_vbond.j2 @@ -14,16 +14,12 @@ chpasswd: expire: false list: - root:root - - admin:{{ admin_password }} + - {{ admin_username }}:{{ admin_password }} write_files: - path: /etc/default/personality content: "vedge\n" - path: /etc/default/inited content: "1\n" -# - path: /etc/viptela/testbed -# content: "\n" -# - path: /boot/testbed -# content: "\n" - path: /etc/confd/init/zcloud.xml content: | @@ -42,7 +38,7 @@ write_files: - admin + {{ admin_username }} {{ admin_password }} diff --git a/roles/aws_controllers/templates/userdata_vmanage.j2 b/roles/aws_controllers/templates/userdata_vmanage.j2 index 1f2b230..4d00f79 100644 --- a/roles/aws_controllers/templates/userdata_vmanage.j2 +++ b/roles/aws_controllers/templates/userdata_vmanage.j2 @@ -14,7 +14,7 @@ chpasswd: expire: false list: - root:root - - admin:{{ admin_password }} + - {{ admin_username }}:{{ admin_password }} disk_setup: /dev/nvme1n1: table_type: mbr @@ -38,11 +38,6 @@ write_files: content: "vmanage\n" - path: /etc/default/inited content: "1\n" -# These are only for internal usage -# - path: /etc/viptela/testbed -# content: "\n" -# - path: /boot/testbed -# content: "\n" - path: /etc/confd/init/zcloud.xml content: | @@ -62,7 +57,7 @@ write_files: radius tacacs - admin + {{ admin_username }} {{ admin_password }} netadmin diff --git a/roles/aws_controllers/templates/userdata_vsmart.j2 b/roles/aws_controllers/templates/userdata_vsmart.j2 index 6f9d734..767f780 100644 --- a/roles/aws_controllers/templates/userdata_vsmart.j2 +++ b/roles/aws_controllers/templates/userdata_vsmart.j2 @@ -14,16 +14,12 @@ chpasswd: expire: false list: - root:root - - admin:Cisco#123@Viptela + - {{ admin_username }}:{{ admin_password }} write_files: - path: /etc/default/personality content: "vsmart\n" - path: /etc/default/inited content: "1\n" -# - path: /etc/viptela/testbed -# content: "\n" -# - path: /boot/testbed -# content: "\n" - path: /etc/confd/init/zcloud.xml content: | @@ -40,7 +36,7 @@ write_files: - admin + {{ admin_username }} {{ admin_password }} diff --git a/roles/aws_edges/tasks/aws_wait_for_instances_readiness.yml b/roles/aws_edges/tasks/aws_wait_for_instances_readiness.yml deleted file mode 100644 index 5ca1a7e..0000000 --- a/roles/aws_edges/tasks/aws_wait_for_instances_readiness.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -- name: Wait for edge device ssh server 300 seconds, start checking after 10 seconds - ansible.builtin.wait_for: - delay: 10 - timeout: 300 - state: started - host: "{{ instance_item.mgmt_public_ip }}" - port: 22 - loop: "{{ deployment_facts.deployed_edge_instances }}" - loop_control: - loop_var: instance_item diff --git a/roles/aws_edges/tasks/main.yml b/roles/aws_edges/tasks/main.yml index ebe6862..3b56d1e 100644 --- a/roles/aws_edges/tasks/main.yml +++ b/roles/aws_edges/tasks/main.yml @@ -30,11 +30,11 @@ aws_security_group_config: "{{ aws_discovered_security_group }}" aws_subnets_config: "{{ aws_discovered_subnets }}" -- name: Assert all required variables for AWS controllers deployment +- name: Assert all required variables for AWS edges deployment ansible.builtin.include_role: name: common - tasks_from: aws_required_variables - defaults_from: required_vars_controllers.yml + tasks_from: required_variables + defaults_from: aws_required_vars_edges.yml - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: @@ -69,7 +69,16 @@ when: edge_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) - name: Extract deployment facts - ansible.builtin.include_tasks: generate_deployment_facts.yml + ansible.builtin.include_role: + name: common + tasks_from: generate_deployment_facts_edges.yml + when: deployment_facts.deployed_edge_instances | length > 0 -- name: Check reachability of Edge instances with SSH probe - ansible.builtin.include_tasks: aws_wait_for_instances_readiness.yml +- name: Check reachability of cEdge instances with SSH probe + ansible.builtin.include_role: + name: common + tasks_from: wait_for_ssh_readiness + vars: + ssh_readiness_delay: 10 + ssh_readiness_timeout: 300 + ssh_readiness_instances: "{{ deployment_facts.deployed_edge_instances }}" diff --git a/roles/aws_network_infrastructure/defaults/main.yml b/roles/aws_network_infrastructure/defaults/main.yml index 7281ab0..72bb202 100644 --- a/roles/aws_network_infrastructure/defaults/main.yml +++ b/roles/aws_network_infrastructure/defaults/main.yml @@ -46,6 +46,3 @@ aws_security_group_name: "{{ aws_resources_prefix }}-sg" aws_vpn_name: "{{ aws_resources_prefix }}-vpn" aws_eip_name: "{{ aws_resources_prefix }}-eip" aws_nacl_name: "{{ aws_resources_prefix }}-nacl" - -# EC2 INSTANCES -aws_key_name: null diff --git a/roles/aws_network_infrastructure/tasks/main.yml b/roles/aws_network_infrastructure/tasks/main.yml index 6786468..f7b35b8 100644 --- a/roles/aws_network_infrastructure/tasks/main.yml +++ b/roles/aws_network_infrastructure/tasks/main.yml @@ -16,8 +16,8 @@ - name: Assert all required variables for AWS network infrastructure deployment ansible.builtin.include_role: name: common - tasks_from: aws_required_variables - defaults_from: required_vars_network_infrastructure.yml + tasks_from: required_variables + defaults_from: aws_required_vars_network_infrastructure.yml - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: diff --git a/roles/azure/tasks/main.yml b/roles/azure/tasks/main.yml deleted file mode 100644 index 9dd2f37..0000000 --- a/roles/azure/tasks/main.yml +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - -# # Network Interfaces for vManage -# - name: Create Network Interface for vManage1 -# azure.azcollection.azure_rm_networkinterface: - -# - name: Create Network Interface for vManage2 -# azure.azcollection.azure_rm_networkinterface: - -# # Network Interfaces for vSmart -# - name: Create Network Interface for vSmart1 -# azure.azcollection.azure_rm_networkinterface: - -# - name: Create Network Interface for vSmart2 -# azure.azcollection.azure_rm_networkinterface: - -# # Network Interfaces for vBond -# - name: Create Network Interface for vBond1 -# azure.azcollection.azure_rm_networkinterface: - -# - name: Create Network Interface for vBond2 -# azure.azcollection.azure_rm_networkinterface: - -# # Network Interfaces for vEdge -# - name: Create Network Interface for vEdge1 -# azure.azcollection.azure_rm_networkinterface: - -# - name: Create Network Interface for vEdge2 -# azure.azcollection.azure_rm_networkinterface: - -# # Virtual Machines for vManage -# - name: Create virtual machine for vManage -# azure.azcollection.azure_rm_virtualmachine: - -# # Virtual Machines for vSmart -# - name: Create virtual machine for vSmart -# azure.azcollection.azure_rm_virtualmachine: - -# # Virtual Machines for vBond -# - name: Create virtual machine for vBond -# azure.azcollection.azure_rm_virtualmachine: - -# # Virtual Machines for vEdge -# - name: Create virtual machine for vEdge -# azure.azcollection.azure_rm_virtualmachine: diff --git a/roles/azure_controllers/defaults/main.yml b/roles/azure_controllers/defaults/main.yml new file mode 100644 index 0000000..2b318a1 --- /dev/null +++ b/roles/azure_controllers/defaults/main.yml @@ -0,0 +1,88 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +organization_name: null # has to be set by user + +################################################## +# Networking Azure configuration defaults # +################################################## + +# Common +az_location: null +az_tag_creator: "{{ organization_name }}" +az_resources_prefix: "{{ organization_name }}" # default to organization_name, but user should have option to modify + +# Resource group +az_resource_group: "{{ az_resources_prefix }}-rg" + +# Virtual Network +az_virtual_network: "{{ az_resources_prefix }}-vn" +az_vn_address_prefixes_cidr: 10.0.0.0/16 + +# Subnets +az_subnets: + - name: "{{ az_resources_prefix }}-mgmt-subnet-512" + cidr: "10.0.1.0/24" + VPN: 512 + - name: "{{ az_resources_prefix }}-transport-subnet-0" + cidr: "10.0.2.0/24" + VPN: 0 + # - name: "{{ az_resources_prefix }}-cluster-subnet-1" + # subnet_cidr: "10.0.3.0/24" + # VPN: 1 + +# Security group +az_network_security_group: "{{ az_resources_prefix }}-nsg" + + +# VPN subnets from which we can connect to Azure EIPs (Network Security Group config) +az_allowed_subnets: null + + +########################################## +# SD-WAN Instances configuration # +########################################## + +azure_key_name: null + +# Cloud-init general configurations +admin_username: admin +admin_password: Cisco#123@Viptela +vbond_port: 12346 +default_vbond_ip: 192.168.1.199 +# vpn0_interface_color: default + + +############################### +# Controllers # +############################### + +# vManage +az_vmanage_vm_size: "Standard_F16s_v2" +site_id_vmanage: 100 + +vmanage_instances: [] + # - hostname: "{{ az_resources_prefix }}-vManage" + # system_ip: 192.168.1.1 + # site_id: "{{ site_id_vmanage }}" + + +# vBond +az_vbond_vm_size: "Standard_F4s_v2" +site_id_vbond: 200 + +vbond_instances: [] + # - hostname: "{{ az_resources_prefix }}-vBond" + # system_ip: 192.168.3.1 + # site_id: "{{ site_id_vbond }}" + + +# vSmart +az_vsmart_vm_size: "Standard_F4s_v2" +site_id_vsmart: 300 + +vsmart_instances: [] + # - hostname: "{{ az_resources_prefix }}-vSmart" + # system_ip: 192.168.2.1 + # site_id: "{{ site_id_vsmart }}" diff --git a/roles/azure_controllers/handlers/main.yml b/roles/azure_controllers/handlers/main.yml new file mode 100644 index 0000000..a7068f7 --- /dev/null +++ b/roles/azure_controllers/handlers/main.yml @@ -0,0 +1,6 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Show deployment_facts + ansible.builtin.debug: + msg: "{{ deployment_facts }}" diff --git a/roles/azure_controllers/meta/main.yml b/roles/azure_controllers/meta/main.yml new file mode 100644 index 0000000..c192ecb --- /dev/null +++ b/roles/azure_controllers/meta/main.yml @@ -0,0 +1,3 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- diff --git a/roles/azure_controllers/tasks/azure_vbond_vm.yml b/roles/azure_controllers/tasks/azure_vbond_vm.yml new file mode 100644 index 0000000..d6bcc92 --- /dev/null +++ b/roles/azure_controllers/tasks/azure_vbond_vm.yml @@ -0,0 +1,177 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Create public IP addresses for machine: {{ hostname }}" + azure.azcollection.azure_rm_publicipaddress: + resource_group: "{{ az_resource_group }}" + allocation_method: static + name: "public-ip-{{ hostname }}-vpn-{{ subnet_item.VPN }}" + tags: + Name: "public-ip-{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ subnet_item.VPN }}" + Subnet: "{{ subnet_item.name }}" + loop: "{{ az_subnets }}" + loop_control: + loop_var: subnet_item + register: public_ip_addresses + +- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" + azure_rm_securitygroup_info: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + register: az_res_gr + +- name: "Extend Network Security Group for machine, NSG: {{ az_network_security_group }}" + azure.azcollection.azure_rm_securitygroup: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + rules: + - name: "{{ public_ip_state.state.name }}" + protocol: "*" + destination_port_range: "*" + source_port_range: "*" + source_address_prefix: "{{ public_ip_state.state.ip_address }}" + access: Allow + priority: "{{ 1500 + ((az_res_gr.securitygroups | first).rules | length) + 1 + my_idx }}" + direction: Inbound + tags: + Name: "{{ az_network_security_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + +- name: "Create virtual network interface cards" + azure.azcollection.azure_rm_networkinterface: + resource_group: "{{ az_resource_group }}" + name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + virtual_network: "{{ az_virtual_network }}" + subnet_name: "{{ public_ip_state.state.tags.Subnet }}" + security_group: "{{ az_network_security_group }}" + ip_configurations: + - name: "ipconfig-vpn-{{ public_ip_state.state.tags.VPN }}" + public_ip_address_name: "{{ public_ip_state.state.name }}" + private_ip_allocation_method: "Dynamic" + tags: + Name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + VPN: "{{ public_ip_state.state.tags.VPN }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + register: vbond_nics + +- name: Set az_network_interfaces_vbond fact with a list of interfaces for vBond + ansible.builtin.set_fact: + az_network_interfaces_vbond: "{{ vbond_nics.results | map(attribute='state') | list }}" + az_public_ip_addresses_vbond: "{{ public_ip_addresses.results | map(attribute='state') | list }}" + +- name: Filter az_network_interfaces_vbond for instance creation. Set az_mgmt_nic and az_transport_nic facts + ansible.builtin.set_fact: + az_mgmt_nic: "{{ az_network_interfaces_vbond | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_nic: "{{ az_network_interfaces_vbond | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + az_mgmt_public_ip: "{{ az_public_ip_addresses_vbond | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_public_ip: "{{ az_public_ip_addresses_vbond | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + +# vbond_mgmt_private_ip +- name: "Set ip addresses vbond facts" + ansible.builtin.set_fact: + vbond_mgmt_private_ip: "{{ az_mgmt_nic.ip_configuration.private_ip_address }}" + vbond_transport_private_ip: "{{ az_transport_nic.ip_configuration.private_ip_address }}" + vbond_mgmt_public_ip: "{{ az_mgmt_public_ip.ip_address }}" + vbond_transport_public_ip: "{{ az_transport_public_ip.ip_address }}" + +- name: "Set vpn0_default_gateway fact from VPN 0 subnet value" + set_fact: + vpn0_default_gateway: "{{ item.cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" + loop: "{{ az_subnets }}" + when: item.VPN == 0 + +- name: "Set path for bootstrap configuration: {{ userdata_vbond_path }}-{{ hostname }}" + ansible.builtin.set_fact: + generated_userdata_vbond: "{{ userdata_vbond_path }}-{{ hostname }}" + changed_when: true + +- name: "Template userdata file for vBond: {{ hostname }}" + ansible.builtin.template: + src: ./userdata_vbond.j2 # ./bond.j2 ./userdata_vbond.j2 + dest: "{{ generated_userdata_vbond }}" + mode: "0644" + +# # Note for image: + +# # What are the options for image? +# # Do we only go with VHD so user has to create it in advance? +# # Or can we use image id? + +# # For custom images, the name of the image. To narrow the search to a specific resource group, a dict with the keys name and resource_group. +# # For Marketplace images, a dict with the keys publisher, offer, sku, and version. + +- name: "Create an image from a VHD for vBond: {{ hostname }}-image" + azure.azcollection.azure_rm_image: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}-image" + location: "{{ az_location }}" + os_type: "Linux" + hyper_v_generation: "V1" + source: "{{ az_vbond_image_vhd_source }}" + +- name: "Create vBond VM: {{ hostname }}" + azure.azcollection.azure_rm_virtualmachine: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}" + vm_size: "{{ az_vbond_vm_size }}" + ssh_password_enabled: true + admin_username: "{{ admin_username }}-tmp" + admin_password: "{{ admin_password }}" + managed_disk_type: "Premium_LRS" + os_disk_size_gb: 30 + os_disk_name: "{{ hostname }}-os-disk" + os_type: "Linux" + os_disk_caching: "ReadWrite" + ephemeral_os_disk: false + linux_config: + disable_password_authentication: false + network_interfaces: + - "{{ az_mgmt_nic.id }}" + - "{{ az_transport_nic.id }}" + image: + name: "{{ hostname }}-image" + resource_group: "{{ az_resource_group }}" + boot_diagnostics: + enabled: true + type: "managed" + tags: + Name: "{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + custom_data: "{{ lookup('file', generated_userdata_vbond) }}" + +- name: Store vBond instance details for deployment_results + ansible.builtin.set_fact: + instance: + hostname: "{{ hostname }}" + system_ip: "{{ system_ip }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" + mgmt_public_ip: "{{ vbond_mgmt_public_ip }}" + transport_public_ip: "{{ vbond_transport_public_ip }}" + changed_when: true + notify: Show deployment_facts + +- name: Update deployment facts - vBond - that will be consumed by vManage-client in Ansible + ansible.builtin.set_fact: + deployment_facts: + vbond_instances: "{{ deployment_facts.vbond_instances + [instance] }}" + vmanage_instances: "{{ deployment_facts.vmanage_instances }}" + vsmart_instances: "{{ deployment_facts.vsmart_instances }}" diff --git a/roles/azure_controllers/tasks/azure_vmanage_vm.yml b/roles/azure_controllers/tasks/azure_vmanage_vm.yml new file mode 100644 index 0000000..2ded923 --- /dev/null +++ b/roles/azure_controllers/tasks/azure_vmanage_vm.yml @@ -0,0 +1,170 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Create public IP addresses for machine: {{ hostname }}" + azure.azcollection.azure_rm_publicipaddress: + resource_group: "{{ az_resource_group }}" + allocation_method: static + name: "public-ip-{{ hostname }}-vpn-{{ subnet_item.VPN }}" + tags: + Name: "public-ip-{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ subnet_item.VPN }}" + Subnet: "{{ subnet_item.name }}" + loop: "{{ az_subnets }}" + loop_control: + loop_var: subnet_item + register: public_ip_addresses + +- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" + azure_rm_securitygroup_info: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + register: az_res_gr + +- name: "Extend Network Security Group for machine, NSG: {{ az_network_security_group }}" + azure.azcollection.azure_rm_securitygroup: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + rules: + - name: "{{ public_ip_state.state.name }}" + protocol: "*" + destination_port_range: "*" + source_port_range: "*" + source_address_prefix: "{{ public_ip_state.state.ip_address }}" + access: Allow + priority: "{{ 2500 + ((az_res_gr.securitygroups | first).rules | length) + 1 + my_idx }}" + direction: Inbound + tags: + Name: "{{ az_network_security_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + +- name: "Create virtual network interface cards" + azure.azcollection.azure_rm_networkinterface: + resource_group: "{{ az_resource_group }}" + name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + virtual_network: "{{ az_virtual_network }}" + subnet_name: "{{ public_ip_state.state.tags.Subnet }}" + security_group: "{{ az_network_security_group }}" + ip_configurations: + - name: "ipconfig-vpn-{{ public_ip_state.state.tags.VPN }}" + public_ip_address_name: "{{ public_ip_state.state.name }}" + private_ip_allocation_method: "Dynamic" + tags: + Name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + VPN: "{{ public_ip_state.state.tags.VPN }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + register: vmanage_nics + +- name: Set az_network_interfaces_vmanage fact with a list of interfaces for vmanage + ansible.builtin.set_fact: + az_network_interfaces_vmanage: "{{ vmanage_nics.results | map(attribute='state') | list }}" + az_public_ip_addresses_vmanage: "{{ public_ip_addresses.results | map(attribute='state') | list }}" + +- name: Filter az_network_interfaces_vmanage for instance creation. Set az_mgmt_nic and az_transport_nic facts + ansible.builtin.set_fact: + az_mgmt_nic: "{{ az_network_interfaces_vmanage | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_nic: "{{ az_network_interfaces_vmanage | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + az_mgmt_public_ip: "{{ az_public_ip_addresses_vmanage | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_public_ip: "{{ az_public_ip_addresses_vmanage | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + +# vmanage_mgmt_private_ip +- name: Set vmanage facts + ansible.builtin.set_fact: + vmanage_mgmt_private_ip: "{{ az_mgmt_nic.ip_configuration.private_ip_address }}" + vmanage_transport_private_ip: "{{ az_transport_nic.ip_configuration.private_ip_address }}" + vmanage_mgmt_public_ip: "{{ az_mgmt_public_ip.ip_address }}" + vmanage_transport_public_ip: "{{ az_transport_public_ip.ip_address }}" + +- name: "Set vpn0_default_gateway fact from VPN 0 subnet value" + set_fact: + vpn0_default_gateway: "{{ item.cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" + loop: "{{ az_subnets }}" + when: item.VPN == 0 + +- name: "Set path for bootstrap configuration: {{ userdata_vmanage_path }}-{{ hostname }}" + ansible.builtin.set_fact: + generated_userdata_vmanage: "{{ userdata_vmanage_path }}-{{ hostname }}" + changed_when: true + +- name: "Template userdata file for vmanage: {{ hostname }}" + ansible.builtin.template: + src: ./userdata_vmanage.j2 + dest: "{{ generated_userdata_vmanage }}" + mode: "0644" + +- name: "Create an image from a VHD for vManage: {{ hostname }}-image" + azure.azcollection.azure_rm_image: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}-image" + location: "{{ az_location }}" + os_type: "Linux" + hyper_v_generation: "V1" + source: "{{ az_vmanage_image_vhd_source }}" + +- name: "Create VM for vmanage: {{ hostname }}" + azure.azcollection.azure_rm_virtualmachine: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}" + vm_size: "{{ az_vmanage_vm_size }}" + admin_username: "{{ admin_username }}-tmp" # Not included in cloud init + admin_password: "{{ admin_password }}" + managed_disk_type: "Premium_LRS" + os_disk_size_gb: 30 + os_disk_name: "{{ hostname }}-os-disk" + os_type: "Linux" + os_disk_caching: "ReadWrite" + ephemeral_os_disk: false + network_interfaces: + - "{{ az_mgmt_nic.id }}" + - "{{ az_transport_nic.id }}" + image: + name: "{{ hostname }}-image" + resource_group: "{{ az_resource_group }}" + boot_diagnostics: + enabled: true + type: "managed" + data_disks: + - lun: 10 + disk_size_gb: 100 + managed_disk_type: Premium_LRS + storage_container_name: "{{ hostname }}-datadisk1" + tags: + Name: "{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + custom_data: "{{ lookup('file', generated_userdata_vmanage) }}" + +- name: "Store vManage instance details for deployment_results" + ansible.builtin.set_fact: + instance: + hostname: "{{ hostname }}" + system_ip: "{{ system_ip }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" + mgmt_public_ip: "{{ vmanage_mgmt_public_ip }}" + transport_public_ip: "{{ vmanage_transport_public_ip }}" + changed_when: true + notify: Show deployment_facts + +- name: "Update deployment facts - vManage - that will be consumed by vManage-client in Ansible" + ansible.builtin.set_fact: + deployment_facts: + vmanage_instances: "{{ deployment_facts.vmanage_instances + [instance] }}" + vbond_instances: "{{ deployment_facts.vbond_instances }}" + vsmart_instances: "{{ deployment_facts.vsmart_instances }}" diff --git a/roles/azure_controllers/tasks/azure_vsmart_vm.yml b/roles/azure_controllers/tasks/azure_vsmart_vm.yml new file mode 100644 index 0000000..ed4b860 --- /dev/null +++ b/roles/azure_controllers/tasks/azure_vsmart_vm.yml @@ -0,0 +1,164 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Create public IP addresses for machine: {{ hostname }}" + azure.azcollection.azure_rm_publicipaddress: + resource_group: "{{ az_resource_group }}" + allocation_method: static + name: "public-ip-{{ hostname }}-vpn-{{ subnet_item.VPN }}" + tags: + Name: "public-ip-{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ subnet_item.VPN }}" + Subnet: "{{ subnet_item.name }}" + loop: "{{ az_subnets }}" + loop_control: + loop_var: subnet_item + register: public_ip_addresses + +- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" + azure_rm_securitygroup_info: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + register: az_res_gr + +- name: "Extend Network Security Group for machine, NSG: {{ az_network_security_group }}" + azure.azcollection.azure_rm_securitygroup: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + rules: + - name: "{{ public_ip_state.state.name }}" + protocol: "*" + destination_port_range: "*" + source_port_range: "*" + source_address_prefix: "{{ public_ip_state.state.ip_address }}" + access: Allow + priority: "{{ 2000 + ((az_res_gr.securitygroups | first).rules | length) + 1 + my_idx }}" + direction: Inbound + tags: + Name: "{{ az_network_security_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + +- name: "Create virtual network interface cards" + azure.azcollection.azure_rm_networkinterface: + resource_group: "{{ az_resource_group }}" + name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + virtual_network: "{{ az_virtual_network }}" + subnet_name: "{{ public_ip_state.state.tags.Subnet }}" + security_group: "{{ az_network_security_group }}" + ip_configurations: + - name: "ipconfig-vpn-{{ public_ip_state.state.tags.VPN }}" + public_ip_address_name: "{{ public_ip_state.state.name }}" + private_ip_allocation_method: "Dynamic" + tags: + Name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + VPN: "{{ public_ip_state.state.tags.VPN }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + register: vsmart_nics + +- name: "Set az_network_interfaces_vsmart fact with a list of interfaces for vSmart" + ansible.builtin.set_fact: + az_network_interfaces_vsmart: "{{ vsmart_nics.results | map(attribute='state') | list }}" + az_public_ip_addresses_vsmart: "{{ public_ip_addresses.results | map(attribute='state') | list }}" + +- name: "Filter az_network_interfaces_vsmart for instance creation. Set az_mgmt_nic and az_transport_nic facts" + ansible.builtin.set_fact: + az_mgmt_nic: "{{ az_network_interfaces_vsmart | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_nic: "{{ az_network_interfaces_vsmart | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + az_mgmt_public_ip: "{{ az_public_ip_addresses_vsmart | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_public_ip: "{{ az_public_ip_addresses_vsmart | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + +- name: "Set vsmart facts" + ansible.builtin.set_fact: + vsmart_mgmt_private_ip: "{{ az_mgmt_nic.ip_configuration.private_ip_address }}" + vsmart_transport_private_ip: "{{ az_transport_nic.ip_configuration.private_ip_address }}" + vsmart_mgmt_public_ip: "{{ az_mgmt_public_ip.ip_address }}" + vsmart_transport_public_ip: "{{ az_transport_public_ip.ip_address }}" + +- name: "Set vpn0_default_gateway fact from VPN 0 subnet value" + set_fact: + vpn0_default_gateway: "{{ item.cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" + loop: "{{ az_subnets }}" + when: item.VPN == 0 + +- name: "Set path for bootstrap configuration: {{ userdata_vsmart_path }}-{{ hostname }}" + ansible.builtin.set_fact: + generated_userdata_vsmart: "{{ userdata_vsmart_path }}-{{ hostname }}" + changed_when: true + +- name: "Template userdata file for vSmart: {{ hostname }}" + ansible.builtin.template: + src: ./userdata_vsmart.j2 + dest: "{{ generated_userdata_vsmart }}" + mode: "0644" + +- name: "Create an image from a VHD for vSmart: {{ hostname }}-image" + azure.azcollection.azure_rm_image: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}-image" + location: "{{ az_location }}" + os_type: "Linux" + hyper_v_generation: "V1" + source: "{{ az_vsmart_image_vhd_source }}" + +- name: "Create vSmart VM: {{ hostname }}" + azure.azcollection.azure_rm_virtualmachine: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}" + vm_size: "{{ az_vsmart_vm_size }}" + admin_username: "{{ admin_username }}-tmp" # Not included in cloud init + admin_password: "{{ admin_password }}" + managed_disk_type: "Premium_LRS" + os_disk_size_gb: 30 + os_disk_name: "{{ hostname }}-os-disk" + os_type: "Linux" + os_disk_caching: "ReadWrite" + ephemeral_os_disk: false + network_interfaces: + - "{{ az_mgmt_nic.id }}" + - "{{ az_transport_nic.id }}" + image: + name: "{{ hostname }}-image" + resource_group: "{{ az_resource_group }}" + boot_diagnostics: + enabled: true + type: "managed" + tags: + Name: "{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + custom_data: "{{ lookup('file', generated_userdata_vsmart) }}" + +- name: "Store vSmart instance details for deployment_results" + ansible.builtin.set_fact: + instance: + hostname: "{{ hostname }}" + system_ip: "{{ system_ip }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" + mgmt_public_ip: "{{ vsmart_mgmt_public_ip }}" + transport_public_ip: "{{ vsmart_transport_public_ip }}" + changed_when: true + notify: Show deployment_facts + +- name: "Update deployment facts - vSmart - that will be consumed by vManage-client in Ansible" + ansible.builtin.set_fact: + deployment_facts: + vsmart_instances: "{{ deployment_facts.vsmart_instances + [instance] }}" + vmanage_instances: "{{ deployment_facts.vmanage_instances }}" + vbond_instances: "{{ deployment_facts.vbond_instances }}" diff --git a/roles/aws_controllers/tasks/generate_deployment_facts.yml b/roles/azure_controllers/tasks/generate_deployment_facts.yml similarity index 82% rename from roles/aws_controllers/tasks/generate_deployment_facts.yml rename to roles/azure_controllers/tasks/generate_deployment_facts.yml index 0b9c6cc..ba3b6b9 100644 --- a/roles/aws_controllers/tasks/generate_deployment_facts.yml +++ b/roles/azure_controllers/tasks/generate_deployment_facts.yml @@ -21,8 +21,14 @@ # for deployment results filename .yml extension will be added along with timestamp # results_path_controllers: "{{ results_dir }}/deployment_facts_edges" - name: Set results_path_controllers if not defined - ansible.builtin.set_fact: - results_path_controllers: "{{ results_dir }}/deployment_facts_controllers_{{ ansible_date_time.date }}.yml" + block: + - name: Get info about time + ansible.builtin.setup: + gather_subset: + - min + - name: Create path + ansible.builtin.set_fact: + results_path_controllers: "{{ results_dir }}/deployment_facts_controllers_{{ ansible_date_time.date }}.yml" when: results_path_controllers is not defined - name: Generate file to store deployment facts - {{ results_path_controllers }} diff --git a/roles/azure_controllers/tasks/main.yml b/roles/azure_controllers/tasks/main.yml new file mode 100644 index 0000000..bd48d6f --- /dev/null +++ b/roles/azure_controllers/tasks/main.yml @@ -0,0 +1,93 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Verify if user session with Azure is active + ansible.builtin.include_role: + name: common + tasks_from: az_user_session_probe + +- name: Assert all required variables for Azure controllers deployment + ansible.builtin.include_role: + name: common + tasks_from: required_variables + defaults_from: az_required_vars_controllers.yml + +- name: "Check if the value of hostname has length of 32 or less" + ansible.builtin.assert: + that: + - instance_item.hostname | length > 0 + - instance_item.hostname | length <= 32 + fail_msg: "Verification for hostname failed, wrong hostname: {{ instance_item.hostname }}" + loop: "{{ vmanage_instances + vbond_instances + vsmart_instances }}" + loop_control: + loop_var: instance_item + label: "{{ instance_item.hostname }}" + +- name: "Prepare directory for results, path: {{ results_dir }}" + ansible.builtin.file: + path: "{{ results_dir }}" + state: directory + mode: "0755" + +- name: Verify if inside specified VN there are already existing instances that match requested instances + ansible.builtin.include_role: + name: common + tasks_from: az_existing_instances.yml + vars: + instances_marked_for_deployment: "{{ vmanage_instances + vbond_instances + vsmart_instances }}" + +- name: Define deployment facts - that will be consumed by vManage-client in Ansible + ansible.builtin.set_fact: + deployment_facts: + vbond_instances: [] + vmanage_instances: [] + vsmart_instances: [] + +- name: Deploy vBond - Create Virtual Machines + ansible.builtin.include_tasks: azure_vbond_vm.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vbond_instances }}" + loop_control: + loop_var: instance_item + when: vbond_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) + +- name: Deploy vSmart - Create Virtual Machines + ansible.builtin.include_tasks: azure_vsmart_vm.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vsmart_instances }}" + loop_control: + loop_var: instance_item + when: vsmart_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) + +- name: Deploy vManage - Create Virtual Machines + ansible.builtin.include_tasks: azure_vmanage_vm.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vmanage_instances }}" + loop_control: + loop_var: instance_item + when: vmanage_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) + +- name: Extract deployment facts + ansible.builtin.include_role: + name: common + tasks_from: generate_deployment_facts_controllers.yml + when: deployment_facts.vbond_instances | length > 0 or deployment_facts.vmanage_instances | length > 0 or deployment_facts.vsmart_instances | length > 0 + +- name: Check reachability of vManage instance with SSH probe + ansible.builtin.include_role: + name: common + tasks_from: wait_for_ssh_readiness + vars: + ssh_readiness_delay: 60 + ssh_readiness_timeout: 900 + ssh_readiness_instances: "{{ deployment_facts.vmanage_instances }}" + when: vmanage_instances is defined and deployment_facts.vmanage_instances | length > 0 diff --git a/roles/azure_controllers/templates/userdata_vbond.j2 b/roles/azure_controllers/templates/userdata_vbond.j2 new file mode 100644 index 0000000..4a57058 --- /dev/null +++ b/roles/azure_controllers/templates/userdata_vbond.j2 @@ -0,0 +1,89 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +write_files: +- path: /etc/default/personality + content: "vedge\n" +- path: /etc/default/inited + content: "1\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vedge + vedge-cloud + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id }} + + {{ vbond_transport_private_ip }} + + + + + + {{ admin_username }} + {{ admin_password }} + + + + + + 0 + + ge0/0 + + true + + + + ipsec + + + default + + + true + true + + + false + + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+
+ + 512 + + eth0 + + true + + false + + +
+
+--===============8815267485200512281== \ No newline at end of file diff --git a/roles/azure_controllers/templates/userdata_vmanage.j2 b/roles/azure_controllers/templates/userdata_vmanage.j2 new file mode 100644 index 0000000..b4f4758 --- /dev/null +++ b/roles/azure_controllers/templates/userdata_vmanage.j2 @@ -0,0 +1,108 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +disk_setup: + /dev/disk/azure/scsi1/lun10: + table_type: mbr + layout: false + overwrite: false +fs_setup: +- device: /dev/disk/azure/scsi1/lun10 + label: data + partition: none + filesystem: ext4 + overwrite: false +mounts: +- [ /dev/disk/azure/scsi1/lun10, /opt/data ] + +write_files: +- path: /opt/web-app/etc/persona + owner: vmanage:vmanage-admin + permissions: '0644' + content: '{"persona":"COMPUTE_AND_DATA"}' +- path: /etc/default/personality + content: "vmanage\n" +- path: /etc/default/inited + content: "1\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vmanage + vmanage + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id_vmanage }} + + {{ vbond_transport_public_ip | default(default_vbond_ip) }} + + + local + radius + tacacs + + {{ admin_username }} + {{ admin_password }} + netadmin + + + + + + 0 + + eth1 + + true + + + + true + true + true + true + true + true + true + + + false + + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+
+ + 512 + + eth0 + + true + + false + + +
+
+--===============8815267485200512281== \ No newline at end of file diff --git a/roles/azure_controllers/templates/userdata_vsmart.j2 b/roles/azure_controllers/templates/userdata_vsmart.j2 new file mode 100644 index 0000000..493f1fa --- /dev/null +++ b/roles/azure_controllers/templates/userdata_vsmart.j2 @@ -0,0 +1,87 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +write_files: +- path: /etc/default/personality + content: "vsmart\n" +- path: /etc/default/inited + content: "1\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vsmart + vsmart + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id }} + + {{ vbond_transport_public_ip | default(default_vbond_ip) }} + + + + {{ admin_username }} + {{ admin_password }} + + + + + + 0 + + eth1 + + true + + + + ipsec + + + default + + + true + true + + + false + + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+
+ + 512 + + eth0 + + true + + false + + +
+
+--===============8815267485200512281== \ No newline at end of file diff --git a/roles/azure_controllers/vars/main.yml b/roles/azure_controllers/vars/main.yml new file mode 100644 index 0000000..ea398a1 --- /dev/null +++ b/roles/azure_controllers/vars/main.yml @@ -0,0 +1,14 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# vars/ are used by the role and not likely to be changed +# Deployment results path +results_dir: "{{ playbook_dir }}/results" + + +# Path to templated userdata config +userdata_vmanage_path: "{{ results_dir }}/.userdata_vmanage" +userdata_vbond_path: "{{ results_dir }}/.userdata_vbond" +userdata_vsmart_path: "{{ results_dir }}/.userdata_vsmart" diff --git a/roles/azure_edges/defaults/main.yml b/roles/azure_edges/defaults/main.yml new file mode 100644 index 0000000..5296342 --- /dev/null +++ b/roles/azure_edges/defaults/main.yml @@ -0,0 +1,68 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +organization_name: null # has to be set by user + +################################################## +# Networking Azure configuration defaults # +################################################## + +# Common +az_location: null +az_tag_creator: "{{ organization_name }}" +az_resources_prefix: "{{ organization_name }}" # default to organization_name, but user should have option to modify + +# Resource group +az_resource_group: "{{ az_resources_prefix }}-rg" + +# Virtual Network +az_virtual_network: "{{ az_resources_prefix }}-vn" +az_vn_address_prefixes_cidr: 10.0.0.0/16 + +# Subnets +az_subnets: + - name: "{{ az_resources_prefix }}-mgmt-subnet-512" + cidr: "10.0.1.0/24" + VPN: 512 + - name: "{{ az_resources_prefix }}-transport-subnet-0" + cidr: "10.0.2.0/24" + VPN: 0 + # - name: "{{ az_resources_prefix }}-cluster-subnet-1" + # subnet_cidr: "10.0.3.0/24" + # VPN: 1 + +# Security group +az_network_security_group: "{{ az_resources_prefix }}-nsg" + + +# VPN subnets from which we can connect to Azure EIPs (Network Security Group config) +az_allowed_subnets: null + + +########################################## +# SD-WAN Instances configuration # +########################################## + +azure_key_name: null + +# Cloud-init general configurations +admin_username: admin +admin_password: Cisco#123@Viptela +vbond_port: 12346 +default_vbond_ip: 192.168.1.199 +# vpn0_interface_color: default + +################################ +# Edge devices # +################################ + +# cedge C8000K +az_cedge_vm_size: "Standard_D2_v2" + +edge_instances: [] + + +# If no edge instances configured, they will be automatically created +# based on the PnP Portal information. +# See `deployment_edges_config` to inspect result diff --git a/roles/azure_edges/handlers/main.yml b/roles/azure_edges/handlers/main.yml new file mode 100644 index 0000000..a7068f7 --- /dev/null +++ b/roles/azure_edges/handlers/main.yml @@ -0,0 +1,6 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Show deployment_facts + ansible.builtin.debug: + msg: "{{ deployment_facts }}" diff --git a/roles/azure_edges/meta/main.yml b/roles/azure_edges/meta/main.yml new file mode 100644 index 0000000..c192ecb --- /dev/null +++ b/roles/azure_edges/meta/main.yml @@ -0,0 +1,3 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- diff --git a/roles/azure_edges/tasks/azure_cedge_vm.yml b/roles/azure_edges/tasks/azure_cedge_vm.yml new file mode 100644 index 0000000..7d0c19f --- /dev/null +++ b/roles/azure_edges/tasks/azure_cedge_vm.yml @@ -0,0 +1,163 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Create public IP addresses for machine: {{ hostname }}" + azure.azcollection.azure_rm_publicipaddress: + resource_group: "{{ az_resource_group }}" + allocation_method: static + name: "public-ip-{{ hostname }}-vpn-{{ subnet_item.VPN }}" + tags: + Name: "public-ip-{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ subnet_item.VPN }}" + Subnet: "{{ subnet_item.name }}" + loop: "{{ az_subnets }}" + loop_control: + loop_var: subnet_item + register: public_ip_addresses + +- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" + azure_rm_securitygroup_info: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + register: az_res_gr + +- name: "Extend Network Security Group for machine, NSG: {{ az_network_security_group }}" + azure.azcollection.azure_rm_securitygroup: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + rules: + - name: "{{ public_ip_state.state.name }}" + protocol: "*" + destination_port_range: "*" + source_port_range: "*" + source_address_prefix: "{{ public_ip_state.state.ip_address }}" + access: Allow + priority: "{{ 1500 + ((az_res_gr.securitygroups | first).rules | length) + 1 + my_idx }}" + direction: Inbound + tags: + Name: "{{ az_network_security_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + +- name: "Create virtual network interface cards" + azure.azcollection.azure_rm_networkinterface: + resource_group: "{{ az_resource_group }}" + name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + virtual_network: "{{ az_virtual_network }}" + subnet_name: "{{ public_ip_state.state.tags.Subnet }}" + security_group: "{{ az_network_security_group }}" + ip_configurations: + - name: "ipconfig-vpn-{{ public_ip_state.state.tags.VPN }}" + public_ip_address_name: "{{ public_ip_state.state.name }}" + private_ip_allocation_method: "Dynamic" + tags: + Name: "nic-{{ hostname }}-vpn-{{ public_ip_state.state.tags.VPN }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + VPN: "{{ public_ip_state.state.tags.VPN }}" + loop: "{{ public_ip_addresses.results }}" + loop_control: + loop_var: public_ip_state + index_var: my_idx + label: public_ip_state.state.name + register: cedge_nics + +- name: Set az_network_interfaces_cedge fact with a list of interfaces for cedge + ansible.builtin.set_fact: + az_network_interfaces_cedge: "{{ cedge_nics.results | map(attribute='state') | list }}" + az_public_ip_addresses_cedge: "{{ public_ip_addresses.results | map(attribute='state') | list }}" + +- name: Filter az_network_interfaces_cedge for instance creation. Set az_mgmt_nic and az_transport_nic facts + ansible.builtin.set_fact: + az_mgmt_nic: "{{ az_network_interfaces_cedge | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_nic: "{{ az_network_interfaces_cedge | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + az_mgmt_public_ip: "{{ az_public_ip_addresses_cedge | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + az_transport_public_ip: "{{ az_public_ip_addresses_cedge | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + +# cedge_mgmt_private_ip +- name: "Set ip addresses cedge facts" + ansible.builtin.set_fact: + cedge_mgmt_private_ip: "{{ az_mgmt_nic.ip_configuration.private_ip_address }}" + cedge_transport_private_ip: "{{ az_transport_nic.ip_configuration.private_ip_address }}" + cedge_mgmt_public_ip: "{{ az_mgmt_public_ip.ip_address }}" + cedge_transport_public_ip: "{{ az_transport_public_ip.ip_address }}" + +- name: "Set vpn0_default_gateway fact from VPN 0 subnet value" + set_fact: + vpn0_default_gateway: "{{ item.cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" + loop: "{{ az_subnets }}" + when: item.VPN == 0 + +- name: "Set path for bootstrap configuration: {{ userdata_cedge_path }}-{{ hostname }}" + ansible.builtin.set_fact: + generated_userdata_cedge: "{{ userdata_cedge_path }}-{{ hostname }}" + changed_when: true + +- name: "Template userdata file for cedge: {{ hostname }}" + ansible.builtin.template: + src: ./userdata_cedge.j2 # ./bond.j2 ./userdata_cedge.j2 + dest: "{{ generated_userdata_cedge }}" + mode: "0644" + +- name: "Create cedge VM: {{ hostname }}" + azure.azcollection.azure_rm_virtualmachine: + resource_group: "{{ az_resource_group }}" + name: "{{ hostname }}" + vm_size: "{{ az_cedge_vm_size }}" + ssh_password_enabled: true + admin_username: "{{ admin_username }}-tmp" + admin_password: "{{ admin_password }}" + managed_disk_type: "StandardSSD_ZRS" + os_disk_size_gb: 30 + os_disk_name: "{{ hostname }}-os-disk" + os_type: "Linux" + os_disk_caching: "ReadWrite" + ephemeral_os_disk: false + linux_config: + disable_password_authentication: false + network_interfaces: + - "{{ az_mgmt_nic.id }}" + - "{{ az_transport_nic.id }}" + image: + offer: "{{ az_cedge_image_offer }}" + publisher: "{{ az_cedge_image_publisher }}" + sku: "{{ az_cedge_image_sku }}" + version: "{{ az_cedge_image_version }}" + plan: + name: "{{ az_cedge_image_sku }}" + product: "{{ az_cedge_image_offer }}" + publisher: "{{ az_cedge_image_publisher }}" + boot_diagnostics: + enabled: true + type: "managed" + tags: + Name: "{{ hostname }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + custom_data: "{{ lookup('file', generated_userdata_cedge) }}" + +- name: Store cEdge instance details for deployment_results + ansible.builtin.set_fact: + instance: + hostname: "{{ hostname }}" + system_ip: "{{ system_ip }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" + mgmt_public_ip: "{{ cedge_mgmt_public_ip }}" + transport_public_ip: "{{ cedge_transport_public_ip }}" + changed_when: true + notify: Show deployment_facts + +- name: Update deployment facts - cedge - that will be consumed by vManage-client in Ansible + ansible.builtin.set_fact: + deployment_facts: + deployed_edge_instances: "{{ deployment_facts.deployed_edge_instances + [instance] }}" diff --git a/roles/azure_edges/tasks/main.yml b/roles/azure_edges/tasks/main.yml new file mode 100644 index 0000000..f5f9ed7 --- /dev/null +++ b/roles/azure_edges/tasks/main.yml @@ -0,0 +1,71 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Verify if user session with Azure is active + ansible.builtin.include_role: + name: common + tasks_from: az_user_session_probe + +- name: "Check if the value of hostname has length of 32 or less" + ansible.builtin.assert: + that: + - instance_item.hostname | length > 0 + - instance_item.hostname | length <= 32 + fail_msg: "Verification for hostname failed, wrong hostname: {{ instance_item.hostname }}" + loop: "{{ edge_instances }}" + loop_control: + loop_var: instance_item + label: "{{ instance_item.hostname }}" + +- name: Assert all required variables for Azure cEdges deployment + ansible.builtin.include_role: + name: common + tasks_from: aws_required_variables + defaults_from: az_required_vars_edges.yml + +- name: "Prepare directory for results, path: {{ results_dir }}" + ansible.builtin.file: + path: "{{ results_dir }}" + state: directory + mode: "0755" + +- name: Verify if inside specified VN there are already existing instances that match requested instances + ansible.builtin.include_role: + name: common + tasks_from: az_existing_instances.yml + vars: + instances_marked_for_deployment: "{{ edge_instances }}" + +- name: Define deployment facts - that will be consumed by vManage-client in Ansible + ansible.builtin.set_fact: + deployment_facts: + deployed_edge_instances: [] + +- name: Create ec2 instance - cEdge (C8000V) + ansible.builtin.include_tasks: azure_cedge_vm.yml + vars: + hostname: "{{ instance_item.hostname }}" + uuid: "{{ instance_item.uuid }}" + otp: "{{ instance_item.otp }}" + vbond: "{{ instance_item.vbond }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ edge_instances }}" + loop_control: + loop_var: instance_item + when: edge_instances is defined and (instance_item.hostname not in instances_info or not instances_info[instance_item.hostname]) + +- name: Extract deployment facts + ansible.builtin.include_role: + name: common + tasks_from: generate_deployment_facts_edges.yml + when: deployment_facts.deployed_edge_instances | length > 0 + +- name: Check reachability of cEdge instances with SSH probe + ansible.builtin.include_role: + name: common + tasks_from: wait_for_ssh_readiness + vars: + ssh_readiness_delay: 10 + ssh_readiness_timeout: 600 + ssh_readiness_instances: "{{ deployment_facts.deployed_edge_instances }}" diff --git a/roles/azure_edges/templates/userdata_cedge.j2 b/roles/azure_edges/templates/userdata_cedge.j2 new file mode 100644 index 0000000..e968d09 --- /dev/null +++ b/roles/azure_edges/templates/userdata_cedge.j2 @@ -0,0 +1,231 @@ +Content-Type: multipart/mixed; boundary="===============0630588950316195806==" +MIME-Version: 1.0 + +--===============0630588950316195806== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="tmpo3jv4ny6" + +#cloud-config +vinitparam: + - uuid : {{ uuid }} + - otp : {{ otp }} + - org : {{ organization_name }} + - vbond: {{ vbond }} + + +--===============0630588950316195806== +Content-Type: text/cloud-boothook; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="config-{{ uuid }}.txt" + +#cloud-boothook + system + ztp-status success + pseudo-confirm-commit 300 + personality vedge + device-model vedge-C8000V + chassis-number {{ uuid }} + system-ip {{ system_ip }} + overlay-id 1 + site-id {{ site_id }} + no transport-gateway enable + port-offset 1 + control-session-pps 300 + admin-tech-on-failure + sp-organization-name "{{ organization_name }}" + organization-name "{{ organization_name }}" + port-hop + track-transport + track-default-gateway + console-baud-rate 19200 + config-template-name Default_Azure_vWAN_C8000V_Template_V01 + no on-demand enable + on-demand idle-timeout 10 + vbond {{ vbond }} port {{ vbond_port }} + ! + bfd color lte + hello-interval 1000 + no pmtu-discovery + multiplier 1 + ! + bfd default-dscp 48 + bfd app-route multiplier 2 + bfd app-route poll-interval 123400 + security + ipsec + rekey 86400 + replay-window 512 + authentication-type ah-sha1-hmac sha1-hmac + integrity-type ip-udp-esp esp + ! + ! + sslproxy + no enable + rsa-key-modulus 2048 + certificate-lifetime 730 + eckey-type P256 + ca-tp-label PROXY-SIGNING-CA + settings expired-certificate drop + settings untrusted-certificate drop + settings unknown-status drop + settings certificate-revocation-check none + settings unsupported-protocol-versions drop + settings unsupported-cipher-suites drop + settings failure-mode close + settings minimum-tls-ver TLSv1 + dual-side optimization enable + ! + sdwan + interface GigabitEthernet1 + tunnel-interface + encapsulation ipsec weight 1 + no border + color default + no last-resort-circuit + no low-bandwidth-link + no vbond-as-stun-server + vmanage-connection-preference 5 + port-hop + carrier default + nat-refresh-interval 5 + hello-interval 1000 + hello-tolerance 12 + no allow-service all + no allow-service bgp + allow-service dhcp + allow-service dns + allow-service icmp + allow-service sshd + no allow-service netconf + no allow-service ntp + no allow-service ospf + no allow-service stun + allow-service https + no allow-service snmp + no allow-service bfd + exit + exit + interface GigabitEthernet2 + exit + appqoe + no tcpopt enable + no dreopt enable + no httpopt enable + ! + omp + no shutdown + send-path-limit 4 + ecmp-limit 4 + graceful-restart + no as-dot-notation + timers + holdtime 15 + advertisement-interval 1 + graceful-restart-timer 120 + eor-timer 300 + exit + address-family ipv4 + advertise connected + advertise static + ! + address-family ipv6 + advertise connected + advertise static + ! + ! + ! + service tcp-keepalives-in + service tcp-keepalives-out + no service tcp-small-servers + no service udp-small-servers + hostname {{ hostname }} + username admin privilege 15 secret 0 {{ admin_password }} + vrf definition Mgmt-intf + rd 1:512 + address-family ipv4 + route-target export 1:512 + route-target import 1:512 + exit-address-family + ! + address-family ipv6 + exit-address-family + ! + ! + ip arp proxy disable + no ip finger + no ip rcmd rcp-enable + no ip rcmd rsh-enable + no ip dhcp use class + no ip ftp passive + ip bootp server + no ip source-route + no ip ssh bulk-mode + no ip http server + no ip http secure-server + no ip http ctc authentication + ip nat settings central-policy + interface GigabitEthernet1 + no shutdown + arp timeout 1200 + ip address dhcp client-id GigabitEthernet1 + no ip redirects + ip dhcp client default-router distance 1 + ip mtu 1500 + load-interval 30 + mtu 1500 + negotiation auto + exit + interface GigabitEthernet2 + no shutdown + arp timeout 1200 + ip address dhcp client-id GigabitEthernet2 + no ip redirects + ip dhcp client default-router distance 1 + ip mtu 1500 + load-interval 30 + mtu 1500 + negotiation auto + exit + interface Tunnel1 + no shutdown + ip unnumbered GigabitEthernet1 + no ip redirects + ipv6 unnumbered GigabitEthernet1 + no ipv6 redirects + tunnel source GigabitEthernet1 + tunnel mode sdwan + exit + clock timezone UTC 0 0 + logging persistent size 104857600 filesize 10485760 + no logging monitor + logging buffered 512000 + logging console + aaa authentication login default local + aaa authorization exec default local + aaa server radius dynamic-author + ! + no crypto ikev2 diagnose error + no crypto isakmp diagnose error + no network-clock revertive + snmp-server ifindex persist + fhrp version vrrp v2 + line con 0 + speed 19200 + stopbits 1 + ! + line vty 0 4 + transport input ssh + ! + line vty 5 80 + transport input ssh + ! + lldp run + nat64 translation timeout tcp 3600 + nat64 translation timeout udp 300 + ! +! + +--===============0630588950316195806==-- \ No newline at end of file diff --git a/roles/azure_edges/vars/main.yml b/roles/azure_edges/vars/main.yml new file mode 100644 index 0000000..ae6acca --- /dev/null +++ b/roles/azure_edges/vars/main.yml @@ -0,0 +1,12 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# vars/ are used by the role and not likely to be changed +# Deployment results path +results_dir: "{{ playbook_dir }}/results" + + +# Path to templated userdata config +userdata_cedge_path: "{{ results_dir }}/.userdata_cedge" diff --git a/roles/azure_network_infrastructure/defaults/main.yml b/roles/azure_network_infrastructure/defaults/main.yml new file mode 100644 index 0000000..c0a1274 --- /dev/null +++ b/roles/azure_network_infrastructure/defaults/main.yml @@ -0,0 +1,40 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +organization_name: null # has to be set by user + +################################################## +# Networking Azure configuration defaults # +################################################## + +# Common +az_location: null +az_tag_creator: "{{ organization_name }}" +az_resources_prefix: "{{ organization_name }}" # default to organization_name, but user should have option to modify + +# Resource group +az_resource_group: "{{ az_resources_prefix }}-rg" + +# Virtual Network +az_virtual_network: "{{ az_resources_prefix }}-vn" +az_vn_address_prefixes_cidr: 10.0.0.0/16 + +# Subnets +az_subnets: + - name: "{{ az_resources_prefix }}-mgmt-subnet-512" + cidr: "10.0.1.0/24" + VPN: 512 + - name: "{{ az_resources_prefix }}-transport-subnet-0" + cidr: "10.0.2.0/24" + VPN: 0 + # - name: "{{ az_resources_prefix }}-cluster-subnet-1" + # subnet_cidr: "10.0.3.0/24" + # VPN: 1 + +# Security group +az_network_security_group: "{{ az_resources_prefix }}-nsg" + + +# VPN subnets from which we can connect to Azure EIPs (Network Security Group config) +az_allowed_subnets: null diff --git a/roles/azure_network_infrastructure/meta/main.yml b/roles/azure_network_infrastructure/meta/main.yml new file mode 100644 index 0000000..c192ecb --- /dev/null +++ b/roles/azure_network_infrastructure/meta/main.yml @@ -0,0 +1,3 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- diff --git a/roles/azure_network_infrastructure/tasks/azure_network_infrastructure.yml b/roles/azure_network_infrastructure/tasks/azure_network_infrastructure.yml new file mode 100644 index 0000000..768868f --- /dev/null +++ b/roles/azure_network_infrastructure/tasks/azure_network_infrastructure.yml @@ -0,0 +1,81 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Create resource group: {{ az_resource_group }}" + azure.azcollection.azure_rm_resourcegroup: + name: "{{ az_resource_group }}" + location: "{{ az_location }}" + tags: + Name: "{{ az_resource_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + +- name: "Create virtual network: {{ az_virtual_network }}" + azure.azcollection.azure_rm_virtualnetwork: + resource_group: "{{ az_resource_group }}" + name: "{{ az_virtual_network }}" + address_prefixes: "{{ az_vn_address_prefixes_cidr }}" + tags: + Name: "{{ az_virtual_network }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" + +- name: "Create subnets inside virtual network: {{ az_virtual_network }}" + azure.azcollection.azure_rm_subnet: + resource_group: "{{ az_resource_group }}" + name: "{{ subnet_item.name }}" + address_prefixes_cidr: "{{ subnet_item.cidr }}" + virtual_network: "{{ az_virtual_network }}" + loop: "{{ az_subnets }}" + loop_control: + loop_var: subnet_item + +# TODO enable for customers handy way to define not only az_allowed_subnets +# but also custom rules for Security Groups. Both AWS and Azure +- name: "Create Network Security Group: {{ az_network_security_group }}" + azure.azcollection.azure_rm_securitygroup: + resource_group: "{{ az_resource_group }}" + name: "{{ az_network_security_group }}" + rules: + - name: DenySSH + protocol: Tcp + destination_port_range: 22-23 + access: Deny + priority: 4000 + direction: Inbound + - name: ExternalTCP + protocol: Tcp + destination_port_range: + - 22 + - 443 + - 830 # NETCONF over SSH + - 8443 + source_address_prefix: "{{ az_allowed_subnets }}" + access: Allow + priority: 1001 + direction: Inbound + - name: InternalTCP + protocol: Tcp + destination_port_range: 23456-24156 + source_address_prefix: "{{ az_allowed_subnets }}" + access: Allow + priority: 1002 + direction: Inbound + - name: InternalUDP + protocol: Udp + destination_port_range: 12346-13046 + source_address_prefix: "{{ az_allowed_subnets }}" + access: Allow + priority: 1003 + direction: Inbound + - name: ICMP + protocol: Icmp + source_address_prefix: "{{ az_allowed_subnets }}" + access: Allow + priority: 1004 + tags: + Name: "{{ az_network_security_group }}" + Creator: "{{ az_tag_creator }}" + Organization: "{{ organization_name }}" diff --git a/roles/azure_network_infrastructure/tasks/main.yml b/roles/azure_network_infrastructure/tasks/main.yml new file mode 100644 index 0000000..1672bd6 --- /dev/null +++ b/roles/azure_network_infrastructure/tasks/main.yml @@ -0,0 +1,23 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: "Verify if user session with Azure is active" + ansible.builtin.include_role: + name: common + tasks_from: az_user_session_probe + +- name: "Assert all required variables for Azure network infrastructure deployment" + ansible.builtin.include_role: + name: common + tasks_from: required_variables + defaults_from: az_required_vars_network_infrastructure.yml + +- name: "Prepare directory for results, path: {{ results_dir }}" + ansible.builtin.file: + path: "{{ results_dir }}" + state: directory + mode: "0755" + +# Add task to verify if images name or image id have been provided +- name: "Network resources for SD-WAN machines" + ansible.builtin.include_tasks: azure_network_infrastructure.yml diff --git a/roles/azure_network_infrastructure/vars/main.yml b/roles/azure_network_infrastructure/vars/main.yml new file mode 100644 index 0000000..7305bde --- /dev/null +++ b/roles/azure_network_infrastructure/vars/main.yml @@ -0,0 +1,8 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# vars/ are used by the role and not likely to be changed +# Deployment results path +results_dir: "{{ playbook_dir }}/results" diff --git a/roles/azure_teardown/defaults/main.yml b/roles/azure_teardown/defaults/main.yml new file mode 100644 index 0000000..9701317 --- /dev/null +++ b/roles/azure_teardown/defaults/main.yml @@ -0,0 +1,20 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +organization_name: null # has to be set by user + +wait_for_teardown: true # if set to false, teardown playbook will finish witout waiting for result + +################################################## +# Networking Azure configuration defaults # +################################################## + +# Common +az_location: null +az_tag_creator: "{{ organization_name }}" +az_resources_prefix: "{{ organization_name }}" # default to organization_name, but user should have option to modify + +# Resource group +az_resource_group: "{{ az_resources_prefix }}-rg" + diff --git a/roles/azure_teardown/meta/main.yml b/roles/azure_teardown/meta/main.yml new file mode 100644 index 0000000..c192ecb --- /dev/null +++ b/roles/azure_teardown/meta/main.yml @@ -0,0 +1,3 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- diff --git a/roles/azure_teardown/tasks/az_teardown_rg.yml b/roles/azure_teardown/tasks/az_teardown_rg.yml new file mode 100644 index 0000000..8386c3b --- /dev/null +++ b/roles/azure_teardown/tasks/az_teardown_rg.yml @@ -0,0 +1,7 @@ +--- + +- name: "Remove resource group: {{ az_resource_group }}" + azure.azcollection.azure_rm_resourcegroup: + name: "{{ az_resource_group }}" + force_delete_nonempty: true + state: absent diff --git a/roles/azure_teardown/tasks/main.yml b/roles/azure_teardown/tasks/main.yml new file mode 100644 index 0000000..bcf20a2 --- /dev/null +++ b/roles/azure_teardown/tasks/main.yml @@ -0,0 +1,10 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: Verify if user session with Azure is active + ansible.builtin.include_role: + name: common + tasks_from: az_user_session_probe + +- name: Remove Azure Resource Group and wait for teardown completion + ansible.builtin.include_tasks: az_teardown_rg.yml diff --git a/roles/common/defaults/required_vars_controllers.yml b/roles/common/defaults/aws_required_vars_controllers.yml similarity index 100% rename from roles/common/defaults/required_vars_controllers.yml rename to roles/common/defaults/aws_required_vars_controllers.yml diff --git a/roles/common/defaults/required_vars_edges.yml b/roles/common/defaults/aws_required_vars_edges.yml similarity index 100% rename from roles/common/defaults/required_vars_edges.yml rename to roles/common/defaults/aws_required_vars_edges.yml diff --git a/roles/common/defaults/required_vars_network_infrastructure.yml b/roles/common/defaults/aws_required_vars_network_infrastructure.yml similarity index 100% rename from roles/common/defaults/required_vars_network_infrastructure.yml rename to roles/common/defaults/aws_required_vars_network_infrastructure.yml diff --git a/roles/common/defaults/az_required_vars_controllers.yml b/roles/common/defaults/az_required_vars_controllers.yml new file mode 100644 index 0000000..af1e803 --- /dev/null +++ b/roles/common/defaults/az_required_vars_controllers.yml @@ -0,0 +1,13 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +required_variables: + organization_name: "{{ organization_name }}" + az_location: "{{ az_location }}" + az_resource_group: "{{ az_resource_group }}" + az_network_security_group: "{{ az_network_security_group }}" + az_subnets: "{{ az_subnets }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" diff --git a/roles/common/defaults/az_required_vars_edges.yml b/roles/common/defaults/az_required_vars_edges.yml new file mode 100644 index 0000000..2fff9b9 --- /dev/null +++ b/roles/common/defaults/az_required_vars_edges.yml @@ -0,0 +1,17 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +required_variables: + organization_name: "{{ organization_name }}" + az_location: "{{ az_location }}" + az_resource_group: "{{ az_resource_group }}" + az_network_security_group: "{{ az_network_security_group }}" + az_subnets: "{{ az_subnets }}" + az_cedge_image_offer: "{{ az_cedge_image_offer }}" + az_cedge_image_publisher: "{{ az_cedge_image_publisher }}" + az_cedge_image_sku: "{{ az_cedge_image_sku }}" + az_cedge_image_version: "{{ az_cedge_image_version }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" diff --git a/roles/common/defaults/az_required_vars_network_infrastructure.yml b/roles/common/defaults/az_required_vars_network_infrastructure.yml new file mode 100644 index 0000000..3f10d2d --- /dev/null +++ b/roles/common/defaults/az_required_vars_network_infrastructure.yml @@ -0,0 +1,10 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +required_variables: + organization_name: "{{ organization_name }}" + az_location: "{{ az_location }}" + az_subnets: "{{ az_subnets }}" + az_allowed_subnets: "{{ az_allowed_subnets }}" diff --git a/roles/common/tasks/az_existing_instances.yml b/roles/common/tasks/az_existing_instances.yml new file mode 100644 index 0000000..90a3cea --- /dev/null +++ b/roles/common/tasks/az_existing_instances.yml @@ -0,0 +1,59 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +# VN info +- name: Retrieve specific VN details + azure.azcollection.azure_rm_virtualnetwork_info: + resource_group: "{{ az_resource_group }}" + name: "{{ az_virtual_network }}" + register: az_virtualnetwork_info + +- name: Initialize instances_info dictionary + ansible.builtin.set_fact: + instances_info: {} + +- name: "Gather facts about all instances in resource_group: {{ az_resource_group }}" + azure.azcollection.azure_rm_virtualmachine_info: + resource_group: "{{ az_resource_group }}" + register: az_instance_info + when: az_virtualnetwork_info.virtualnetworks | length > 0 + + +# We are working inside one VN, consider changing desing in order to maintain more VNs. +- name: Verify if there are instances with requested parameters already present + when: az_instance_info is defined and az_instance_info.vms | length > 0 + block: + - name: Set instance status and state, variable 'instances_info' will hold list of existing instances + ansible.builtin.set_fact: + instances_info: >- + {{ + instances_info | default({}) | combine({ + instance_item.hostname: { + 'state': (az_instance_info.vms | selectattr('name', 'equalto', instance_item.hostname) | map(attribute='provisioning_state') | first) + } + }) if instance_item.hostname in (az_instance_info.vms | map(attribute='name') | list) else instances_info + }} + loop: "{{ instances_marked_for_deployment }}" + loop_control: + loop_var: instance_item + when: instance_item | length > 0 + + - name: Prompt user information about existing instances + ansible.builtin.pause: + prompt: | + + Detected instances with the same name as requested via configuration file: + + {{ instances_info | to_nice_yaml }} + + + Instances defined withing configuration file will not be re-deployed. Please verify your instances. + + Do you want to continue? (yes/no) [yes] + when: instances_info | length > 0 + register: user_response + + - name: Stop deployment if user response is 'no' + ansible.builtin.meta: end_play + when: instances_info | length > 0 and user_response.user_input | default('yes') | lower == 'no' diff --git a/roles/common/tasks/az_user_session_probe.yml b/roles/common/tasks/az_user_session_probe.yml new file mode 100644 index 0000000..210ab0f --- /dev/null +++ b/roles/common/tasks/az_user_session_probe.yml @@ -0,0 +1,19 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates + +--- + +# Verify if user session is active +- name: Get Azure caller facts + azure.azcollection.azure_rm_account_info: + register: az_facts + ignore_errors: true + +- name: Check Azure connection + ansible.builtin.debug: + msg: "Azure connection is active." + when: az_facts is succeeded + +- name: Fail if Azure connection is not active + ansible.builtin.fail: + msg: "Azure connection is not active or not congigured. Original message: {{ az_facts.msg }}" + when: az_facts is failed diff --git a/roles/common/tasks/generate_deployment_facts_controllers.yml b/roles/common/tasks/generate_deployment_facts_controllers.yml new file mode 100644 index 0000000..ba3b6b9 --- /dev/null +++ b/roles/common/tasks/generate_deployment_facts_controllers.yml @@ -0,0 +1,42 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Add these: + # private_mgmt_ip: + # private_transport_ip: + +- name: Set dictionary for additional variables + ansible.builtin.set_fact: + _additional: + organization_name: "{{ organization_name }}" + vbond_transport_public_ip: "{{ vbond_transport_public_ip | default('null', true) }}" + +- name: Update deployment facts with additional variables + ansible.builtin.set_fact: + deployment_facts: "{{ deployment_facts | ansible.builtin.combine(_additional) }}" + + +# for deployment results filename .yml extension will be added along with timestamp +# results_path_controllers: "{{ results_dir }}/deployment_facts_edges" +- name: Set results_path_controllers if not defined + block: + - name: Get info about time + ansible.builtin.setup: + gather_subset: + - min + - name: Create path + ansible.builtin.set_fact: + results_path_controllers: "{{ results_dir }}/deployment_facts_controllers_{{ ansible_date_time.date }}.yml" + when: results_path_controllers is not defined + +- name: Generate file to store deployment facts - {{ results_path_controllers }} + ansible.builtin.blockinfile: + create: true + state: present + mode: "0644" + insertafter: EOF + dest: "{{ results_path_controllers }}" + marker: "# {mark} ansible generated data" + content: "{{ deployment_facts | to_nice_yaml(indent=2) }}" diff --git a/roles/aws_edges/tasks/generate_deployment_facts.yml b/roles/common/tasks/generate_deployment_facts_edges.yml similarity index 100% rename from roles/aws_edges/tasks/generate_deployment_facts.yml rename to roles/common/tasks/generate_deployment_facts_edges.yml diff --git a/roles/common/tasks/aws_required_variables.yml b/roles/common/tasks/required_variables.yml similarity index 100% rename from roles/common/tasks/aws_required_variables.yml rename to roles/common/tasks/required_variables.yml diff --git a/roles/common/tasks/wait_for_ssh_readiness.yml b/roles/common/tasks/wait_for_ssh_readiness.yml new file mode 100644 index 0000000..1199557 --- /dev/null +++ b/roles/common/tasks/wait_for_ssh_readiness.yml @@ -0,0 +1,16 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +- name: "Wait for device ssh server readiness, timeout in seconds: {{ ssh_readiness_timeout | default(600) }}" + ansible.builtin.wait_for: + delay: "{{ ssh_readiness_delay | default(60) }}" + timeout: "{{ ssh_readiness_timeout | default(600) }}" + state: started + host: 20.185.83.97 + port: 22 + connect_timeout: 15 + loop: "{{ ssh_readiness_instances }}" + loop_control: + loop_var: instance_item diff --git a/roles/template_cloudinit/defaults/main.yml b/roles/template_cloudinit/defaults/main.yml new file mode 100644 index 0000000..ff99414 --- /dev/null +++ b/roles/template_cloudinit/defaults/main.yml @@ -0,0 +1,50 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +organization_name: null # has to be set by user + +aws_tag_creator: "{{ organization_name }}" + + +aws_resources_prefix: "{{ organization_name }}" + +aws_key_name: null + + +########################################## +# SD-WAN Instances configuration # +########################################## + +# Cloud-init general configurations +admin_username: admin +admin_password: Cisco#123@Viptela +vbond_port: 12346 +default_vbond_ip: 192.168.1.199 # default ips from official Cisco guides +# vpn0_interface_color: default + + +############################### +# Controllers # +############################### + +# vManage +site_id_vmanage: 100 + +vmanage_instances: [] + +# vBond +site_id_vbond: 200 + +vbond_instances: [] + + +# vSmart +site_id_vsmart: 300 + +vsmart_instances: [] + +# cedge C8000K +edge_instances: [] + diff --git a/roles/template_cloudinit/meta/main.yml b/roles/template_cloudinit/meta/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/template_cloudinit/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml b/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml new file mode 100644 index 0000000..6e90831 --- /dev/null +++ b/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml @@ -0,0 +1,17 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# template cloud init with proper ip assigned to EiP +# cloud-init +- name: Set path for bootstrap configuration + ansible.builtin.set_fact: + generated_userdata_vbond: "{{ userdata_vbond_path }}-{{ hostname }}" + changed_when: true + +- name: Template userdata file for vBond + ansible.builtin.template: + src: ./userdata_vbond.j2 + dest: "{{ generated_userdata_vbond }}" + mode: "0644" diff --git a/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml b/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml new file mode 100644 index 0000000..45707a0 --- /dev/null +++ b/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml @@ -0,0 +1,16 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# cloud-init +- name: Set path for bootstrap configuration + ansible.builtin.set_fact: + generated_userdata_vmanage: "{{ userdata_vmanage_path }}-{{ hostname }}" + changed_when: true + +- name: Template userdata file for vManage + ansible.builtin.template: + src: ./userdata_vmanage.j2 + dest: "{{ generated_userdata_vmanage }}" + mode: "0644" diff --git a/roles/template_cloudinit/tasks/aws_vsmart_ec2_instance.yml b/roles/template_cloudinit/tasks/aws_vsmart_ec2_instance.yml new file mode 100644 index 0000000..db57d84 --- /dev/null +++ b/roles/template_cloudinit/tasks/aws_vsmart_ec2_instance.yml @@ -0,0 +1,180 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# For vsmart +# +# 2 aws_network_interface +# 2 aws_network_interface_attachment +# 2 aws_eip +# 1 ec2 instance + + +# NICs +- name: Filter required subnets for instance creation. Set aws_mgmt_subnet and aws_transport_subnet facts + ansible.builtin.set_fact: + aws_mgmt_subnet: "{{ aws_subnets_config | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + aws_transport_subnet: "{{ aws_subnets_config | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + +# There are already few deployments that failed because of +# 'error: code: InvalidNetworkInterfaceID.NotFound' +# For that we add retry to proceed, can be debugged later +- name: Create network interfaces for vsmart + amazon.aws.ec2_eni: + subnet_id: "{{ subnet_item.id }}" + description: Network interface for SD-WAN Controller + security_groups: "{{ aws_security_group_config.group_id }}" + region: "{{ aws_region }}" + tags: + Name: "nic-{{ subnet_item.tags.Name }}" + Creator: "{{ aws_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ subnet_item.tags.VPN }}" + register: network_interfaces_vsmart + loop: "{{ [aws_mgmt_subnet, aws_transport_subnet] }}" + loop_control: + loop_var: subnet_item + label: "nic-{{ subnet_item.tags.Name }}" + # retries: 3 + # delay: 3 + # until: network_interfaces_vsmart.results | map(attribute='rc') | all(is_same=True, test_value=0) + +- name: Set aws_network_interfaces fact with a list of interfaces for vSmart + ansible.builtin.set_fact: + aws_network_interfaces: "{{ network_interfaces_vsmart.results | map(attribute='interface') | list }}" + +- name: Filter aws_network_interfaces for instance creation. Set aws_mgmt_nic and aws_transport_nic facts + ansible.builtin.set_fact: + aws_mgmt_nic: "{{ aws_network_interfaces | selectattr('tags.VPN', 'equalto', '512') | list | first }}" + aws_transport_nic: "{{ aws_network_interfaces | selectattr('tags.VPN', 'equalto', '0') | list | first }}" + + +# EIPs +- name: Associate EIP with mgmt network interface + amazon.aws.ec2_eip: + device_id: "{{ interface_item.id }}" + region: "{{ aws_region }}" + in_vpc: true + state: present + tags: + Name: "eip-for-{{ interface_item.tags.Name }}" + Creator: "{{ aws_tag_creator }}" + Machine: "{{ hostname }}" + VPN: "{{ interface_item.tags.VPN }}" + loop: "{{ [aws_mgmt_nic, aws_transport_nic] }}" # We do loop starting with mgmt nic, so we know results[0] is mgmt ip + loop_control: + loop_var: interface_item + label: "eip-for-{{ interface_item.tags.Name }}" + register: eip_vsmart + retries: 3 + delay: 3 + until: eip_vsmart is succeeded + + +# cloud-init +- name: Set path for bootstrap configuration + ansible.builtin.set_fact: + generated_userdata_vsmart: "{{ userdata_vsmart_path }}-{{ hostname }}" + changed_when: true + +- name: Template userdata file for vSmart + ansible.builtin.template: + src: ./userdata_vsmart.j2 + dest: "{{ generated_userdata_vsmart }}" + mode: "0644" + + +# vManage +- name: Launch vsmart + amazon.aws.ec2_instance: + count: 1 + instance_type: "{{ aws_vsmart_instance_type }}" + image: + id: "{{ aws_vsmart_ami_id }}" + state: present + vpc_subnet_id: "{{ aws_mgmt_subnet.id }}" + region: "{{ aws_region }}" + key_name: "{{ aws_key_name | default('') | bool | ternary(aws_key_name, omit) }}" + network: + assign_public_ip: false + interfaces: + - id: "{{ aws_mgmt_nic.id }}" + device_index: 0 + description: "{{ aws_mgmt_nic.tags.Name }}" + - id: "{{ aws_transport_nic.id }}" + device_index: 1 + description: "{{ aws_transport_nic.tags.Name }}" + name: "{{ hostname }}" + tags: + Name: "{{ hostname }}" + Creator: "{{ aws_tag_creator }}" + user_data: "{{ lookup('file', generated_userdata_vsmart) }}" + volumes: + - device_name: /dev/xvda + ebs: + volume_size: 23 + delete_on_termination: true + register: ec2_vsmart + +# TODO: +# Note that the variable: ec2_vsmart.instances[0].network_interfaces is returning a list of interfaces +# but that list can be different than device_index (so mgmt and transport are mixed) + +- name: Store vSmart instance details for deployment_results + ansible.builtin.set_fact: + instance: + hostname: "{{ hostname }}" + system_ip: "{{ system_ip }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" + mgmt_public_ip: "{{ eip_vsmart.results[0].public_ip }}" + transport_public_ip: "{{ eip_vsmart.results[1].public_ip }}" + changed_when: true + notify: Show deployment_facts + register: _vsmart_facts + retries: 3 + delay: 3 + until: _vsmart_facts is succeeded + + +- name: Update deployment facts - vSmart - that will be consumed by vManage-client in Ansible + ansible.builtin.set_fact: + deployment_facts: + vsmart_instances: "{{ deployment_facts.vsmart_instances + [instance] }}" + vmanage_instances: "{{ deployment_facts.vmanage_instances }}" + vbond_instances: "{{ deployment_facts.vbond_instances }}" + + +- name: Copy ec2 vSmart resources information to log file + ansible.builtin.blockinfile: + create: true + state: present + mode: "0644" + insertafter: EOF + dest: "{{ aws_deployed_controllers_data }}" + marker: "\n-------------- ec2 vsmart --------------\n" + content: "{{ ec2_vsmart | to_nice_yaml }}" + + +- name: Allow traffic outside VPC for vSmart IP addresses + amazon.aws.ec2_security_group: + name: "{{ aws_security_group_config.group_name }}" + description: "Security Group for SD-WAN instances" + vpc_id: "{{ aws_vpc_config.id }}" + region: "{{ aws_region }}" + purge_rules: false + purge_tags: false + purge_rules_egress: false + rules: + - proto: all + cidr_ip: "{{ eip_vsmart.results[0].public_ip }}/32" + rule_desc: "{{ hostname }} - mgmt (VPN 512)" + - proto: all + cidr_ip: "{{ eip_vsmart.results[1].public_ip }}/32" + rule_desc: "{{ hostname }} - transport (VPN 0)" + rules_egress: [] + register: allow_traffic + retries: 3 + delay: 3 + until: allow_traffic is succeeded diff --git a/roles/template_cloudinit/tasks/main.yml b/roles/template_cloudinit/tasks/main.yml new file mode 100644 index 0000000..809897f --- /dev/null +++ b/roles/template_cloudinit/tasks/main.yml @@ -0,0 +1,61 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Example topology deployed according to: +# +# https://www.cisco.com/c/en/us/td/docs/routers/sdwan/configuration/sdwan-xe-gs-book/controller-aws.html +# +# More extensive topologies and cluster support TODO + + +- name: Assert all required variables for AWS cloudinit generation + ansible.builtin.include_role: + name: common + tasks_from: aws_required_variables + defaults_from: required_vars_controllers.yml + +- name: "Prepare directory for results, path: {{ results_dir }}" + ansible.builtin.file: + path: "{{ results_dir }}" + state: directory + mode: "0755" + +# cloud-init vBond data requires information about private IP assigned to mgmt interface +# cloud-init templates require information about vBond IP +# vbond_mgmt_private_ip & ec2_vbond_mgmt_public_ip +# That are the reasons why vBond has to go up first (if we will use static IPs it can be changed) + +- name: Generate cloudinit template for vBond + ansible.builtin.include_tasks: aws_vbond_cloudinit.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vbond_instances }}" + loop_control: + loop_var: instance_item + when: vbond_instances is defined + +- name: Generate cloudinit template for vManage + ansible.builtin.include_tasks: aws_vmanage_cloudinit.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vmanage_instances }}" + loop_control: + loop_var: instance_item + when: vmanage_instances is defined + +- name: Generate cloudinit template for vSmart + ansible.builtin.include_tasks: aws_vsmart_cloudinit.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + loop: "{{ vsmart_instances }}" + loop_control: + loop_var: instance_item + when: vsmart_instances is defined diff --git a/roles/template_cloudinit/templates/userdata_vbond.j2 b/roles/template_cloudinit/templates/userdata_vbond.j2 new file mode 100644 index 0000000..c383742 --- /dev/null +++ b/roles/template_cloudinit/templates/userdata_vbond.j2 @@ -0,0 +1,81 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +write_files: +- path: /etc/default/personality + content: "vedge\n" +- path: /etc/default/inited + content: "1\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vedge + vedge-cloud + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id }} + + {{ vbond_transport_private_ip }} + + + + + + {{ admin_username }} + {{ admin_password }} + + + + + + 0 + + ge0/0 + + true + + + + ipsec + + + default + + + true + true + + + false + + + + 512 + + eth0 + + true + + false + + + + +--===============8815267485200512281== \ No newline at end of file diff --git a/roles/template_cloudinit/templates/userdata_vmanage.j2 b/roles/template_cloudinit/templates/userdata_vmanage.j2 new file mode 100644 index 0000000..947ba73 --- /dev/null +++ b/roles/template_cloudinit/templates/userdata_vmanage.j2 @@ -0,0 +1,105 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +disk_setup: + /dev/nvme1n1: + table_type: mbr + layout: false + overwrite: false +fs_setup: +- device: /dev/nvme1n1 + label: data + partition: none + filesystem: ext4 + overwrite: false +mounts: +- [ /dev/nvme1n1, /opt/data ] + +write_files: +- path: /opt/web-app/etc/persona + owner: vmanage:vmanage-admin + permissions: '0644' + content: '{"persona":"COMPUTE_AND_DATA"}' +- path: /etc/default/personality + content: "vmanage\n" +- path: /etc/default/inited + content: "1\n" +# These are only for internal usage +# - path: /etc/viptela/testbed +# content: "\n" +# - path: /boot/testbed +# content: "\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vmanage + vmanage + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id_vmanage }} + + {{ vbond_transport_public_ip | default(default_vbond_ip) }} + + + local + radius + tacacs + + admin + {{ admin_password }} + netadmin + + + + + + 0 + + eth1 + + true + + + + true + true + true + true + true + true + true + + + false + + + + 512 + + eth0 + + true + + false + + + + +--===============8815267485200512281== \ No newline at end of file diff --git a/roles/template_cloudinit/templates/userdata_vsmart.j2 b/roles/template_cloudinit/templates/userdata_vsmart.j2 new file mode 100644 index 0000000..767f780 --- /dev/null +++ b/roles/template_cloudinit/templates/userdata_vsmart.j2 @@ -0,0 +1,79 @@ +Content-Type: multipart/mixed; boundary="===============8815267485200512281==" +MIME-Version: 1.0 + +--===============8815267485200512281== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="cloud-config" + + +#cloud-config + +chpasswd: + expire: false + list: + - root:root + - {{ admin_username }}:{{ admin_password }} +write_files: +- path: /etc/default/personality + content: "vsmart\n" +- path: /etc/default/inited + content: "1\n" +- path: /etc/confd/init/zcloud.xml + content: | + + + {{ hostname }} + vsmart + vsmart + {{ system_ip }} + {{ organization_name }} + {{ organization_name }} + {{ site_id }} + + {{ vbond_transport_public_ip | default(default_vbond_ip) }} + + + + {{ admin_username }} + {{ admin_password }} + + + + + + 0 + + eth1 + + true + + + + ipsec + + + default + + + true + true + + + false + + + + 512 + + eth0 + + true + + false + + + + +--===============8815267485200512281== \ No newline at end of file diff --git a/roles/template_cloudinit/vars/main.yml b/roles/template_cloudinit/vars/main.yml new file mode 100644 index 0000000..f2d38c0 --- /dev/null +++ b/roles/template_cloudinit/vars/main.yml @@ -0,0 +1,18 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# vars/ are used by the role and not likely to be changed + + +# Deployment results path +results_dir: "{{ playbook_dir }}/results" + +aws_deployed_controllers_data: "{{ results_dir }}/.aws_deployed_controllers_data.yml" + + +# Path to templated userdata config +userdata_vmanage_path: "{{ results_dir }}/.userdata_vmanage" +userdata_vbond_path: "{{ results_dir }}/.userdata_vbond" +userdata_vsmart_path: "{{ results_dir }}/.userdata_vsmart" From 1d12e0411aaccd8c1bae5989e0c941c25b86810d Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 4 Apr 2024 18:58:46 +0200 Subject: [PATCH 02/20] fix for ansible-lint for config files --- .ansible-lint | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.ansible-lint b/.ansible-lint index 5a680dd..248e07b 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -13,7 +13,8 @@ exclude_paths: - .dev_dir/dev_vars.yml - .dev_dir/example_dev_vars.yml - playbooks/results/ - - playbooks/sdwan_config* + - playbooks/aws_sdwan_config* + - playbooks/azure_sdwan_config* - playbooks/specific_edges_to_teardown.yml # parseable: true # quiet: true From 5324ebfb19a7c1b6b16a865f02506f07e00cbf08 Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 4 Apr 2024 19:25:01 +0200 Subject: [PATCH 03/20] add noqa for # noqa syntax-check[unknown-module] --- .../tasks/aws_gather_network_resources.yml | 2 +- roles/aws_teardown/tasks/main.yml | 2 +- roles/common/tasks/aws_existing_instances.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/aws_network_infrastructure/tasks/aws_gather_network_resources.yml b/roles/aws_network_infrastructure/tasks/aws_gather_network_resources.yml index 9f4d91e..e0d3508 100644 --- a/roles/aws_network_infrastructure/tasks/aws_gather_network_resources.yml +++ b/roles/aws_network_infrastructure/tasks/aws_gather_network_resources.yml @@ -8,7 +8,7 @@ # VPC info - name: Retrieve VPC details - amazon.aws.ec2_vpc_net_info: + amazon.aws.ec2_vpc_net_info: # noqa: syntax-check[unknown-module] region: "{{ aws_region }}" filters: "tag:Name": "{{ aws_vpc_name }}" diff --git a/roles/aws_teardown/tasks/main.yml b/roles/aws_teardown/tasks/main.yml index ece856d..4dc011a 100644 --- a/roles/aws_teardown/tasks/main.yml +++ b/roles/aws_teardown/tasks/main.yml @@ -19,7 +19,7 @@ # VPC info - name: Retrieve VPC details - amazon.aws.ec2_vpc_net_info: + amazon.aws.ec2_vpc_net_info: # noqa: syntax-check[unknown-module] region: "{{ aws_region }}" filters: "tag:Name": "{{ aws_vpc_name }}" diff --git a/roles/common/tasks/aws_existing_instances.yml b/roles/common/tasks/aws_existing_instances.yml index 234743c..b2aa3b5 100644 --- a/roles/common/tasks/aws_existing_instances.yml +++ b/roles/common/tasks/aws_existing_instances.yml @@ -4,7 +4,7 @@ --- # VPC info - name: Retrieve VPC details - amazon.aws.ec2_vpc_net_info: + amazon.aws.ec2_vpc_net_info: # noqa: syntax-check[unknown-module] region: "{{ aws_region }}" filters: "tag:Name": "{{ aws_vpc_config.tags.Name }}" From b81e8dedc2e7e4552226593ae884030984011739 Mon Sep 17 00:00:00 2001 From: acichon Date: Fri, 5 Apr 2024 08:35:18 +0200 Subject: [PATCH 04/20] use full collection names and safe loops --- roles/aws_network_infrastructure/.DS_Store | Bin 6148 -> 0 bytes roles/azure_controllers/defaults/main.yml | 2 +- .../azure_controllers/tasks/azure_vbond_vm.yml | 10 ++++++---- .../tasks/azure_vmanage_vm.yml | 12 +++++++----- .../azure_controllers/tasks/azure_vsmart_vm.yml | 10 ++++++---- .../tasks/generate_deployment_facts.yml | 16 ++++++++-------- roles/azure_edges/tasks/azure_cedge_vm.yml | 10 ++++++---- roles/azure_teardown/defaults/main.yml | 1 - .../generate_deployment_facts_controllers.yml | 16 ++++++++-------- roles/template_cloudinit/defaults/main.yml | 1 - ...c2_instance.yml => aws_vsmart_cloudinit.yml} | 0 11 files changed, 42 insertions(+), 36 deletions(-) delete mode 100644 roles/aws_network_infrastructure/.DS_Store rename roles/template_cloudinit/tasks/{aws_vsmart_ec2_instance.yml => aws_vsmart_cloudinit.yml} (100%) diff --git a/roles/aws_network_infrastructure/.DS_Store b/roles/aws_network_infrastructure/.DS_Store deleted file mode 100644 index 6c130550098aed6e9b6c92355584e057e65fc248..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n1@lf?%O2_^Y?_TprCgpJrL?v{2r_^|ww;MgL}Uavl!pynvwic9^)jMBIL^4-SLfs5bli1v-vx|2l&fsyBKsEKc4$<9 z3Qz$mKn1A4rxnNwI~srbV4g<>sKC!FVBd!VH>` Date: Fri, 5 Apr 2024 14:20:56 +0200 Subject: [PATCH 05/20] fix requirements --- .ansible-lint | 2 +- .pre-commit-config.yaml | 2 +- pyproject.toml | 82 ++ requirements.txt | 818 +++++++++++++++--- .../templates/userdata_vbond.j2 | 2 +- .../templates/userdata_vmanage.j2 | 2 +- .../templates/userdata_vsmart.j2 | 2 +- roles/aws_edges/templates/bootstrap_cedge.j2 | 2 +- .../templates/userdata_vbond.j2 | 2 +- .../templates/userdata_vmanage.j2 | 2 +- .../templates/userdata_vsmart.j2 | 2 +- roles/azure_edges/templates/userdata_cedge.j2 | 2 +- .../templates/userdata_vbond.j2 | 2 +- .../templates/userdata_vmanage.j2 | 2 +- .../templates/userdata_vsmart.j2 | 2 +- 15 files changed, 802 insertions(+), 124 deletions(-) create mode 100644 pyproject.toml diff --git a/.ansible-lint b/.ansible-lint index 248e07b..27dc519 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -1,7 +1,7 @@ --- # .ansible-lint -profile: null # min, basic, moderate,safety, shared, production +profile: production # min, basic, moderate, safety, shared, production # Allows dumping of results in SARIF format # sarif_file: result.sarif diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d98a23..2b575ce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/ansible-community/ansible-lint.git - rev: v24.2.0 # latest release tag from https://github.com/ansible-community/ansible-lint/releases/ + rev: v24.2.1 # latest release tag from https://github.com/ansible-community/ansible-lint/releases/ hooks: - id: ansible-lint files: \.(yaml|yml)$ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b0676f1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,82 @@ +[tool.poetry] +name = "ansible-collection-sdwan-deployment" +version = "0.1.0" +description = "Ansible roles and playbooks for deploying and tearing down Cisco SD-WAN on AWS and Azure" +authors = ["acichon "] +license = "GPL-3.0" +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.10" +ansible = "^9.4.0" +boto3 = "1.34.78" +botocore = "1.34.78" +msal = "1.27.0" +azure-cli-core = "^2.59.0" +azure-common = "^1.1.28" +azure-identity = "^1.15.0" +azure-mgmt-authorization = "^4.0.0" +azure-mgmt-apimanagement = "^4.0.1" +azure-mgmt-batch = "^17.3.0" +azure-mgmt-cdn = "^13.0.0" +azure-mgmt-compute = "^30.6.0" +azure-mgmt-containerinstance = "^10.1.0" +azure-mgmt-core = "^1.4.0" +azure-mgmt-containerregistry = "^10.3.0" +azure-containerregistry = "^1.2.0" +azure-mgmt-containerservice = "^29.1.0" +azure-mgmt-datalake-store = "^0.5.0" +azure-mgmt-datafactory = "^6.1.0" +azure-mgmt-dns = "^8.1.0" +azure-mgmt-marketplaceordering = "^1.1.0" +azure-mgmt-monitor = "^6.0.2" +azure-mgmt-managedservices = "^6.0.0" +azure-mgmt-managementgroups = "^1.0.0" +azure-mgmt-network = "^25.3.0" +azure-mgmt-nspkg = "^3.0.2" +azure-mgmt-privatedns = "^1.1.0" +azure-mgmt-redis = "^14.3.0" +azure-mgmt-resource = "^23.0.1" +azure-mgmt-rdbms = "^10.1.0" +azure-mgmt-search = "^9.1.0" +azure-mgmt-servicebus = "^8.2.0" +azure-mgmt-sql = "^3.0.1" +azure-mgmt-storage = "^21.1.0" +azure-mgmt-trafficmanager = "^1.1.0" +azure-mgmt-web = "^7.2.0" +azure-nspkg = "^3.0.2" +azure-storage-blob = "^12.19.1" +msrest = "^0.7.1" +azure-core = "^1.30.1" +msrestazure = "^0.6.4" +azure-keyvault = "^4.2.0" +azure-mgmt-keyvault = "^10.3.0" +azure-graphrbac = "^0.61.1" +azure-mgmt-cosmosdb = "^9.4.0" +azure-mgmt-hdinsight = "^9.0.0" +azure-mgmt-devtestlabs = "^9.0.0" +azure-mgmt-loganalytics = "^12.0.0" +azure-mgmt-automation = "^1.0.0" +azure-mgmt-iothub = "^3.0.0" +azure-mgmt-recoveryservices = "^2.5.0" +azure-mgmt-recoveryservicesbackup = "^9.0.0" +azure-mgmt-notificationhubs = "^8.0.0" +azure-mgmt-eventhub = "^11.0.0" +pre-commit = "^3.7.0" +netaddr = "^1.2.1" + +[tool.poetry.dev-dependencies] +ansible-lint = { version = "^24.2.1", markers = "platform_system != 'Windows'" } + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 120 + +[tool.isort] +profile = "black" +line_length = 120 diff --git a/requirements.txt b/requirements.txt index 10950b8..3942e5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,111 +1,707 @@ -adal==1.2.7 -ansible==8.7.0 -ansible-core==2.15.9 -applicationinsights==0.11.10 -argcomplete==1.12.3 -azure-cli-core==2.34.0 -azure-cli-telemetry==1.0.6 -azure-common==1.1.11 -azure-containerregistry==1.1.0 -azure-core==1.28.0 -azure-graphrbac==0.61.1 -azure-identity==1.7.0 -azure-iot-hub==2.6.1 -azure-keyvault==4.2.0 -azure-keyvault-certificates==4.7.0 -azure-keyvault-keys==4.8.0 -azure-keyvault-secrets==4.7.0 -azure-mgmt-apimanagement==3.0.0 -azure-mgmt-authorization==2.0.0 -azure-mgmt-automation==1.0.0 -azure-mgmt-batch==16.2.0 -azure-mgmt-cdn==11.0.0 -azure-mgmt-compute==26.1.0 -azure-mgmt-containerinstance==9.0.0 -azure-mgmt-containerregistry==9.1.0 -azure-mgmt-containerservice==20.0.0 -azure-mgmt-core==1.3.0 -azure-mgmt-cosmosdb==6.4.0 -azure-mgmt-datafactory==2.0.0 -azure-mgmt-datalake-store==1.0.0 -azure-mgmt-devtestlabs==9.0.0 -azure-mgmt-dns==8.0.0 -azure-mgmt-eventhub==10.1.0 -azure-mgmt-hdinsight==9.0.0 -azure-mgmt-iothub==2.2.0 -azure-mgmt-keyvault==10.0.0 -azure-mgmt-loganalytics==12.0.0 -azure-mgmt-managedservices==6.0.0 -azure-mgmt-managementgroups==1.0.0 -azure-mgmt-marketplaceordering==1.1.0 -azure-mgmt-monitor==3.0.0 -azure-mgmt-network==19.1.0 -azure-mgmt-notificationhubs==7.0.0 -azure-mgmt-nspkg==2.0.0 -azure-mgmt-privatedns==1.0.0 -azure-mgmt-rdbms==10.0.0 -azure-mgmt-recoveryservices==2.0.0 -azure-mgmt-recoveryservicesbackup==3.0.0 -azure-mgmt-redis==13.0.0 -azure-mgmt-resource==21.1.0 -azure-mgmt-search==8.0.0 -azure-mgmt-servicebus==7.1.0 -azure-mgmt-sql==3.0.1 -azure-mgmt-storage==19.0.0 -azure-mgmt-trafficmanager==1.0.0b1 -azure-mgmt-web==6.1.0 -azure-nspkg==2.0.0 -azure-storage-blob==12.11.0 -bcrypt==4.1.2 -boto3==1.34.69 -botocore==1.34.69 -certifi==2024.2.2 -cffi==1.16.0 -cfgv==3.4.0 -charset-normalizer==3.3.2 -cryptography==42.0.5 -distlib==0.3.8 -filelock==3.13.3 -humanfriendly==10.0 -identify==2.5.35 -idna==3.6 -importlib-resources==5.0.7 -isodate==0.6.1 -Jinja2==3.1.3 -jmespath==1.0.1 -knack==0.9.0 -MarkupSafe==2.1.5 -msal==1.23.0 -msal-extensions==0.3.1 -msrest==0.7.1 -msrestazure==0.6.4 -netaddr==1.2.1 -nodeenv==1.8.0 -oauthlib==3.2.2 -packaging==21.3 -paramiko==2.12.0 -pkginfo==1.10.0 -platformdirs==4.2.0 -portalocker==1.7.1 -pre-commit==3.7.0 -psutil==5.9.8 -pycparser==2.21 -Pygments==2.17.2 -PyJWT==2.8.0 -PyNaCl==1.5.0 -pyOpenSSL==24.1.0 -pyparsing==3.1.2 -PySocks==1.7.1 -python-dateutil==2.9.0.post0 -PyYAML==6.0.1 -requests==2.31.0 -requests-oauthlib==2.0.0 -resolvelib==1.0.1 -s3transfer==0.10.1 -six==1.16.0 -tabulate==0.9.0 -typing_extensions==4.10.0 -uamqp==1.6.8 -urllib3==1.26.18 -virtualenv==20.25.1 -xmltodict==0.13.0 +adal==1.2.7 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2a7451ed7441ddbc57703042204a3e30ef747478eea022c70f789fc7f084bc3d \ + --hash=sha256:d74f45b81317454d96e982fd1c50e6fb5c99ac2223728aea8764433a39f566f1 +ansible-core==2.16.5 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:371b0bb11d109a58982684307c18cc44ff8d408b1b3350c0c5c78d9f096ee1f1 \ + --hash=sha256:cdd29b0ec3f20c35657355a2f6a9c1d0cf1131da99cc9a4a3401801b0ab36d6d +ansible==9.4.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:dd431c63380e18c3faca3288ebde8ce2f4f992363ab558a3c11c8f2032d90867 \ + --hash=sha256:f1d67a2c21dbed3fee4fe579f750e5d20b5a5f13f4399f256a8a70f0505e62f7 +applicationinsights==0.11.10 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0b761f3ef0680acf4731906dfc1807faa6f2a57168ae74592db0084a6099f7b3 \ + --hash=sha256:e89a890db1c6906b6a7d0bcfd617dac83974773c64573147c8d6654f9cf2a6ea +argcomplete==3.1.6 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3b1f07d133332547a53c79437527c00be48cca3807b1d4ca5cab1b26313386a6 \ + --hash=sha256:71f4683bc9e6b0be85f2b2c1224c47680f210903e23512cfebfe5a41edfd883a +azure-cli-core==2.59.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:560fee308654f851435ece9cc9d6412e10fa72cd3b00a5fc327efe029b052caf \ + --hash=sha256:879733b55309e5ce23739a3f6bfa2198ea8e232015e10477021eaedef3965f23 +azure-cli-telemetry==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2fc12608c0cf0ea6e69b392af9cab92f1249340b8caff7e9674cf91b3becb337 \ + --hash=sha256:d922379cda1b48952be75fb3bd2ac5e7ceecf569492a6088bab77894c624a278 +azure-common==1.1.28 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4ac0cd3214e36b6a1b6a442686722a5d8cc449603aa833f3f0f40bda836704a3 \ + --hash=sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad +azure-containerregistry==1.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4acd32821d086553eabd5ddfecbb21fb915b5d13ef8375d15afcb2c80bdc96a3 \ + --hash=sha256:7ba5b84911f1b381cec290b22747a679b98ddbf536fae7923124743f5ed97e6c +azure-core==1.30.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:26273a254131f84269e8ea4464f3560c731f29c0c1f69ac99010845f239c1a8f \ + --hash=sha256:7c5ee397e48f281ec4dd773d67a0a47a0962ed6fa833036057f9ea067f688e74 +azure-graphrbac==0.61.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:53e98ae2ca7c19b349e9e9bb1b6a824aeae8dcfcbe17190d20fe69c0f185b2e2 \ + --hash=sha256:7b4e0f05676acc912f2b33c71c328d9fb2e4dc8e70ebadc9d3de8ab08bf0b175 +azure-identity==1.15.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4c28fc246b7f9265610eb5261d65931183d019a23d4b0e99357facb2e6c227c8 \ + --hash=sha256:a14b1f01c7036f11f148f22cd8c16e05035293d714458d6b44ddf534d93eb912 +azure-keyvault-certificates==4.8.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:6466b8ce33b628d7336e5f4fba3e18fb9a42f1342f19a7e4029f69b1b2fa1198 \ + --hash=sha256:c561273e4402c25114873486c98bfa1b2c47886229d4100e87daf100ee047728 +azure-keyvault-keys==4.9.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:05eff85600f2f288a38e5c818ff77c5121840d327e66188cfa7ad333defb545b \ + --hash=sha256:08632dcd6ece28657204e9a256ad64369fe2b0e385ed43349f932f007d89f774 +azure-keyvault-secrets==4.8.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5636c0a1d8a20e3c5799cb3ccffd4ebf3f0d1acb7cae9526861833af8b0fe814 \ + --hash=sha256:e5898c87cef95e54a8c4aa48cdbf4717ee30543a10b793c95bd57a476554a893 +azure-keyvault==4.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:16b29039244cbe8b940c98a0d795626d76d2a579cb9b8c559983ad208082c0de \ + --hash=sha256:731add108a3e29ab4fd501a3c477256c286c34d0996b383fb6a3945462933761 +azure-mgmt-apimanagement==4.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3ed71ab763dc34413f60bcd416871563127ca8fbf14738728719854f3194c1c2 \ + --hash=sha256:5cf509cc02ed8bb4174e682dbb054384203696e5b3ef37f291612c266a47cc0e +azure-mgmt-authorization==4.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:69b85abc09ae64fc72975bd43431170d8c7eb5d166754b98aac5f3845de57dc4 \ + --hash=sha256:d8feeb3842e6ddf1a370963ca4f61fb6edc124e8997b807dd025bc9b2379cd1a +azure-mgmt-automation==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:a49d2d413fef57010cb36161e5bc056601b8d7c6d05bd3cb05a13512ef291e1e \ + --hash=sha256:a7e41afd475a4c5c751f1bede56ce040688700640797dbc3b95b34fa928e1dd7 +azure-mgmt-batch==17.3.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:8cd70837831c2681a6fa2d0b3232bbec9df69627283c6abe1c336fd230249a12 \ + --hash=sha256:fc94881a6acdb8a9533f371b6f7b2d3eaea1789eb955014b24a908d6dfe75991 +azure-mgmt-cdn==13.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:7c96088a329c2ad9fb64f5b1855e87df36acb904d1e748fbdea9b101fc95431d \ + --hash=sha256:c89f234de4f81aedb76121e5e46674fb37650b7b3e188c52e22afccff1c1900e +azure-mgmt-compute==30.6.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4d80d723ec6d4cb9583617ebec0716e7d74b2732acbaed023ed2e3cc7053d00e \ + --hash=sha256:9f6d29864ebe080796d4020533e79e4c8508512d3c53ec5a7a8930e4bd2f0bd4 +azure-mgmt-containerinstance==10.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:78d437adb28574f448c838ed5f01f9ced378196098061deb59d9f7031704c17e \ + --hash=sha256:ee7977b7b70f2233e44ec6ce8c99027f3f7892bb3452b4bad46df340d9f98959 +azure-mgmt-containerregistry==10.3.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:851e1c57f9bc4a3589c6b21fb627c11fd6cbb57a0388b7dfccd530ba3160805f \ + --hash=sha256:ae21651855dfb19c42d91d6b3a965c6c611e23f8bc4bf7138835e652d2f918e3 +azure-mgmt-containerservice==29.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0941a26a9c61930e004001e7340812dadb8a726e2ccc5b4d30ce4e6403fe1f43 \ + --hash=sha256:46887178bb1035933f06fa63121c1ac9d4c5871f202ae2b86bc4af6e1e3b354f +azure-mgmt-core==1.4.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:81071675f186a585555ef01816f2774d49c1c9024cb76e5720c3c0f6b337bb7d \ + --hash=sha256:d195208340094f98e5a6661b781cde6f6a051e79ce317caabd8ff97030a9b3ae +azure-mgmt-cosmosdb==9.4.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:8ce9ab58df018980c4cf8defb38022fa5f2a9dcbccdeb73e952374cbaff919c5 \ + --hash=sha256:cabb821cd446b09e73d24c31c287a60fcc3623488f1ffa9335c692267e79c341 +azure-mgmt-datafactory==6.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:e746f608136235eaf5e532318cf406b270d27275362ae5853e8344e1a5d2dd9c \ + --hash=sha256:f5632c7d587d71afe76db4cf56e8f5070848bfa9066653db4f3ab386f69d069b +azure-mgmt-datalake-nspkg==3.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2ac6fa13c55b87112199c5fb03a3098cefebed5f44ac34ab3d39b399951b22c4 \ + --hash=sha256:3b9e2843f5d0fd6015bba13040dfc2f5fe9bc7b02c9d91dd578e8fe852d1b2dd \ + --hash=sha256:deb192ba422f8b3ec272ce4e88736796f216f28ea5b03f28331d784b7a3f4880 +azure-mgmt-datalake-store==0.5.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2af98236cd7eaa439b239bf761338c866996ce82e9c129b204e8851e5dc095dd \ + --hash=sha256:9376d35495661d19f8acc5604f67b0bc59493b1835bbc480f9a1952f90017a4c +azure-mgmt-devtestlabs==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5fb7fd768e5ca85cd5a6726e94b9d4d2dcd71f7d3c87fdcdc42ad78fcd87e6b2 \ + --hash=sha256:d8160d93fd3d947e5613c6919176b0edf72c94ac69679ea3b92cf27ff7398e64 +azure-mgmt-dns==8.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:640be3ae428a40e5c3576a760e8c345d64df421bd1be6385d7124244f6089897 \ + --hash=sha256:d8379d4bb9194b81b79e5284d875fa6df80707346f2cbb5c5491a20f35266fd0 +azure-mgmt-eventhub==11.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:17107d4e85dde8f675794acc58302d6ce98a7254ee03f41d3fbd96b06ef36b96 \ + --hash=sha256:e8db29d76c6ebc914af225bc409b2be1184989b96877f6d9ac5efe3f09feb083 +azure-mgmt-hdinsight==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1df6d8284bc173d8d556a31a9bde677ada0fe1f52227c5d499ab05fcd71b8d4f \ + --hash=sha256:41ebdc69c0d1f81d25dd30438c14fff4331f66639f55805b918b9649eaffe78a +azure-mgmt-iothub==3.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4ba0fbe1736eebbadfe759075bc33412f03d920b5a982614bd07b9ab07a369c7 \ + --hash=sha256:daf21fc98c68a353ec616318c0e62be04c8d6899960be8c2cbf991673ac8b722 +azure-mgmt-keyvault==10.3.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:183b4164cf1868b8ea7efeaa98edad7d2a4e14a9bd977c2818b12b75150cd2a2 \ + --hash=sha256:3410cf6c703e9570ed3c8e9716e483c02b1804adde6ab437ddc8feac4545acd6 +azure-mgmt-loganalytics==12.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:75ac1d47dd81179905c40765be8834643d8994acff31056ddc1863017f3faa02 \ + --hash=sha256:da128a7e0291be7fa2063848df92a9180cf5c16d42adc09d2bc2efd711536bfb +azure-mgmt-managedservices==6.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:78db45fc282d0e1973cc1a08d42a89b53b6084af45c6b7cac2aee57a469ee7b6 \ + --hash=sha256:ec0cb3858bcf8edf5eee0eddee81560424eb84352e0df082ddc94eb99badfd5e +azure-mgmt-managementgroups==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:bab9bd532a1c34557f5b0ab9950e431e3f00bb96e8a3ce66df0f6ce2ae19cd73 \ + --hash=sha256:f569b942cfdabb4adf184aedd689dec98373fb173f5aa81131328159bfb4e629 +azure-mgmt-marketplaceordering==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:68b381f52a4df4435dacad5a97e1c59ac4c981f667dcca8f9d04453417d60ad8 \ + --hash=sha256:dbce4ea08ead3fce6c663a0b448f7e34e92ce4cdb23393aead0a65f082cb14f0 +azure-mgmt-monitor==6.0.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5ffbf500e499ab7912b1ba6d26cef26480d9ae411532019bb78d72562196e07b \ + --hash=sha256:fe4cf41e6680b74a228f81451dc5522656d599c6f343ecf702fc790fda9a357b +azure-mgmt-network==25.3.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:87b5338d14c957bd3a28a5ec85fb74043749d1a16a48cd5978ef51c4a1036af3 \ + --hash=sha256:dce2cafb1ae0e563e0b5efc537dc98a7c0ad824d4261e64bed75f788196dd5c6 +azure-mgmt-notificationhubs==8.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:4dd924f4704993e3ebf1d42e2be1cbe0b0d908e695857fa08c4369ae11d0eb36 \ + --hash=sha256:adec3271d5bf014964c98d4c10d84b92606ff4e53ab5c18eaaa39ba3be69cd5d +azure-mgmt-nspkg==3.0.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1c6f5134de78c8907e8b73a8ceaaf1f336a24193a543039994fe002bb5f7f39f \ + --hash=sha256:8b2287f671529505b296005e6de9150b074344c2c7d1c805b3f053d081d58c52 \ + --hash=sha256:d638ea5fda3ed323db943feb29acaa200f5d8ff092078bf8d29d4a2f8ed16999 +azure-mgmt-privatedns==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:32db9c605a4a8ff00d34e37551d5eb06b4ec267ab9de2a61dd2275ca95a3fb98 \ + --hash=sha256:e74f897627d23dbf14921585c033f445d65dcb84a4d5b10cbf54f5fcf6d7dcfb +azure-mgmt-rdbms==10.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:8eac17d1341a91d7ed914435941ba917b5ef1568acabc3e65653603966a7cc88 \ + --hash=sha256:a87d401c876c84734cdd4888af551e4a1461b4b328d9816af60cb8ac5979f035 +azure-mgmt-recoveryservices==2.5.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5f1a308c4858c79b83ff8bd8e61192092bdc6ab99d6dd73963618b1dc884bab5 \ + --hash=sha256:81ecccc955278c02bcf37b6836fd3f6b26dd16f95fc33ea2031ccd95c93d4dd6 +azure-mgmt-recoveryservicesbackup==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1ff4ac3bf0e71d74ac4b27a3617ec115e9b51aa3e1db40d119e72b615908bb51 \ + --hash=sha256:7d1170ea3687075fac2ee872e2cf29594cb76cb5a7390bba8bf5912333b6923d +azure-mgmt-redis==14.3.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:7a831b638a0dcd85e49f7b85521c5e709403f81c589064db5a10164a00282f20 \ + --hash=sha256:af86513a2bd57aede540d529034d6407cdc021131bb64f73125b6d92252b03e8 +azure-mgmt-resource==23.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:c2ba6cfd99df95f55f36eadc4245e3dc713257302a1fd0277756d94bd8cb28e0 \ + --hash=sha256:f185eec72bbc39f42bcb83ae6f1bad744f0e3f20a12d9b2b3e70d16c74ad9cc0 +azure-mgmt-search==9.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:488ff81477e980e2b7abf0b857387c74ebbad419e6f6126044e3e6fad2da72b6 \ + --hash=sha256:53bc6eeadb0974d21f120bb21bb5e6827df6d650e17347460fd83e2d68883599 +azure-mgmt-servicebus==8.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:22e7a81a4560d5e6b01a7ea959152f6b78668f559a60c3233d43b720061a6ff3 \ + --hash=sha256:8be9208f141d9a789f68db8d219754ff78069fd8f9390e9f7644bb95a3be9ec2 +azure-mgmt-sql==3.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:129042cc011225e27aee6ef2697d585fa5722e5d1aeb0038af6ad2451a285457 \ + --hash=sha256:1d1dd940d4d41be4ee319aad626341251572a5bf4a2addec71779432d9a1381f +azure-mgmt-storage==21.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:593f2544fc4f05750c4fe7ca4d83c32ea1e9d266e57899bbf79ce5940124e8cc \ + --hash=sha256:d6d3c0e917c988bc9ed0472477d3ef3f90886009eb1d97a711944f8375630162 +azure-mgmt-trafficmanager==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:35bf1902bf1589d626e35971e5aaa009e884094672b479b798cd1bb8d4f2fdf9 \ + --hash=sha256:911142974694bd16cfac2848e005af8e569096238fd3ad67efc91aafdc6f3858 +azure-mgmt-web==7.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:28e88602ad9d6d03ed3ba89f966f478b6148e28d292d165e5f371c92c59621df \ + --hash=sha256:efcfe6f7f520ed0abcfe86517e1c8cf02a712f737a3db0db7cb46c6d647981ed +azure-nspkg==3.0.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1d0bbb2157cf57b1bef6c8c8e5b41133957364456c43b0a43599890023cca0a8 \ + --hash=sha256:31a060caca00ed1ebd369fc7fe01a56768c927e404ebc92268f4d9d636435e28 \ + --hash=sha256:e7d3cea6af63e667d87ba1ca4f8cd7cb4dfca678e4c55fc1cedb320760e39dd0 +azure-storage-blob==12.19.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:13e16ba42fc54ac2c7e8f976062173a5c82b9ec0594728e134aac372965a11b0 \ + --hash=sha256:c5530dc51c21c9564e4eb706cd499befca8819b10dd89716d3fc90d747556243 +bcrypt==4.1.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f \ + --hash=sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5 \ + --hash=sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb \ + --hash=sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258 \ + --hash=sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4 \ + --hash=sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc \ + --hash=sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2 \ + --hash=sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326 \ + --hash=sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483 \ + --hash=sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a \ + --hash=sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966 \ + --hash=sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63 \ + --hash=sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c \ + --hash=sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551 \ + --hash=sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d \ + --hash=sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e \ + --hash=sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0 \ + --hash=sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c \ + --hash=sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb \ + --hash=sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1 \ + --hash=sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42 \ + --hash=sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946 \ + --hash=sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab \ + --hash=sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1 \ + --hash=sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c \ + --hash=sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7 \ + --hash=sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369 +boto3==1.34.78 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:227487f9a40e7963aa108f4fabc81374d65e085891a2a442c190dfd976b86a9e \ + --hash=sha256:47a7899af97960493ed58754c838be658650c8fb231c658866f491965ddfc94f +botocore==1.34.78 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:889fcfd1813fad225a5a70940c58cd4bd7a6f5ba6c9769a1d41d0c670272b75d \ + --hash=sha256:bc10738826a4970a6d3a40ac40b9799c02b1b661c0c741a67b915b500562ab3c +certifi==2024.2.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ + --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 +cffi==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \ + --hash=sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a \ + --hash=sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417 \ + --hash=sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab \ + --hash=sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520 \ + --hash=sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36 \ + --hash=sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743 \ + --hash=sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8 \ + --hash=sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed \ + --hash=sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684 \ + --hash=sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56 \ + --hash=sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324 \ + --hash=sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d \ + --hash=sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235 \ + --hash=sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e \ + --hash=sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088 \ + --hash=sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000 \ + --hash=sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7 \ + --hash=sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e \ + --hash=sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673 \ + --hash=sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c \ + --hash=sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe \ + --hash=sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2 \ + --hash=sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098 \ + --hash=sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8 \ + --hash=sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a \ + --hash=sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0 \ + --hash=sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b \ + --hash=sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896 \ + --hash=sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e \ + --hash=sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9 \ + --hash=sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2 \ + --hash=sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b \ + --hash=sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6 \ + --hash=sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404 \ + --hash=sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f \ + --hash=sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0 \ + --hash=sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4 \ + --hash=sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc \ + --hash=sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936 \ + --hash=sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba \ + --hash=sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872 \ + --hash=sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb \ + --hash=sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614 \ + --hash=sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1 \ + --hash=sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d \ + --hash=sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969 \ + --hash=sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b \ + --hash=sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4 \ + --hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \ + --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ + --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 +cfgv==3.4.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \ + --hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560 +charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ + --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ + --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ + --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ + --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ + --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ + --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ + --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ + --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ + --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ + --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ + --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ + --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ + --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ + --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ + --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ + --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ + --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ + --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ + --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ + --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ + --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ + --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ + --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ + --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ + --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ + --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ + --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ + --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ + --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ + --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ + --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ + --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ + --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ + --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ + --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ + --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ + --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ + --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ + --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ + --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ + --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ + --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ + --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ + --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ + --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ + --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ + --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ + --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ + --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ + --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ + --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ + --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ + --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ + --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ + --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ + --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ + --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ + --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ + --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ + --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ + --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ + --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ + --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ + --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ + --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ + --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ + --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ + --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ + --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ + --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ + --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ + --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ + --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ + --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ + --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ + --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ + --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ + --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ + --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ + --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ + --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ + --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ + --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ + --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ + --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ + --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ + --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ + --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ + --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 +cryptography==42.0.5 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee \ + --hash=sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576 \ + --hash=sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d \ + --hash=sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30 \ + --hash=sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413 \ + --hash=sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb \ + --hash=sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da \ + --hash=sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4 \ + --hash=sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd \ + --hash=sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc \ + --hash=sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8 \ + --hash=sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1 \ + --hash=sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc \ + --hash=sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e \ + --hash=sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8 \ + --hash=sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940 \ + --hash=sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400 \ + --hash=sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7 \ + --hash=sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16 \ + --hash=sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278 \ + --hash=sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74 \ + --hash=sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec \ + --hash=sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1 \ + --hash=sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2 \ + --hash=sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c \ + --hash=sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922 \ + --hash=sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a \ + --hash=sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6 \ + --hash=sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1 \ + --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \ + --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \ + --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7 +distlib==0.3.8 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ + --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 +distro==1.9.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "linux" \ + --hash=sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed \ + --hash=sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2 +filelock==3.13.3 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb \ + --hash=sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546 +humanfriendly==10.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 \ + --hash=sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc +identify==2.5.35 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791 \ + --hash=sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e +idna==3.6 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ + --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f +isodate==0.6.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96 \ + --hash=sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9 +jinja2==3.1.3 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ + --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 +jmespath==1.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ + --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe +knack==0.11.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:6704c867840978a119a193914a90e2e98c7be7dff764c8fcd8a2286c5a978d00 \ + --hash=sha256:eb6568001e9110b1b320941431c51033d104cc98cda2254a5c2b09ba569fd494 +markupsafe==2.1.5 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ + --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ + --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ + --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ + --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ + --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ + --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ + --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ + --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ + --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ + --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ + --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ + --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ + --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ + --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ + --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ + --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ + --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ + --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ + --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ + --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ + --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ + --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ + --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ + --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ + --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ + --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ + --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ + --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ + --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ + --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ + --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ + --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ + --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ + --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ + --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ + --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ + --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ + --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ + --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ + --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ + --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ + --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ + --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ + --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ + --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ + --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ + --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ + --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ + --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ + --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ + --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ + --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ + --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ + --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ + --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ + --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ + --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ + --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ + --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 +msal-extensions==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:91e3db9620b822d0ed2b4d1850056a0f133cba04455e62f11612e40f5502f2ee \ + --hash=sha256:c676aba56b0cce3783de1b5c5ecfe828db998167875126ca4b47dc6436451354 +msal==1.27.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3109503c038ba6b307152b0e8d34f98113f2e7a78986e28d0baf5b5303afda52 \ + --hash=sha256:572d07149b83e7343a85a3bcef8e581167b4ac76befcbbb6eef0c0e19643cdc0 +msal[broker]==1.27.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3109503c038ba6b307152b0e8d34f98113f2e7a78986e28d0baf5b5303afda52 \ + --hash=sha256:572d07149b83e7343a85a3bcef8e581167b4ac76befcbbb6eef0c0e19643cdc0 +msrest==0.7.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32 \ + --hash=sha256:6e7661f46f3afd88b75667b7187a92829924446c7ea1d169be8c4bb7eeb788b9 +msrestazure==0.6.4 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3de50f56147ef529b31e099a982496690468ecef33f0544cb0fa0cfe1e1de5b9 \ + --hash=sha256:a06f0dabc9a6f5efe3b6add4bd8fb623aeadacf816b7a35b0f89107e0544d189 +netaddr==1.2.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:6eb8fedf0412c6d294d06885c110de945cf4d22d2b510d0404f4e06950857987 \ + --hash=sha256:bd9e9534b0d46af328cf64f0e5a23a5a43fca292df221c85580b27394793496e +nodeenv==1.8.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ + --hash=sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec +oauthlib==3.2.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca \ + --hash=sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918 +packaging==24.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ + --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 +paramiko==3.4.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:43f0b51115a896f9c00f59618023484cb3a14b98bbceab43394a39c6739b7ee7 \ + --hash=sha256:aac08f26a31dc4dffd92821527d1682d99d52f9ef6851968114a8728f3c274d3 +pkginfo==1.10.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297 \ + --hash=sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097 +platformdirs==4.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ + --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 +portalocker==2.8.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33 \ + --hash=sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e +pre-commit==3.7.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab \ + --hash=sha256:e209d61b8acdcf742404408531f0c37d49d2c734fd7cff2d6076083d191cb060 +psutil==5.9.8 ; python_version >= "3.10" and python_version < "4.0" and sys_platform != "cygwin" \ + --hash=sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d \ + --hash=sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73 \ + --hash=sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8 \ + --hash=sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2 \ + --hash=sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e \ + --hash=sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36 \ + --hash=sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7 \ + --hash=sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c \ + --hash=sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee \ + --hash=sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421 \ + --hash=sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf \ + --hash=sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81 \ + --hash=sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0 \ + --hash=sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631 \ + --hash=sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4 \ + --hash=sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8 +pycparser==2.22 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ + --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc +pygments==2.17.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \ + --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367 +pyjwt==2.8.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ + --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 +pyjwt[crypto]==2.8.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ + --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 +pymsalruntime==0.14.0 ; python_version >= "3.10" and platform_system == "Windows" and python_version < "4.0" \ + --hash=sha256:0a43b31f6fa9172611f3cb3b38a8b4a933e5aaf33f08e159882aaa0cd1322cb8 \ + --hash=sha256:1199024aeebdb0aa254cfcb8cab2f62b26dee4d547f5e30493681cf72217e889 \ + --hash=sha256:139eea587c1fc2fd167857443317d067a3be5f34e6ce087a4c1d78a94085a0f7 \ + --hash=sha256:2866f78cb101d13c969693bc763fd0192806cecbde8e8647442b768acad62ca0 \ + --hash=sha256:293bbc7b35ab7cf4f0862b18213b764a5983025a4d04864cca6c6ccd6a67078e \ + --hash=sha256:2a7606123129d5f46d056687eca910338de7c0b67f361c3cc31809b2b736d2f1 \ + --hash=sha256:3a4c413d91546da22229c2287e4c23e2fa094145aed686d19d2d432c627f4f23 \ + --hash=sha256:4c3008f6c2350c9d52c5bccdf0f631ff1d1a7f175469c531d446e43f2cdf4aed \ + --hash=sha256:655411b72a99a7f164911ee28f0c3cb89a6782f7d21863f98439689f617ea5a2 \ + --hash=sha256:6d2461bbec391d7420ca83951ab158030a3455ff2dde29fb2086f10e05010fe8 \ + --hash=sha256:6d4c3a9038e0348a2315752f68a507eee11daca372f2c77c2452d9ed2284376d \ + --hash=sha256:76c9eacd246177c08e0ca2e759201cd4e0e5e3186255ff23b8e5addf1be44905 \ + --hash=sha256:78b5d6c933f4e209d65258222a89cd91dd7cdde088bac80f941f2c83dd49de80 \ + --hash=sha256:7d62b4bf29b01a799b975e56ba7fe736149df6db1e6b5152384abde305532824 \ + --hash=sha256:8260c63fcd38897eeff35f35af5628e350c3040e47d3bd0f6badf829f71c21cd \ + --hash=sha256:84f7d564531c6ed510d2abf2564824344a673325b9a440dac3d4d82d5ae3b7fa \ + --hash=sha256:a54a099379f2a29f97e13fa6304dd5de99f76d16c0adff1732054ee9c0bba87a \ + --hash=sha256:a89a123b3f05d4d527215f37eb1e9ff33a9de09fb6b2d74d0df5873ead856512 \ + --hash=sha256:aca97d133d98480045279557e3ba217c782ca0a9944f8a35e16962cc4723ac17 \ + --hash=sha256:ba429415a52404dc5513fd1c8e3617d7d9dcb04b951be56da50f299c53ec22b8 \ + --hash=sha256:cfa98d0099b860f946e57d81506c8c3c0efc209bd9ed0510fc5f0801478032aa \ + --hash=sha256:d7efa342b7e280273b79548ed0f304bfcd799a643041a1a9bf6728c2008b2b6a \ + --hash=sha256:dc03267074d6b0f037e5a33564ab9bc9023b4bd6dff92abd94722e6b7ab91e59 \ + --hash=sha256:df0865f2a614839d6cde6c5bf769690edd7b1e69b6d13fd2fdc74333726a0655 \ + --hash=sha256:ebab8d86e231937febc2a5a0673f0fac6824281a6b827feec6629034d0682e55 \ + --hash=sha256:efaa27c03baf5adab4e8acd3561af36ddbde9f2efab9ad013f34a0ba62305310 \ + --hash=sha256:fd1fd7baffecdbb09f5277efd6daf8f2cff9be164dbb1080c2108b56469aec65 +pynacl==1.5.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ + --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ + --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ + --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ + --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ + --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ + --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ + --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ + --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ + --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 +pyopenssl==24.1.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad \ + --hash=sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f +pyreadline3==3.4.1 ; sys_platform == "win32" and python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae \ + --hash=sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb +pysocks==1.7.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \ + --hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \ + --hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0 +python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 +pywin32==306 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" \ + --hash=sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d \ + --hash=sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65 \ + --hash=sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e \ + --hash=sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b \ + --hash=sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4 \ + --hash=sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040 \ + --hash=sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a \ + --hash=sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36 \ + --hash=sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8 \ + --hash=sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e \ + --hash=sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802 \ + --hash=sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a \ + --hash=sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407 \ + --hash=sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0 +pyyaml==6.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ + --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ + --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f +requests-oauthlib==2.0.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36 \ + --hash=sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9 +requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 +requests[socks]==2.31.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 +resolvelib==1.0.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309 \ + --hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf +s3transfer==0.10.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19 \ + --hash=sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d +setuptools==69.2.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \ + --hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c +six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 +tabulate==0.9.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ + --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f +typing-extensions==4.10.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ + --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb +urllib3==2.2.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ + --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 +virtualenv==20.25.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ + --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 diff --git a/roles/aws_controllers/templates/userdata_vbond.j2 b/roles/aws_controllers/templates/userdata_vbond.j2 index c383742..4aa6b7e 100644 --- a/roles/aws_controllers/templates/userdata_vbond.j2 +++ b/roles/aws_controllers/templates/userdata_vbond.j2 @@ -78,4 +78,4 @@ write_files:
---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/aws_controllers/templates/userdata_vmanage.j2 b/roles/aws_controllers/templates/userdata_vmanage.j2 index 4d00f79..a9b99f9 100644 --- a/roles/aws_controllers/templates/userdata_vmanage.j2 +++ b/roles/aws_controllers/templates/userdata_vmanage.j2 @@ -97,4 +97,4 @@ write_files:
---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/aws_controllers/templates/userdata_vsmart.j2 b/roles/aws_controllers/templates/userdata_vsmart.j2 index 767f780..c5f8e7d 100644 --- a/roles/aws_controllers/templates/userdata_vsmart.j2 +++ b/roles/aws_controllers/templates/userdata_vsmart.j2 @@ -76,4 +76,4 @@ write_files:
---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/aws_edges/templates/bootstrap_cedge.j2 b/roles/aws_edges/templates/bootstrap_cedge.j2 index e968d09..40802e6 100644 --- a/roles/aws_edges/templates/bootstrap_cedge.j2 +++ b/roles/aws_edges/templates/bootstrap_cedge.j2 @@ -228,4 +228,4 @@ Content-Disposition: attachment; filename="config-{{ uuid }}.txt" ! ! ---===============0630588950316195806==-- \ No newline at end of file +--===============0630588950316195806==-- diff --git a/roles/azure_controllers/templates/userdata_vbond.j2 b/roles/azure_controllers/templates/userdata_vbond.j2 index 4a57058..d8744e7 100644 --- a/roles/azure_controllers/templates/userdata_vbond.j2 +++ b/roles/azure_controllers/templates/userdata_vbond.j2 @@ -86,4 +86,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/azure_controllers/templates/userdata_vmanage.j2 b/roles/azure_controllers/templates/userdata_vmanage.j2 index b4f4758..2beafa1 100644 --- a/roles/azure_controllers/templates/userdata_vmanage.j2 +++ b/roles/azure_controllers/templates/userdata_vmanage.j2 @@ -105,4 +105,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/azure_controllers/templates/userdata_vsmart.j2 b/roles/azure_controllers/templates/userdata_vsmart.j2 index 493f1fa..f3accbe 100644 --- a/roles/azure_controllers/templates/userdata_vsmart.j2 +++ b/roles/azure_controllers/templates/userdata_vsmart.j2 @@ -84,4 +84,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/azure_edges/templates/userdata_cedge.j2 b/roles/azure_edges/templates/userdata_cedge.j2 index e968d09..40802e6 100644 --- a/roles/azure_edges/templates/userdata_cedge.j2 +++ b/roles/azure_edges/templates/userdata_cedge.j2 @@ -228,4 +228,4 @@ Content-Disposition: attachment; filename="config-{{ uuid }}.txt" ! ! ---===============0630588950316195806==-- \ No newline at end of file +--===============0630588950316195806==-- diff --git a/roles/template_cloudinit/templates/userdata_vbond.j2 b/roles/template_cloudinit/templates/userdata_vbond.j2 index c383742..4aa6b7e 100644 --- a/roles/template_cloudinit/templates/userdata_vbond.j2 +++ b/roles/template_cloudinit/templates/userdata_vbond.j2 @@ -78,4 +78,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/template_cloudinit/templates/userdata_vmanage.j2 b/roles/template_cloudinit/templates/userdata_vmanage.j2 index 947ba73..06b800b 100644 --- a/roles/template_cloudinit/templates/userdata_vmanage.j2 +++ b/roles/template_cloudinit/templates/userdata_vmanage.j2 @@ -102,4 +102,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== diff --git a/roles/template_cloudinit/templates/userdata_vsmart.j2 b/roles/template_cloudinit/templates/userdata_vsmart.j2 index 767f780..c5f8e7d 100644 --- a/roles/template_cloudinit/templates/userdata_vsmart.j2 +++ b/roles/template_cloudinit/templates/userdata_vsmart.j2 @@ -76,4 +76,4 @@ write_files: ---===============8815267485200512281== \ No newline at end of file +--===============8815267485200512281== From 079a1c5e92bfee9516a33f137aaef017e5cd2d27 Mon Sep 17 00:00:00 2001 From: acichon Date: Fri, 5 Apr 2024 15:07:17 +0200 Subject: [PATCH 06/20] fix for ssh readiness --- pyproject.toml | 3 +- requirements.txt | 33 ++----------------- roles/aws_teardown/tasks/main.yml | 2 +- roles/common/tasks/wait_for_ssh_readiness.yml | 2 +- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b0676f1..e1559dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,12 +63,11 @@ azure-mgmt-recoveryservices = "^2.5.0" azure-mgmt-recoveryservicesbackup = "^9.0.0" azure-mgmt-notificationhubs = "^8.0.0" azure-mgmt-eventhub = "^11.0.0" -pre-commit = "^3.7.0" netaddr = "^1.2.1" [tool.poetry.dev-dependencies] ansible-lint = { version = "^24.2.1", markers = "platform_system != 'Windows'" } - +pre-commit = "^3.7.0" [build-system] requires = ["poetry-core"] diff --git a/requirements.txt b/requirements.txt index 3942e5d..ab1cd89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -265,9 +265,6 @@ cffi==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \ --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 -cfgv==3.4.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \ - --hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560 charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ @@ -392,21 +389,12 @@ cryptography==42.0.5 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \ --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \ --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7 -distlib==0.3.8 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ - --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 distro==1.9.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "linux" \ --hash=sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed \ --hash=sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2 -filelock==3.13.3 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb \ - --hash=sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546 humanfriendly==10.0 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 \ --hash=sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc -identify==2.5.35 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791 \ - --hash=sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e idna==3.6 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f @@ -501,9 +489,6 @@ msrestazure==0.6.4 ; python_version >= "3.10" and python_version < "4.0" \ netaddr==1.2.1 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:6eb8fedf0412c6d294d06885c110de945cf4d22d2b510d0404f4e06950857987 \ --hash=sha256:bd9e9534b0d46af328cf64f0e5a23a5a43fca292df221c85580b27394793496e -nodeenv==1.8.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ - --hash=sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec oauthlib==3.2.2 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca \ --hash=sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918 @@ -516,15 +501,9 @@ paramiko==3.4.0 ; python_version >= "3.10" and python_version < "4.0" \ pkginfo==1.10.0 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297 \ --hash=sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097 -platformdirs==4.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ - --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 portalocker==2.8.2 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33 \ --hash=sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e -pre-commit==3.7.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab \ - --hash=sha256:e209d61b8acdcf742404408531f0c37d49d2c734fd7cff2d6076083d191cb060 psutil==5.9.8 ; python_version >= "3.10" and python_version < "4.0" and sys_platform != "cygwin" \ --hash=sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d \ --hash=sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73 \ @@ -687,21 +666,15 @@ resolvelib==1.0.1 ; python_version >= "3.10" and python_version < "4.0" \ s3transfer==0.10.1 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19 \ --hash=sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d -setuptools==69.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e \ - --hash=sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 tabulate==0.9.0 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f -typing-extensions==4.10.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ - --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb +typing-extensions==4.11.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ + --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a urllib3==2.2.1 ; python_version >= "3.10" and python_version < "4.0" \ --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 -virtualenv==20.25.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ - --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 diff --git a/roles/aws_teardown/tasks/main.yml b/roles/aws_teardown/tasks/main.yml index 4dc011a..7286bb4 100644 --- a/roles/aws_teardown/tasks/main.yml +++ b/roles/aws_teardown/tasks/main.yml @@ -18,7 +18,7 @@ tasks_from: aws_user_session_probe # VPC info -- name: Retrieve VPC details +- name: Retrieve VPC details # noqa: syntax-check[unknown-module] amazon.aws.ec2_vpc_net_info: # noqa: syntax-check[unknown-module] region: "{{ aws_region }}" filters: diff --git a/roles/common/tasks/wait_for_ssh_readiness.yml b/roles/common/tasks/wait_for_ssh_readiness.yml index 1199557..6832409 100644 --- a/roles/common/tasks/wait_for_ssh_readiness.yml +++ b/roles/common/tasks/wait_for_ssh_readiness.yml @@ -8,7 +8,7 @@ delay: "{{ ssh_readiness_delay | default(60) }}" timeout: "{{ ssh_readiness_timeout | default(600) }}" state: started - host: 20.185.83.97 + host: "{{ instance_item.mgmt_public_ip }}" port: 22 connect_timeout: 15 loop: "{{ ssh_readiness_instances }}" From ad279eb207b2dbea35f6fa20784949354b113a9e Mon Sep 17 00:00:00 2001 From: acichon Date: Fri, 5 Apr 2024 16:50:11 +0200 Subject: [PATCH 07/20] use only requirements.txt --- .ansible-lint | 1 + pyproject.toml | 81 ----- requirements.txt | 780 ++++++----------------------------------------- 3 files changed, 101 insertions(+), 761 deletions(-) delete mode 100644 pyproject.toml diff --git a/.ansible-lint b/.ansible-lint index 27dc519..b9fafdd 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -16,6 +16,7 @@ exclude_paths: - playbooks/aws_sdwan_config* - playbooks/azure_sdwan_config* - playbooks/specific_edges_to_teardown.yml + - roles/aws_teardown/tasks/main.yml # parseable: true # quiet: true # strict: true diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index e1559dd..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,81 +0,0 @@ -[tool.poetry] -name = "ansible-collection-sdwan-deployment" -version = "0.1.0" -description = "Ansible roles and playbooks for deploying and tearing down Cisco SD-WAN on AWS and Azure" -authors = ["acichon "] -license = "GPL-3.0" -readme = "README.md" -package-mode = false - -[tool.poetry.dependencies] -python = "^3.10" -ansible = "^9.4.0" -boto3 = "1.34.78" -botocore = "1.34.78" -msal = "1.27.0" -azure-cli-core = "^2.59.0" -azure-common = "^1.1.28" -azure-identity = "^1.15.0" -azure-mgmt-authorization = "^4.0.0" -azure-mgmt-apimanagement = "^4.0.1" -azure-mgmt-batch = "^17.3.0" -azure-mgmt-cdn = "^13.0.0" -azure-mgmt-compute = "^30.6.0" -azure-mgmt-containerinstance = "^10.1.0" -azure-mgmt-core = "^1.4.0" -azure-mgmt-containerregistry = "^10.3.0" -azure-containerregistry = "^1.2.0" -azure-mgmt-containerservice = "^29.1.0" -azure-mgmt-datalake-store = "^0.5.0" -azure-mgmt-datafactory = "^6.1.0" -azure-mgmt-dns = "^8.1.0" -azure-mgmt-marketplaceordering = "^1.1.0" -azure-mgmt-monitor = "^6.0.2" -azure-mgmt-managedservices = "^6.0.0" -azure-mgmt-managementgroups = "^1.0.0" -azure-mgmt-network = "^25.3.0" -azure-mgmt-nspkg = "^3.0.2" -azure-mgmt-privatedns = "^1.1.0" -azure-mgmt-redis = "^14.3.0" -azure-mgmt-resource = "^23.0.1" -azure-mgmt-rdbms = "^10.1.0" -azure-mgmt-search = "^9.1.0" -azure-mgmt-servicebus = "^8.2.0" -azure-mgmt-sql = "^3.0.1" -azure-mgmt-storage = "^21.1.0" -azure-mgmt-trafficmanager = "^1.1.0" -azure-mgmt-web = "^7.2.0" -azure-nspkg = "^3.0.2" -azure-storage-blob = "^12.19.1" -msrest = "^0.7.1" -azure-core = "^1.30.1" -msrestazure = "^0.6.4" -azure-keyvault = "^4.2.0" -azure-mgmt-keyvault = "^10.3.0" -azure-graphrbac = "^0.61.1" -azure-mgmt-cosmosdb = "^9.4.0" -azure-mgmt-hdinsight = "^9.0.0" -azure-mgmt-devtestlabs = "^9.0.0" -azure-mgmt-loganalytics = "^12.0.0" -azure-mgmt-automation = "^1.0.0" -azure-mgmt-iothub = "^3.0.0" -azure-mgmt-recoveryservices = "^2.5.0" -azure-mgmt-recoveryservicesbackup = "^9.0.0" -azure-mgmt-notificationhubs = "^8.0.0" -azure-mgmt-eventhub = "^11.0.0" -netaddr = "^1.2.1" - -[tool.poetry.dev-dependencies] -ansible-lint = { version = "^24.2.1", markers = "platform_system != 'Windows'" } -pre-commit = "^3.7.0" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - -[tool.black] -line-length = 120 - -[tool.isort] -profile = "black" -line_length = 120 diff --git a/requirements.txt b/requirements.txt index ab1cd89..23558e8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,680 +1,100 @@ -adal==1.2.7 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2a7451ed7441ddbc57703042204a3e30ef747478eea022c70f789fc7f084bc3d \ - --hash=sha256:d74f45b81317454d96e982fd1c50e6fb5c99ac2223728aea8764433a39f566f1 -ansible-core==2.16.5 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:371b0bb11d109a58982684307c18cc44ff8d408b1b3350c0c5c78d9f096ee1f1 \ - --hash=sha256:cdd29b0ec3f20c35657355a2f6a9c1d0cf1131da99cc9a4a3401801b0ab36d6d -ansible==9.4.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:dd431c63380e18c3faca3288ebde8ce2f4f992363ab558a3c11c8f2032d90867 \ - --hash=sha256:f1d67a2c21dbed3fee4fe579f750e5d20b5a5f13f4399f256a8a70f0505e62f7 -applicationinsights==0.11.10 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0b761f3ef0680acf4731906dfc1807faa6f2a57168ae74592db0084a6099f7b3 \ - --hash=sha256:e89a890db1c6906b6a7d0bcfd617dac83974773c64573147c8d6654f9cf2a6ea -argcomplete==3.1.6 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:3b1f07d133332547a53c79437527c00be48cca3807b1d4ca5cab1b26313386a6 \ - --hash=sha256:71f4683bc9e6b0be85f2b2c1224c47680f210903e23512cfebfe5a41edfd883a -azure-cli-core==2.59.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:560fee308654f851435ece9cc9d6412e10fa72cd3b00a5fc327efe029b052caf \ - --hash=sha256:879733b55309e5ce23739a3f6bfa2198ea8e232015e10477021eaedef3965f23 -azure-cli-telemetry==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2fc12608c0cf0ea6e69b392af9cab92f1249340b8caff7e9674cf91b3becb337 \ - --hash=sha256:d922379cda1b48952be75fb3bd2ac5e7ceecf569492a6088bab77894c624a278 -azure-common==1.1.28 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4ac0cd3214e36b6a1b6a442686722a5d8cc449603aa833f3f0f40bda836704a3 \ - --hash=sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad -azure-containerregistry==1.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4acd32821d086553eabd5ddfecbb21fb915b5d13ef8375d15afcb2c80bdc96a3 \ - --hash=sha256:7ba5b84911f1b381cec290b22747a679b98ddbf536fae7923124743f5ed97e6c -azure-core==1.30.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:26273a254131f84269e8ea4464f3560c731f29c0c1f69ac99010845f239c1a8f \ - --hash=sha256:7c5ee397e48f281ec4dd773d67a0a47a0962ed6fa833036057f9ea067f688e74 -azure-graphrbac==0.61.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:53e98ae2ca7c19b349e9e9bb1b6a824aeae8dcfcbe17190d20fe69c0f185b2e2 \ - --hash=sha256:7b4e0f05676acc912f2b33c71c328d9fb2e4dc8e70ebadc9d3de8ab08bf0b175 -azure-identity==1.15.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4c28fc246b7f9265610eb5261d65931183d019a23d4b0e99357facb2e6c227c8 \ - --hash=sha256:a14b1f01c7036f11f148f22cd8c16e05035293d714458d6b44ddf534d93eb912 -azure-keyvault-certificates==4.8.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:6466b8ce33b628d7336e5f4fba3e18fb9a42f1342f19a7e4029f69b1b2fa1198 \ - --hash=sha256:c561273e4402c25114873486c98bfa1b2c47886229d4100e87daf100ee047728 -azure-keyvault-keys==4.9.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:05eff85600f2f288a38e5c818ff77c5121840d327e66188cfa7ad333defb545b \ - --hash=sha256:08632dcd6ece28657204e9a256ad64369fe2b0e385ed43349f932f007d89f774 -azure-keyvault-secrets==4.8.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5636c0a1d8a20e3c5799cb3ccffd4ebf3f0d1acb7cae9526861833af8b0fe814 \ - --hash=sha256:e5898c87cef95e54a8c4aa48cdbf4717ee30543a10b793c95bd57a476554a893 -azure-keyvault==4.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:16b29039244cbe8b940c98a0d795626d76d2a579cb9b8c559983ad208082c0de \ - --hash=sha256:731add108a3e29ab4fd501a3c477256c286c34d0996b383fb6a3945462933761 -azure-mgmt-apimanagement==4.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:3ed71ab763dc34413f60bcd416871563127ca8fbf14738728719854f3194c1c2 \ - --hash=sha256:5cf509cc02ed8bb4174e682dbb054384203696e5b3ef37f291612c266a47cc0e -azure-mgmt-authorization==4.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:69b85abc09ae64fc72975bd43431170d8c7eb5d166754b98aac5f3845de57dc4 \ - --hash=sha256:d8feeb3842e6ddf1a370963ca4f61fb6edc124e8997b807dd025bc9b2379cd1a -azure-mgmt-automation==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:a49d2d413fef57010cb36161e5bc056601b8d7c6d05bd3cb05a13512ef291e1e \ - --hash=sha256:a7e41afd475a4c5c751f1bede56ce040688700640797dbc3b95b34fa928e1dd7 -azure-mgmt-batch==17.3.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:8cd70837831c2681a6fa2d0b3232bbec9df69627283c6abe1c336fd230249a12 \ - --hash=sha256:fc94881a6acdb8a9533f371b6f7b2d3eaea1789eb955014b24a908d6dfe75991 -azure-mgmt-cdn==13.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:7c96088a329c2ad9fb64f5b1855e87df36acb904d1e748fbdea9b101fc95431d \ - --hash=sha256:c89f234de4f81aedb76121e5e46674fb37650b7b3e188c52e22afccff1c1900e -azure-mgmt-compute==30.6.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4d80d723ec6d4cb9583617ebec0716e7d74b2732acbaed023ed2e3cc7053d00e \ - --hash=sha256:9f6d29864ebe080796d4020533e79e4c8508512d3c53ec5a7a8930e4bd2f0bd4 -azure-mgmt-containerinstance==10.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:78d437adb28574f448c838ed5f01f9ced378196098061deb59d9f7031704c17e \ - --hash=sha256:ee7977b7b70f2233e44ec6ce8c99027f3f7892bb3452b4bad46df340d9f98959 -azure-mgmt-containerregistry==10.3.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:851e1c57f9bc4a3589c6b21fb627c11fd6cbb57a0388b7dfccd530ba3160805f \ - --hash=sha256:ae21651855dfb19c42d91d6b3a965c6c611e23f8bc4bf7138835e652d2f918e3 -azure-mgmt-containerservice==29.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0941a26a9c61930e004001e7340812dadb8a726e2ccc5b4d30ce4e6403fe1f43 \ - --hash=sha256:46887178bb1035933f06fa63121c1ac9d4c5871f202ae2b86bc4af6e1e3b354f -azure-mgmt-core==1.4.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:81071675f186a585555ef01816f2774d49c1c9024cb76e5720c3c0f6b337bb7d \ - --hash=sha256:d195208340094f98e5a6661b781cde6f6a051e79ce317caabd8ff97030a9b3ae -azure-mgmt-cosmosdb==9.4.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:8ce9ab58df018980c4cf8defb38022fa5f2a9dcbccdeb73e952374cbaff919c5 \ - --hash=sha256:cabb821cd446b09e73d24c31c287a60fcc3623488f1ffa9335c692267e79c341 -azure-mgmt-datafactory==6.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:e746f608136235eaf5e532318cf406b270d27275362ae5853e8344e1a5d2dd9c \ - --hash=sha256:f5632c7d587d71afe76db4cf56e8f5070848bfa9066653db4f3ab386f69d069b -azure-mgmt-datalake-nspkg==3.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2ac6fa13c55b87112199c5fb03a3098cefebed5f44ac34ab3d39b399951b22c4 \ - --hash=sha256:3b9e2843f5d0fd6015bba13040dfc2f5fe9bc7b02c9d91dd578e8fe852d1b2dd \ - --hash=sha256:deb192ba422f8b3ec272ce4e88736796f216f28ea5b03f28331d784b7a3f4880 -azure-mgmt-datalake-store==0.5.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2af98236cd7eaa439b239bf761338c866996ce82e9c129b204e8851e5dc095dd \ - --hash=sha256:9376d35495661d19f8acc5604f67b0bc59493b1835bbc480f9a1952f90017a4c -azure-mgmt-devtestlabs==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5fb7fd768e5ca85cd5a6726e94b9d4d2dcd71f7d3c87fdcdc42ad78fcd87e6b2 \ - --hash=sha256:d8160d93fd3d947e5613c6919176b0edf72c94ac69679ea3b92cf27ff7398e64 -azure-mgmt-dns==8.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:640be3ae428a40e5c3576a760e8c345d64df421bd1be6385d7124244f6089897 \ - --hash=sha256:d8379d4bb9194b81b79e5284d875fa6df80707346f2cbb5c5491a20f35266fd0 -azure-mgmt-eventhub==11.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:17107d4e85dde8f675794acc58302d6ce98a7254ee03f41d3fbd96b06ef36b96 \ - --hash=sha256:e8db29d76c6ebc914af225bc409b2be1184989b96877f6d9ac5efe3f09feb083 -azure-mgmt-hdinsight==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1df6d8284bc173d8d556a31a9bde677ada0fe1f52227c5d499ab05fcd71b8d4f \ - --hash=sha256:41ebdc69c0d1f81d25dd30438c14fff4331f66639f55805b918b9649eaffe78a -azure-mgmt-iothub==3.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4ba0fbe1736eebbadfe759075bc33412f03d920b5a982614bd07b9ab07a369c7 \ - --hash=sha256:daf21fc98c68a353ec616318c0e62be04c8d6899960be8c2cbf991673ac8b722 -azure-mgmt-keyvault==10.3.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:183b4164cf1868b8ea7efeaa98edad7d2a4e14a9bd977c2818b12b75150cd2a2 \ - --hash=sha256:3410cf6c703e9570ed3c8e9716e483c02b1804adde6ab437ddc8feac4545acd6 -azure-mgmt-loganalytics==12.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:75ac1d47dd81179905c40765be8834643d8994acff31056ddc1863017f3faa02 \ - --hash=sha256:da128a7e0291be7fa2063848df92a9180cf5c16d42adc09d2bc2efd711536bfb -azure-mgmt-managedservices==6.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:78db45fc282d0e1973cc1a08d42a89b53b6084af45c6b7cac2aee57a469ee7b6 \ - --hash=sha256:ec0cb3858bcf8edf5eee0eddee81560424eb84352e0df082ddc94eb99badfd5e -azure-mgmt-managementgroups==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:bab9bd532a1c34557f5b0ab9950e431e3f00bb96e8a3ce66df0f6ce2ae19cd73 \ - --hash=sha256:f569b942cfdabb4adf184aedd689dec98373fb173f5aa81131328159bfb4e629 -azure-mgmt-marketplaceordering==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:68b381f52a4df4435dacad5a97e1c59ac4c981f667dcca8f9d04453417d60ad8 \ - --hash=sha256:dbce4ea08ead3fce6c663a0b448f7e34e92ce4cdb23393aead0a65f082cb14f0 -azure-mgmt-monitor==6.0.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5ffbf500e499ab7912b1ba6d26cef26480d9ae411532019bb78d72562196e07b \ - --hash=sha256:fe4cf41e6680b74a228f81451dc5522656d599c6f343ecf702fc790fda9a357b -azure-mgmt-network==25.3.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:87b5338d14c957bd3a28a5ec85fb74043749d1a16a48cd5978ef51c4a1036af3 \ - --hash=sha256:dce2cafb1ae0e563e0b5efc537dc98a7c0ad824d4261e64bed75f788196dd5c6 -azure-mgmt-notificationhubs==8.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:4dd924f4704993e3ebf1d42e2be1cbe0b0d908e695857fa08c4369ae11d0eb36 \ - --hash=sha256:adec3271d5bf014964c98d4c10d84b92606ff4e53ab5c18eaaa39ba3be69cd5d -azure-mgmt-nspkg==3.0.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1c6f5134de78c8907e8b73a8ceaaf1f336a24193a543039994fe002bb5f7f39f \ - --hash=sha256:8b2287f671529505b296005e6de9150b074344c2c7d1c805b3f053d081d58c52 \ - --hash=sha256:d638ea5fda3ed323db943feb29acaa200f5d8ff092078bf8d29d4a2f8ed16999 -azure-mgmt-privatedns==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:32db9c605a4a8ff00d34e37551d5eb06b4ec267ab9de2a61dd2275ca95a3fb98 \ - --hash=sha256:e74f897627d23dbf14921585c033f445d65dcb84a4d5b10cbf54f5fcf6d7dcfb -azure-mgmt-rdbms==10.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:8eac17d1341a91d7ed914435941ba917b5ef1568acabc3e65653603966a7cc88 \ - --hash=sha256:a87d401c876c84734cdd4888af551e4a1461b4b328d9816af60cb8ac5979f035 -azure-mgmt-recoveryservices==2.5.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5f1a308c4858c79b83ff8bd8e61192092bdc6ab99d6dd73963618b1dc884bab5 \ - --hash=sha256:81ecccc955278c02bcf37b6836fd3f6b26dd16f95fc33ea2031ccd95c93d4dd6 -azure-mgmt-recoveryservicesbackup==9.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1ff4ac3bf0e71d74ac4b27a3617ec115e9b51aa3e1db40d119e72b615908bb51 \ - --hash=sha256:7d1170ea3687075fac2ee872e2cf29594cb76cb5a7390bba8bf5912333b6923d -azure-mgmt-redis==14.3.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:7a831b638a0dcd85e49f7b85521c5e709403f81c589064db5a10164a00282f20 \ - --hash=sha256:af86513a2bd57aede540d529034d6407cdc021131bb64f73125b6d92252b03e8 -azure-mgmt-resource==23.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:c2ba6cfd99df95f55f36eadc4245e3dc713257302a1fd0277756d94bd8cb28e0 \ - --hash=sha256:f185eec72bbc39f42bcb83ae6f1bad744f0e3f20a12d9b2b3e70d16c74ad9cc0 -azure-mgmt-search==9.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:488ff81477e980e2b7abf0b857387c74ebbad419e6f6126044e3e6fad2da72b6 \ - --hash=sha256:53bc6eeadb0974d21f120bb21bb5e6827df6d650e17347460fd83e2d68883599 -azure-mgmt-servicebus==8.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:22e7a81a4560d5e6b01a7ea959152f6b78668f559a60c3233d43b720061a6ff3 \ - --hash=sha256:8be9208f141d9a789f68db8d219754ff78069fd8f9390e9f7644bb95a3be9ec2 -azure-mgmt-sql==3.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:129042cc011225e27aee6ef2697d585fa5722e5d1aeb0038af6ad2451a285457 \ - --hash=sha256:1d1dd940d4d41be4ee319aad626341251572a5bf4a2addec71779432d9a1381f -azure-mgmt-storage==21.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:593f2544fc4f05750c4fe7ca4d83c32ea1e9d266e57899bbf79ce5940124e8cc \ - --hash=sha256:d6d3c0e917c988bc9ed0472477d3ef3f90886009eb1d97a711944f8375630162 -azure-mgmt-trafficmanager==1.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:35bf1902bf1589d626e35971e5aaa009e884094672b479b798cd1bb8d4f2fdf9 \ - --hash=sha256:911142974694bd16cfac2848e005af8e569096238fd3ad67efc91aafdc6f3858 -azure-mgmt-web==7.2.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:28e88602ad9d6d03ed3ba89f966f478b6148e28d292d165e5f371c92c59621df \ - --hash=sha256:efcfe6f7f520ed0abcfe86517e1c8cf02a712f737a3db0db7cb46c6d647981ed -azure-nspkg==3.0.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1d0bbb2157cf57b1bef6c8c8e5b41133957364456c43b0a43599890023cca0a8 \ - --hash=sha256:31a060caca00ed1ebd369fc7fe01a56768c927e404ebc92268f4d9d636435e28 \ - --hash=sha256:e7d3cea6af63e667d87ba1ca4f8cd7cb4dfca678e4c55fc1cedb320760e39dd0 -azure-storage-blob==12.19.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:13e16ba42fc54ac2c7e8f976062173a5c82b9ec0594728e134aac372965a11b0 \ - --hash=sha256:c5530dc51c21c9564e4eb706cd499befca8819b10dd89716d3fc90d747556243 -bcrypt==4.1.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f \ - --hash=sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5 \ - --hash=sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb \ - --hash=sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258 \ - --hash=sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4 \ - --hash=sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc \ - --hash=sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2 \ - --hash=sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326 \ - --hash=sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483 \ - --hash=sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a \ - --hash=sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966 \ - --hash=sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63 \ - --hash=sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c \ - --hash=sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551 \ - --hash=sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d \ - --hash=sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e \ - --hash=sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0 \ - --hash=sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c \ - --hash=sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb \ - --hash=sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1 \ - --hash=sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42 \ - --hash=sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946 \ - --hash=sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab \ - --hash=sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1 \ - --hash=sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c \ - --hash=sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7 \ - --hash=sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369 -boto3==1.34.78 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:227487f9a40e7963aa108f4fabc81374d65e085891a2a442c190dfd976b86a9e \ - --hash=sha256:47a7899af97960493ed58754c838be658650c8fb231c658866f491965ddfc94f -botocore==1.34.78 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:889fcfd1813fad225a5a70940c58cd4bd7a6f5ba6c9769a1d41d0c670272b75d \ - --hash=sha256:bc10738826a4970a6d3a40ac40b9799c02b1b661c0c741a67b915b500562ab3c -certifi==2024.2.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ - --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 -cffi==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc \ - --hash=sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a \ - --hash=sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417 \ - --hash=sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab \ - --hash=sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520 \ - --hash=sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36 \ - --hash=sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743 \ - --hash=sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8 \ - --hash=sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed \ - --hash=sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684 \ - --hash=sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56 \ - --hash=sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324 \ - --hash=sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d \ - --hash=sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235 \ - --hash=sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e \ - --hash=sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088 \ - --hash=sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000 \ - --hash=sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7 \ - --hash=sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e \ - --hash=sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673 \ - --hash=sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c \ - --hash=sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe \ - --hash=sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2 \ - --hash=sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098 \ - --hash=sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8 \ - --hash=sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a \ - --hash=sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0 \ - --hash=sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b \ - --hash=sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896 \ - --hash=sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e \ - --hash=sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9 \ - --hash=sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2 \ - --hash=sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b \ - --hash=sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6 \ - --hash=sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404 \ - --hash=sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f \ - --hash=sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0 \ - --hash=sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4 \ - --hash=sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc \ - --hash=sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936 \ - --hash=sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba \ - --hash=sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872 \ - --hash=sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb \ - --hash=sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614 \ - --hash=sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1 \ - --hash=sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d \ - --hash=sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969 \ - --hash=sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b \ - --hash=sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4 \ - --hash=sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627 \ - --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ - --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 -charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ - --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ - --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ - --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ - --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ - --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ - --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ - --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ - --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ - --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ - --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ - --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ - --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ - --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ - --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ - --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ - --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ - --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ - --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ - --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ - --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ - --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ - --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ - --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ - --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ - --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ - --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ - --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ - --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ - --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ - --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ - --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ - --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ - --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ - --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ - --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ - --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ - --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ - --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ - --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ - --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ - --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ - --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ - --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ - --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ - --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ - --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ - --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ - --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ - --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ - --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ - --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ - --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ - --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ - --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ - --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ - --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ - --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ - --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ - --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ - --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ - --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ - --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ - --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ - --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ - --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ - --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ - --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ - --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ - --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ - --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ - --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ - --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ - --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ - --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ - --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ - --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ - --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ - --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ - --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ - --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ - --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ - --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ - --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ - --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ - --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ - --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ - --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ - --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ - --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 -cryptography==42.0.5 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee \ - --hash=sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576 \ - --hash=sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d \ - --hash=sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30 \ - --hash=sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413 \ - --hash=sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb \ - --hash=sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da \ - --hash=sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4 \ - --hash=sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd \ - --hash=sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc \ - --hash=sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8 \ - --hash=sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1 \ - --hash=sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc \ - --hash=sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e \ - --hash=sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8 \ - --hash=sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940 \ - --hash=sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400 \ - --hash=sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7 \ - --hash=sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16 \ - --hash=sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278 \ - --hash=sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74 \ - --hash=sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec \ - --hash=sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1 \ - --hash=sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2 \ - --hash=sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c \ - --hash=sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922 \ - --hash=sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a \ - --hash=sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6 \ - --hash=sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1 \ - --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \ - --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \ - --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7 -distro==1.9.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "linux" \ - --hash=sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed \ - --hash=sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2 -humanfriendly==10.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 \ - --hash=sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc -idna==3.6 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ - --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f -isodate==0.6.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96 \ - --hash=sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9 -jinja2==3.1.3 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ - --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 -jmespath==1.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ - --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe -knack==0.11.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:6704c867840978a119a193914a90e2e98c7be7dff764c8fcd8a2286c5a978d00 \ - --hash=sha256:eb6568001e9110b1b320941431c51033d104cc98cda2254a5c2b09ba569fd494 -markupsafe==2.1.5 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ - --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ - --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ - --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ - --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ - --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ - --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ - --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ - --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ - --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ - --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ - --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ - --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ - --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ - --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ - --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ - --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ - --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ - --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ - --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ - --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ - --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ - --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ - --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ - --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ - --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ - --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ - --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ - --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ - --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ - --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ - --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ - --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ - --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ - --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ - --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ - --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ - --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ - --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ - --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ - --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ - --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ - --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ - --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ - --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ - --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ - --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ - --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ - --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ - --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ - --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ - --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ - --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ - --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ - --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ - --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ - --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ - --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ - --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ - --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 -msal-extensions==1.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:91e3db9620b822d0ed2b4d1850056a0f133cba04455e62f11612e40f5502f2ee \ - --hash=sha256:c676aba56b0cce3783de1b5c5ecfe828db998167875126ca4b47dc6436451354 -msal==1.27.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:3109503c038ba6b307152b0e8d34f98113f2e7a78986e28d0baf5b5303afda52 \ - --hash=sha256:572d07149b83e7343a85a3bcef8e581167b4ac76befcbbb6eef0c0e19643cdc0 -msal[broker]==1.27.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:3109503c038ba6b307152b0e8d34f98113f2e7a78986e28d0baf5b5303afda52 \ - --hash=sha256:572d07149b83e7343a85a3bcef8e581167b4ac76befcbbb6eef0c0e19643cdc0 -msrest==0.7.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32 \ - --hash=sha256:6e7661f46f3afd88b75667b7187a92829924446c7ea1d169be8c4bb7eeb788b9 -msrestazure==0.6.4 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:3de50f56147ef529b31e099a982496690468ecef33f0544cb0fa0cfe1e1de5b9 \ - --hash=sha256:a06f0dabc9a6f5efe3b6add4bd8fb623aeadacf816b7a35b0f89107e0544d189 -netaddr==1.2.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:6eb8fedf0412c6d294d06885c110de945cf4d22d2b510d0404f4e06950857987 \ - --hash=sha256:bd9e9534b0d46af328cf64f0e5a23a5a43fca292df221c85580b27394793496e -oauthlib==3.2.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca \ - --hash=sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918 -packaging==24.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ - --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 -paramiko==3.4.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:43f0b51115a896f9c00f59618023484cb3a14b98bbceab43394a39c6739b7ee7 \ - --hash=sha256:aac08f26a31dc4dffd92821527d1682d99d52f9ef6851968114a8728f3c274d3 -pkginfo==1.10.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297 \ - --hash=sha256:889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097 -portalocker==2.8.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33 \ - --hash=sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e -psutil==5.9.8 ; python_version >= "3.10" and python_version < "4.0" and sys_platform != "cygwin" \ - --hash=sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d \ - --hash=sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73 \ - --hash=sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8 \ - --hash=sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2 \ - --hash=sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e \ - --hash=sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36 \ - --hash=sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7 \ - --hash=sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c \ - --hash=sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee \ - --hash=sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421 \ - --hash=sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf \ - --hash=sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81 \ - --hash=sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0 \ - --hash=sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631 \ - --hash=sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4 \ - --hash=sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8 -pycparser==2.22 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ - --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc -pygments==2.17.2 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \ - --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367 -pyjwt==2.8.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ - --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 -pyjwt[crypto]==2.8.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ - --hash=sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320 -pymsalruntime==0.14.0 ; python_version >= "3.10" and platform_system == "Windows" and python_version < "4.0" \ - --hash=sha256:0a43b31f6fa9172611f3cb3b38a8b4a933e5aaf33f08e159882aaa0cd1322cb8 \ - --hash=sha256:1199024aeebdb0aa254cfcb8cab2f62b26dee4d547f5e30493681cf72217e889 \ - --hash=sha256:139eea587c1fc2fd167857443317d067a3be5f34e6ce087a4c1d78a94085a0f7 \ - --hash=sha256:2866f78cb101d13c969693bc763fd0192806cecbde8e8647442b768acad62ca0 \ - --hash=sha256:293bbc7b35ab7cf4f0862b18213b764a5983025a4d04864cca6c6ccd6a67078e \ - --hash=sha256:2a7606123129d5f46d056687eca910338de7c0b67f361c3cc31809b2b736d2f1 \ - --hash=sha256:3a4c413d91546da22229c2287e4c23e2fa094145aed686d19d2d432c627f4f23 \ - --hash=sha256:4c3008f6c2350c9d52c5bccdf0f631ff1d1a7f175469c531d446e43f2cdf4aed \ - --hash=sha256:655411b72a99a7f164911ee28f0c3cb89a6782f7d21863f98439689f617ea5a2 \ - --hash=sha256:6d2461bbec391d7420ca83951ab158030a3455ff2dde29fb2086f10e05010fe8 \ - --hash=sha256:6d4c3a9038e0348a2315752f68a507eee11daca372f2c77c2452d9ed2284376d \ - --hash=sha256:76c9eacd246177c08e0ca2e759201cd4e0e5e3186255ff23b8e5addf1be44905 \ - --hash=sha256:78b5d6c933f4e209d65258222a89cd91dd7cdde088bac80f941f2c83dd49de80 \ - --hash=sha256:7d62b4bf29b01a799b975e56ba7fe736149df6db1e6b5152384abde305532824 \ - --hash=sha256:8260c63fcd38897eeff35f35af5628e350c3040e47d3bd0f6badf829f71c21cd \ - --hash=sha256:84f7d564531c6ed510d2abf2564824344a673325b9a440dac3d4d82d5ae3b7fa \ - --hash=sha256:a54a099379f2a29f97e13fa6304dd5de99f76d16c0adff1732054ee9c0bba87a \ - --hash=sha256:a89a123b3f05d4d527215f37eb1e9ff33a9de09fb6b2d74d0df5873ead856512 \ - --hash=sha256:aca97d133d98480045279557e3ba217c782ca0a9944f8a35e16962cc4723ac17 \ - --hash=sha256:ba429415a52404dc5513fd1c8e3617d7d9dcb04b951be56da50f299c53ec22b8 \ - --hash=sha256:cfa98d0099b860f946e57d81506c8c3c0efc209bd9ed0510fc5f0801478032aa \ - --hash=sha256:d7efa342b7e280273b79548ed0f304bfcd799a643041a1a9bf6728c2008b2b6a \ - --hash=sha256:dc03267074d6b0f037e5a33564ab9bc9023b4bd6dff92abd94722e6b7ab91e59 \ - --hash=sha256:df0865f2a614839d6cde6c5bf769690edd7b1e69b6d13fd2fdc74333726a0655 \ - --hash=sha256:ebab8d86e231937febc2a5a0673f0fac6824281a6b827feec6629034d0682e55 \ - --hash=sha256:efaa27c03baf5adab4e8acd3561af36ddbde9f2efab9ad013f34a0ba62305310 \ - --hash=sha256:fd1fd7baffecdbb09f5277efd6daf8f2cff9be164dbb1080c2108b56469aec65 -pynacl==1.5.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ - --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ - --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ - --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ - --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ - --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ - --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ - --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ - --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ - --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 -pyopenssl==24.1.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad \ - --hash=sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f -pyreadline3==3.4.1 ; sys_platform == "win32" and python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae \ - --hash=sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb -pysocks==1.7.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \ - --hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \ - --hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0 -python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ - --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -pywin32==306 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" \ - --hash=sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d \ - --hash=sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65 \ - --hash=sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e \ - --hash=sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b \ - --hash=sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4 \ - --hash=sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040 \ - --hash=sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a \ - --hash=sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36 \ - --hash=sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8 \ - --hash=sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e \ - --hash=sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802 \ - --hash=sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a \ - --hash=sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407 \ - --hash=sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0 -pyyaml==6.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ - --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ - --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ - --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ - --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ - --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ - --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ - --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ - --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ - --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ - --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ - --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ - --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ - --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ - --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ - --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ - --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ - --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ - --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ - --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ - --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ - --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ - --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ - --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ - --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ - --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ - --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ - --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ - --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ - --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ - --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ - --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ - --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ - --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ - --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ - --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ - --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ - --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ - --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ - --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ - --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ - --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ - --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ - --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ - --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ - --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ - --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ - --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ - --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ - --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f -requests-oauthlib==2.0.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36 \ - --hash=sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9 -requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 -requests[socks]==2.31.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 -resolvelib==1.0.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309 \ - --hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf -s3transfer==0.10.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19 \ - --hash=sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d -six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 -tabulate==0.9.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ - --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f -typing-extensions==4.11.0 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ - --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a -urllib3==2.2.1 ; python_version >= "3.10" and python_version < "4.0" \ - --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ - --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 +adal==1.2.7 +ansible==9.4.0 +ansible-core==2.16.5 +applicationinsights==0.11.10 +argcomplete==1.12.3 +azure-cli-core==2.34.0 +azure-cli-telemetry==1.0.6 +azure-common==1.1.11 +azure-containerregistry==1.1.0 +azure-core==1.28.0 +azure-graphrbac==0.61.1 +azure-identity==1.7.0 +azure-keyvault==4.2.0 +azure-keyvault-certificates==4.7.0 +azure-keyvault-keys==4.8.0 +azure-keyvault-secrets==4.7.0 +azure-mgmt-apimanagement==3.0.0 +azure-mgmt-authorization==2.0.0 +azure-mgmt-automation==1.0.0 +azure-mgmt-batch==16.2.0 +azure-mgmt-cdn==11.0.0 +azure-mgmt-compute==26.1.0 +azure-mgmt-containerinstance==9.0.0 +azure-mgmt-containerregistry==9.1.0 +azure-mgmt-containerservice==20.0.0 +azure-mgmt-core==1.3.0 +azure-mgmt-cosmosdb==6.4.0 +azure-mgmt-datafactory==2.0.0 +azure-mgmt-datalake-store==1.0.0 +azure-mgmt-devtestlabs==9.0.0 +azure-mgmt-dns==8.0.0 +azure-mgmt-eventhub==10.1.0 +azure-mgmt-hdinsight==9.0.0 +azure-mgmt-iothub==2.2.0 +azure-mgmt-keyvault==10.0.0 +azure-mgmt-loganalytics==12.0.0 +azure-mgmt-managedservices==6.0.0 +azure-mgmt-managementgroups==1.0.0 +azure-mgmt-marketplaceordering==1.1.0 +azure-mgmt-monitor==3.0.0 +azure-mgmt-network==19.1.0 +azure-mgmt-notificationhubs==7.0.0 +azure-mgmt-nspkg==2.0.0 +azure-mgmt-privatedns==1.0.0 +azure-mgmt-rdbms==10.0.0 +azure-mgmt-recoveryservices==2.0.0 +azure-mgmt-recoveryservicesbackup==3.0.0 +azure-mgmt-redis==13.0.0 +azure-mgmt-resource==21.1.0 +azure-mgmt-search==8.0.0 +azure-mgmt-servicebus==7.1.0 +azure-mgmt-sql==3.0.1 +azure-mgmt-storage==19.0.0 +azure-mgmt-trafficmanager==1.0.0b1 +azure-mgmt-web==6.1.0 +azure-nspkg==2.0.0 +azure-storage-blob==12.11.0 +bcrypt==4.1.2 +boto3==1.34.78 +botocore==1.34.78 +certifi==2024.2.2 +cffi==1.16.0 +charset-normalizer==3.3.2 +cryptography==42.0.5 +humanfriendly==10.0 +idna==3.6 +isodate==0.6.1 +Jinja2==3.1.3 +jmespath==1.0.1 +knack==0.9.0 +MarkupSafe==2.1.5 +msal==1.23.0 +msal-extensions==0.3.1 +msrest==0.7.1 +msrestazure==0.6.4 +netaddr==1.2.1 +oauthlib==3.2.2 +packaging==21.3 +paramiko==2.12.0 +pkginfo==1.10.0 +portalocker==1.7.1 +psutil==5.9.8 +pycparser==2.22 +Pygments==2.17.2 +PyJWT==2.8.0 +PyNaCl==1.5.0 +pyOpenSSL==24.1.0 +pyparsing==3.1.2 +PySocks==1.7.1 +python-dateutil==2.9.0.post0 +PyYAML==6.0.1 +requests==2.31.0 +requests-oauthlib==2.0.0 +resolvelib==1.0.1 +s3transfer==0.10.1 +six==1.16.0 +tabulate==0.9.0 +typing_extensions==4.11.0 +urllib3==2.2.1 +xmltodict==0.13.0 From 2f587ccfe1fc08fa168e6e38c5a76ad16c4f5e4b Mon Sep 17 00:00:00 2001 From: acichon Date: Fri, 5 Apr 2024 19:26:20 +0200 Subject: [PATCH 08/20] workaround for hyphens --- playbooks/azure_sdwan_config.yml | 4 ++-- roles/azure_controllers/tasks/main.yml | 4 ++++ roles/azure_edges/tasks/main.yml | 4 ++++ roles/azure_network_infrastructure/tasks/main.yml | 4 ++++ roles/azure_teardown/tasks/main.yml | 4 ++++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/playbooks/azure_sdwan_config.yml b/playbooks/azure_sdwan_config.yml index 702353f..6f01f87 100644 --- a/playbooks/azure_sdwan_config.yml +++ b/playbooks/azure_sdwan_config.yml @@ -16,10 +16,10 @@ az_resources_prefix: "{{ organization_name }}" # example configuration is: -# aws_allowed_subnets: +# az_allowed_subnets: # - 15.15.0.0/16 # - 10.10.0.0/16 -aws_allowed_subnets: null +az_allowed_subnets: null ############################### diff --git a/roles/azure_controllers/tasks/main.yml b/roles/azure_controllers/tasks/main.yml index bd48d6f..1c81036 100644 --- a/roles/azure_controllers/tasks/main.yml +++ b/roles/azure_controllers/tasks/main.yml @@ -23,6 +23,10 @@ loop_var: instance_item label: "{{ instance_item.hostname }}" +- name: "Replace underscores with hyphens in the az_resources_prefix string" + ansible.builtin.set_fact: + az_resources_prefix: "{{ az_resources_prefix | replace('_', '-') }}" + - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: path: "{{ results_dir }}" diff --git a/roles/azure_edges/tasks/main.yml b/roles/azure_edges/tasks/main.yml index f5f9ed7..015c307 100644 --- a/roles/azure_edges/tasks/main.yml +++ b/roles/azure_edges/tasks/main.yml @@ -23,6 +23,10 @@ tasks_from: aws_required_variables defaults_from: az_required_vars_edges.yml +- name: "Replace underscores with hyphens in the az_resources_prefix string" + ansible.builtin.set_fact: + az_resources_prefix: "{{ az_resources_prefix | replace('_', '-') }}" + - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: path: "{{ results_dir }}" diff --git a/roles/azure_network_infrastructure/tasks/main.yml b/roles/azure_network_infrastructure/tasks/main.yml index 1672bd6..cdae880 100644 --- a/roles/azure_network_infrastructure/tasks/main.yml +++ b/roles/azure_network_infrastructure/tasks/main.yml @@ -12,6 +12,10 @@ tasks_from: required_variables defaults_from: az_required_vars_network_infrastructure.yml +- name: "Replace underscores with hyphens in the az_resources_prefix string" + ansible.builtin.set_fact: + az_resources_prefix: "{{ az_resources_prefix | replace('_', '-') }}" + - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: path: "{{ results_dir }}" diff --git a/roles/azure_teardown/tasks/main.yml b/roles/azure_teardown/tasks/main.yml index bcf20a2..96c1529 100644 --- a/roles/azure_teardown/tasks/main.yml +++ b/roles/azure_teardown/tasks/main.yml @@ -6,5 +6,9 @@ name: common tasks_from: az_user_session_probe +- name: "Replace underscores with hyphens in the az_resources_prefix string" + ansible.builtin.set_fact: + az_resources_prefix: "{{ az_resources_prefix | replace('_', '-') }}" + - name: Remove Azure Resource Group and wait for teardown completion ansible.builtin.include_tasks: az_teardown_rg.yml From 3b8238e893c4a7761fe809607ba4667b11973732 Mon Sep 17 00:00:00 2001 From: acichon Date: Fri, 5 Apr 2024 21:22:54 +0200 Subject: [PATCH 09/20] fix for required_variables --- README.md | 2 +- roles/azure_edges/tasks/azure_cedge_vm.yml | 2 +- roles/azure_edges/tasks/main.yml | 2 +- roles/template_cloudinit/tasks/main.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7567d41..e66c1cd 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Before you begin, ensure you have met the following requirements: In `requirements.yml` inside your project add: ```yml -- name: git@sdwan-git.cisco.com:sdwan-tools/cisco.sdwan_deployment.git +- name: git@github.com:cisco-open/ansible-collection-sdwan-deployment.git type: git version: main ``` diff --git a/roles/azure_edges/tasks/azure_cedge_vm.yml b/roles/azure_edges/tasks/azure_cedge_vm.yml index 6a278ad..1e078d6 100644 --- a/roles/azure_edges/tasks/azure_cedge_vm.yml +++ b/roles/azure_edges/tasks/azure_cedge_vm.yml @@ -92,7 +92,7 @@ cedge_transport_public_ip: "{{ az_transport_public_ip.ip_address }}" - name: "Set vpn0_default_gateway fact from VPN 0 subnet value" - sansible.builtin.et_fact: + ansible.builtin.set_fact: vpn0_default_gateway: "{{ subnet.cidr | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}" loop: "{{ az_subnets }}" loop_control: diff --git a/roles/azure_edges/tasks/main.yml b/roles/azure_edges/tasks/main.yml index 015c307..80e2201 100644 --- a/roles/azure_edges/tasks/main.yml +++ b/roles/azure_edges/tasks/main.yml @@ -20,7 +20,7 @@ - name: Assert all required variables for Azure cEdges deployment ansible.builtin.include_role: name: common - tasks_from: aws_required_variables + tasks_from: required_variables defaults_from: az_required_vars_edges.yml - name: "Replace underscores with hyphens in the az_resources_prefix string" diff --git a/roles/template_cloudinit/tasks/main.yml b/roles/template_cloudinit/tasks/main.yml index 809897f..7a62777 100644 --- a/roles/template_cloudinit/tasks/main.yml +++ b/roles/template_cloudinit/tasks/main.yml @@ -13,7 +13,7 @@ - name: Assert all required variables for AWS cloudinit generation ansible.builtin.include_role: name: common - tasks_from: aws_required_variables + tasks_from: required_variables defaults_from: required_vars_controllers.yml - name: "Prepare directory for results, path: {{ results_dir }}" From 5bdfa3fec7538d39de435be95e885775b2331f34 Mon Sep 17 00:00:00 2001 From: acichon Date: Mon, 8 Apr 2024 16:25:40 +0200 Subject: [PATCH 10/20] role for cloud-init generation --- .ansible-lint | 2 + playbooks/aws_sdwan_config_20_12.yml | 3 +- playbooks/template_cloudinit.yml | 11 + playbooks/template_cloudinit_config.yml | 65 +++++ .../templates/userdata_vbond.j2 | 40 +-- .../templates/userdata_vmanage.j2 | 36 +-- .../templates/userdata_vsmart.j2 | 38 +-- .../templates/userdata_vbond.j2 | 2 +- .../defaults/required_vars_cloudinit.yml | 9 + roles/template_cloudinit/defaults/main.yml | 3 - .../tasks/aws_vbond_cloudinit.yml | 17 -- .../tasks/aws_vmanage_cloudinit.yml | 16 -- .../tasks/aws_vsmart_cloudinit.yml | 180 -------------- roles/template_cloudinit/tasks/main.yml | 67 ++++- .../tasks/template_cloudinit.yml | 14 ++ .../templates/bootstrap_cedge.j2 | 231 ++++++++++++++++++ .../templates/userdata_vbond.j2 | 50 ++-- .../templates/userdata_vmanage.j2 | 46 ++-- .../templates/userdata_vsmart.j2 | 48 ++-- 19 files changed, 533 insertions(+), 345 deletions(-) create mode 100644 playbooks/template_cloudinit.yml create mode 100644 playbooks/template_cloudinit_config.yml create mode 100644 roles/common/defaults/required_vars_cloudinit.yml delete mode 100644 roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml delete mode 100644 roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml delete mode 100644 roles/template_cloudinit/tasks/aws_vsmart_cloudinit.yml create mode 100644 roles/template_cloudinit/tasks/template_cloudinit.yml create mode 100644 roles/template_cloudinit/templates/bootstrap_cedge.j2 diff --git a/.ansible-lint b/.ansible-lint index b9fafdd..340b103 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -15,6 +15,8 @@ exclude_paths: - playbooks/results/ - playbooks/aws_sdwan_config* - playbooks/azure_sdwan_config* + - playbooks/template_cloudinit.yml + - playbooks/template_cloudinit_config.yml - playbooks/specific_edges_to_teardown.yml - roles/aws_teardown/tasks/main.yml # parseable: true diff --git a/playbooks/aws_sdwan_config_20_12.yml b/playbooks/aws_sdwan_config_20_12.yml index 5bc9971..9c1d527 100644 --- a/playbooks/aws_sdwan_config_20_12.yml +++ b/playbooks/aws_sdwan_config_20_12.yml @@ -67,7 +67,8 @@ aws_key_name: null admin_username: admin admin_password: Cisco#123@Viptela vbond_port: 12346 -# vpn0_interface_color: default +# vbond_transport_private_ip: null # note that default: 192.168.1.199 +# vbond_transport_public_ip: null # note that default: 192.168.1.199 diff --git a/playbooks/template_cloudinit.yml b/playbooks/template_cloudinit.yml new file mode 100644 index 0000000..d4b105a --- /dev/null +++ b/playbooks/template_cloudinit.yml @@ -0,0 +1,11 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- +- name: Template cloud-init configuration for Cisco SD-WAN for AWS or Azure + hosts: localhost + gather_facts: false + vars_files: + ./template_cloudinit_config.yml + roles: + - template_cloudinit diff --git a/playbooks/template_cloudinit_config.yml b/playbooks/template_cloudinit_config.yml new file mode 100644 index 0000000..a92e5ba --- /dev/null +++ b/playbooks/template_cloudinit_config.yml @@ -0,0 +1,65 @@ +--- + +####################################### +# Required configuration data # +####################################### + +organization_name: null +resources_prefix: "{{ organization_name }}" + +cloud_provider: null # can be either aws or azure + +# Cloud-init general configurations +admin_username: admin +admin_password: Cisco#123@Viptela +vbond_port: 12346 +# vbond_transport_private_ip: null # note that default: 192.168.1.199 +# vbond_transport_public_ip: null # note that default: 192.168.1.199 + + +############################### +# Controllers # +############################### + +# vManage +site_id_vmanage: 100 + +vmanage_instances: + - hostname: "{{ resources_prefix }}-vManage" + system_ip: 192.168.1.1 + site_id: "{{ site_id_vmanage }}" + vpn0_default_gateway: # has to be set if cloud_provider == "azure" + +# vBond +site_id_vbond: 200 + +vbond_instances: + - hostname: "{{ resources_prefix }}-vBond" + system_ip: 192.168.3.1 + site_id: "{{ site_id_vbond }}" + vpn0_default_gateway: # has to be set if cloud_provider == "azure" + + +# vSmart +site_id_vsmart: 300 + +vsmart_instances: + - hostname: "{{ resources_prefix }}-vSmart" + system_ip: 192.168.2.1 + site_id: "{{ site_id_vsmart }}" + vpn0_default_gateway: # has to be set if cloud_provider == "azure" + + + +################################ +# Edge devices # +################################ + +cedge_instances: [] + + +########################################## +# Reusable deployment facts # +########################################## + +results_dir: "{{ playbook_dir }}/results" diff --git a/roles/aws_controllers/templates/userdata_vbond.j2 b/roles/aws_controllers/templates/userdata_vbond.j2 index 4aa6b7e..49a320e 100644 --- a/roles/aws_controllers/templates/userdata_vbond.j2 +++ b/roles/aws_controllers/templates/userdata_vbond.j2 @@ -32,7 +32,7 @@ write_files: {{ organization_name }} {{ site_id }} - {{ vbond_transport_private_ip }} + {{ vbond_transport_private_ip | default(default_vbond_ip) }} @@ -46,25 +46,25 @@ write_files: 0 - - ge0/0 - - true - - - - ipsec - - - default - - - true - true - - - false - + + ge0/0 + + true + + + + ipsec + + + default + + + true + true + + + false + 512 diff --git a/roles/aws_controllers/templates/userdata_vmanage.j2 b/roles/aws_controllers/templates/userdata_vmanage.j2 index a9b99f9..e6d9a98 100644 --- a/roles/aws_controllers/templates/userdata_vmanage.j2 +++ b/roles/aws_controllers/templates/userdata_vmanage.j2 @@ -66,24 +66,24 @@ write_files: 0 - - eth1 - - true - - - - true - true - true - true - true - true - true - - - false - + + eth1 + + true + + + + true + true + true + true + true + true + true + + + false + 512 diff --git a/roles/aws_controllers/templates/userdata_vsmart.j2 b/roles/aws_controllers/templates/userdata_vsmart.j2 index c5f8e7d..f479626 100644 --- a/roles/aws_controllers/templates/userdata_vsmart.j2 +++ b/roles/aws_controllers/templates/userdata_vsmart.j2 @@ -44,25 +44,25 @@ write_files: 0 - - eth1 - - true - - - - ipsec - - - default - - - true - true - - - false - + + eth1 + + true + + + + ipsec + + + default + + + true + true + + + false + 512 diff --git a/roles/azure_controllers/templates/userdata_vbond.j2 b/roles/azure_controllers/templates/userdata_vbond.j2 index d8744e7..2e27712 100644 --- a/roles/azure_controllers/templates/userdata_vbond.j2 +++ b/roles/azure_controllers/templates/userdata_vbond.j2 @@ -32,7 +32,7 @@ write_files: {{ organization_name }} {{ site_id }} - {{ vbond_transport_private_ip }} + {{ vbond_transport_private_ip | default(default_vbond_ip) }} diff --git a/roles/common/defaults/required_vars_cloudinit.yml b/roles/common/defaults/required_vars_cloudinit.yml new file mode 100644 index 0000000..0db4adc --- /dev/null +++ b/roles/common/defaults/required_vars_cloudinit.yml @@ -0,0 +1,9 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +required_variables: + organization_name: "{{ organization_name }}" + admin_username: "{{ admin_username }}" + admin_password: "{{ admin_password }}" diff --git a/roles/template_cloudinit/defaults/main.yml b/roles/template_cloudinit/defaults/main.yml index 842c689..36ecd99 100644 --- a/roles/template_cloudinit/defaults/main.yml +++ b/roles/template_cloudinit/defaults/main.yml @@ -31,18 +31,15 @@ default_vbond_ip: 192.168.1.199 # default ips from official Cisco guides # vManage site_id_vmanage: 100 - vmanage_instances: [] # vBond site_id_vbond: 200 - vbond_instances: [] # vSmart site_id_vsmart: 300 - vsmart_instances: [] # cedge C8000K diff --git a/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml b/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml deleted file mode 100644 index 6e90831..0000000 --- a/roles/template_cloudinit/tasks/aws_vbond_cloudinit.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -# template cloud init with proper ip assigned to EiP -# cloud-init -- name: Set path for bootstrap configuration - ansible.builtin.set_fact: - generated_userdata_vbond: "{{ userdata_vbond_path }}-{{ hostname }}" - changed_when: true - -- name: Template userdata file for vBond - ansible.builtin.template: - src: ./userdata_vbond.j2 - dest: "{{ generated_userdata_vbond }}" - mode: "0644" diff --git a/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml b/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml deleted file mode 100644 index 45707a0..0000000 --- a/roles/template_cloudinit/tasks/aws_vmanage_cloudinit.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -# cloud-init -- name: Set path for bootstrap configuration - ansible.builtin.set_fact: - generated_userdata_vmanage: "{{ userdata_vmanage_path }}-{{ hostname }}" - changed_when: true - -- name: Template userdata file for vManage - ansible.builtin.template: - src: ./userdata_vmanage.j2 - dest: "{{ generated_userdata_vmanage }}" - mode: "0644" diff --git a/roles/template_cloudinit/tasks/aws_vsmart_cloudinit.yml b/roles/template_cloudinit/tasks/aws_vsmart_cloudinit.yml deleted file mode 100644 index db57d84..0000000 --- a/roles/template_cloudinit/tasks/aws_vsmart_cloudinit.yml +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright 2024 Cisco Systems, Inc. and its affiliates -# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) - ---- - -# For vsmart -# -# 2 aws_network_interface -# 2 aws_network_interface_attachment -# 2 aws_eip -# 1 ec2 instance - - -# NICs -- name: Filter required subnets for instance creation. Set aws_mgmt_subnet and aws_transport_subnet facts - ansible.builtin.set_fact: - aws_mgmt_subnet: "{{ aws_subnets_config | selectattr('tags.VPN', 'equalto', '512') | list | first }}" - aws_transport_subnet: "{{ aws_subnets_config | selectattr('tags.VPN', 'equalto', '0') | list | first }}" - -# There are already few deployments that failed because of -# 'error: code: InvalidNetworkInterfaceID.NotFound' -# For that we add retry to proceed, can be debugged later -- name: Create network interfaces for vsmart - amazon.aws.ec2_eni: - subnet_id: "{{ subnet_item.id }}" - description: Network interface for SD-WAN Controller - security_groups: "{{ aws_security_group_config.group_id }}" - region: "{{ aws_region }}" - tags: - Name: "nic-{{ subnet_item.tags.Name }}" - Creator: "{{ aws_tag_creator }}" - Machine: "{{ hostname }}" - VPN: "{{ subnet_item.tags.VPN }}" - register: network_interfaces_vsmart - loop: "{{ [aws_mgmt_subnet, aws_transport_subnet] }}" - loop_control: - loop_var: subnet_item - label: "nic-{{ subnet_item.tags.Name }}" - # retries: 3 - # delay: 3 - # until: network_interfaces_vsmart.results | map(attribute='rc') | all(is_same=True, test_value=0) - -- name: Set aws_network_interfaces fact with a list of interfaces for vSmart - ansible.builtin.set_fact: - aws_network_interfaces: "{{ network_interfaces_vsmart.results | map(attribute='interface') | list }}" - -- name: Filter aws_network_interfaces for instance creation. Set aws_mgmt_nic and aws_transport_nic facts - ansible.builtin.set_fact: - aws_mgmt_nic: "{{ aws_network_interfaces | selectattr('tags.VPN', 'equalto', '512') | list | first }}" - aws_transport_nic: "{{ aws_network_interfaces | selectattr('tags.VPN', 'equalto', '0') | list | first }}" - - -# EIPs -- name: Associate EIP with mgmt network interface - amazon.aws.ec2_eip: - device_id: "{{ interface_item.id }}" - region: "{{ aws_region }}" - in_vpc: true - state: present - tags: - Name: "eip-for-{{ interface_item.tags.Name }}" - Creator: "{{ aws_tag_creator }}" - Machine: "{{ hostname }}" - VPN: "{{ interface_item.tags.VPN }}" - loop: "{{ [aws_mgmt_nic, aws_transport_nic] }}" # We do loop starting with mgmt nic, so we know results[0] is mgmt ip - loop_control: - loop_var: interface_item - label: "eip-for-{{ interface_item.tags.Name }}" - register: eip_vsmart - retries: 3 - delay: 3 - until: eip_vsmart is succeeded - - -# cloud-init -- name: Set path for bootstrap configuration - ansible.builtin.set_fact: - generated_userdata_vsmart: "{{ userdata_vsmart_path }}-{{ hostname }}" - changed_when: true - -- name: Template userdata file for vSmart - ansible.builtin.template: - src: ./userdata_vsmart.j2 - dest: "{{ generated_userdata_vsmart }}" - mode: "0644" - - -# vManage -- name: Launch vsmart - amazon.aws.ec2_instance: - count: 1 - instance_type: "{{ aws_vsmart_instance_type }}" - image: - id: "{{ aws_vsmart_ami_id }}" - state: present - vpc_subnet_id: "{{ aws_mgmt_subnet.id }}" - region: "{{ aws_region }}" - key_name: "{{ aws_key_name | default('') | bool | ternary(aws_key_name, omit) }}" - network: - assign_public_ip: false - interfaces: - - id: "{{ aws_mgmt_nic.id }}" - device_index: 0 - description: "{{ aws_mgmt_nic.tags.Name }}" - - id: "{{ aws_transport_nic.id }}" - device_index: 1 - description: "{{ aws_transport_nic.tags.Name }}" - name: "{{ hostname }}" - tags: - Name: "{{ hostname }}" - Creator: "{{ aws_tag_creator }}" - user_data: "{{ lookup('file', generated_userdata_vsmart) }}" - volumes: - - device_name: /dev/xvda - ebs: - volume_size: 23 - delete_on_termination: true - register: ec2_vsmart - -# TODO: -# Note that the variable: ec2_vsmart.instances[0].network_interfaces is returning a list of interfaces -# but that list can be different than device_index (so mgmt and transport are mixed) - -- name: Store vSmart instance details for deployment_results - ansible.builtin.set_fact: - instance: - hostname: "{{ hostname }}" - system_ip: "{{ system_ip }}" - admin_username: "{{ admin_username }}" - admin_password: "{{ admin_password }}" - mgmt_public_ip: "{{ eip_vsmart.results[0].public_ip }}" - transport_public_ip: "{{ eip_vsmart.results[1].public_ip }}" - changed_when: true - notify: Show deployment_facts - register: _vsmart_facts - retries: 3 - delay: 3 - until: _vsmart_facts is succeeded - - -- name: Update deployment facts - vSmart - that will be consumed by vManage-client in Ansible - ansible.builtin.set_fact: - deployment_facts: - vsmart_instances: "{{ deployment_facts.vsmart_instances + [instance] }}" - vmanage_instances: "{{ deployment_facts.vmanage_instances }}" - vbond_instances: "{{ deployment_facts.vbond_instances }}" - - -- name: Copy ec2 vSmart resources information to log file - ansible.builtin.blockinfile: - create: true - state: present - mode: "0644" - insertafter: EOF - dest: "{{ aws_deployed_controllers_data }}" - marker: "\n-------------- ec2 vsmart --------------\n" - content: "{{ ec2_vsmart | to_nice_yaml }}" - - -- name: Allow traffic outside VPC for vSmart IP addresses - amazon.aws.ec2_security_group: - name: "{{ aws_security_group_config.group_name }}" - description: "Security Group for SD-WAN instances" - vpc_id: "{{ aws_vpc_config.id }}" - region: "{{ aws_region }}" - purge_rules: false - purge_tags: false - purge_rules_egress: false - rules: - - proto: all - cidr_ip: "{{ eip_vsmart.results[0].public_ip }}/32" - rule_desc: "{{ hostname }} - mgmt (VPN 512)" - - proto: all - cidr_ip: "{{ eip_vsmart.results[1].public_ip }}/32" - rule_desc: "{{ hostname }} - transport (VPN 0)" - rules_egress: [] - register: allow_traffic - retries: 3 - delay: 3 - until: allow_traffic is succeeded diff --git a/roles/template_cloudinit/tasks/main.yml b/roles/template_cloudinit/tasks/main.yml index 7a62777..115e6fa 100644 --- a/roles/template_cloudinit/tasks/main.yml +++ b/roles/template_cloudinit/tasks/main.yml @@ -2,19 +2,37 @@ # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) --- +- name: "Prompt for cloud_provider variable" + ansible.builtin.pause: + prompt: "Which cloud provider are you using (aws/azure)?" + register: provider_input + when: cloud_provider is not defined or cloud_provider is none + vars: + pause_action: "{{ 'pause' if cloud_provider is not defined else 'debug' }}" + +- name: "Set cloud_provider variable from user input if not defined in config file" + ansible.builtin.set_fact: + cloud_provider: "{{ provider_input.user_input }}" + when: provider_input.user_input is defined and provider_input.user_input in ['aws', 'azure'] -# Example topology deployed according to: -# -# https://www.cisco.com/c/en/us/td/docs/routers/sdwan/configuration/sdwan-xe-gs-book/controller-aws.html -# -# More extensive topologies and cluster support TODO +- name: "Validate cloud_provider input" + ansible.builtin.fail: + msg: "Invalid input '{{ provider_input.user_input }}'. You must enter 'aws' or 'azure'." + when: + - provider_input.user_input is defined + - provider_input.user_input not in ['aws', 'azure'] +- name: "Validate cloud_provider variable if set from configuration file" + ansible.builtin.fail: + msg: "Invalid value '{{ cloud_provider }}'. You must use 'aws' or 'azure'." + when: + - cloud_provider not in ['aws', 'azure'] -- name: Assert all required variables for AWS cloudinit generation +- name: "Assert all required variables for AWS cloudinit generation" ansible.builtin.include_role: name: common tasks_from: required_variables - defaults_from: required_vars_controllers.yml + defaults_from: required_vars_cloudinit.yml - name: "Prepare directory for results, path: {{ results_dir }}" ansible.builtin.file: @@ -27,35 +45,58 @@ # vbond_mgmt_private_ip & ec2_vbond_mgmt_public_ip # That are the reasons why vBond has to go up first (if we will use static IPs it can be changed) -- name: Generate cloudinit template for vBond - ansible.builtin.include_tasks: aws_vbond_cloudinit.yml +- name: "Generate cloudinit template for vBond instances" + ansible.builtin.include_tasks: template_cloudinit.yml vars: hostname: "{{ instance_item.hostname }}" system_ip: "{{ instance_item.system_ip }}" site_id: "{{ instance_item.site_id }}" + vpn0_default_gateway: "{{ instance_item.vpn0_default_gateway }}" + template_path: "./userdata_vbond.j2" + generated_cloudinit_path: "{{ cloudinit_path | default('') }}" loop: "{{ vbond_instances }}" loop_control: loop_var: instance_item when: vbond_instances is defined -- name: Generate cloudinit template for vManage - ansible.builtin.include_tasks: aws_vmanage_cloudinit.yml +- name: "Generate cloudinit template for vManage instances" + ansible.builtin.include_tasks: template_cloudinit.yml vars: hostname: "{{ instance_item.hostname }}" system_ip: "{{ instance_item.system_ip }}" site_id: "{{ instance_item.site_id }}" + vpn0_default_gateway: "{{ instance_item.vpn0_default_gateway }}" + template_path: "./userdata_vmanage.j2" + generated_cloudinit_path: "{{ cloudinit_path | default('') }}" loop: "{{ vmanage_instances }}" loop_control: loop_var: instance_item when: vmanage_instances is defined -- name: Generate cloudinit template for vSmart - ansible.builtin.include_tasks: aws_vsmart_cloudinit.yml +- name: "Generate cloudinit template for vSmart instances" + ansible.builtin.include_tasks: template_cloudinit.yml vars: hostname: "{{ instance_item.hostname }}" system_ip: "{{ instance_item.system_ip }}" site_id: "{{ instance_item.site_id }}" + vpn0_default_gateway: "{{ instance_item.vpn0_default_gateway }}" + template_path: "./userdata_vsmart.j2" + generated_cloudinit_path: "{{ cloudinit_path | default('') }}" + loop: "{{ vsmart_instances }}" loop_control: loop_var: instance_item when: vsmart_instances is defined + +- name: "Generate cloudinit template for cEdge instances" + ansible.builtin.include_tasks: template_cloudinit.yml + vars: + hostname: "{{ instance_item.hostname }}" + system_ip: "{{ instance_item.system_ip }}" + site_id: "{{ instance_item.site_id }}" + template_path: "./userdata_cedge.j2" + generated_cloudinit_path: "{{ cloudinit_path | default('') }}" + loop: "{{ cedge_instances }}" + loop_control: + loop_var: instance_item + when: cedge_instances is defined diff --git a/roles/template_cloudinit/tasks/template_cloudinit.yml b/roles/template_cloudinit/tasks/template_cloudinit.yml new file mode 100644 index 0000000..8442008 --- /dev/null +++ b/roles/template_cloudinit/tasks/template_cloudinit.yml @@ -0,0 +1,14 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- +- name: "Set path for bootstrap configuration if not defined" + ansible.builtin.set_fact: + default_path: "{{ results_dir }}/{{ hostname }}" + when: generated_cloudinit_path | length == 0 + +- name: "Template cloud-init configuration file for: {{ hostname }}" + ansible.builtin.template: + src: "{{ template_path }}" + dest: "{{ generated_cloudinit_path if generated_cloudinit_path != '' else default_path }}" + mode: "0644" diff --git a/roles/template_cloudinit/templates/bootstrap_cedge.j2 b/roles/template_cloudinit/templates/bootstrap_cedge.j2 new file mode 100644 index 0000000..40802e6 --- /dev/null +++ b/roles/template_cloudinit/templates/bootstrap_cedge.j2 @@ -0,0 +1,231 @@ +Content-Type: multipart/mixed; boundary="===============0630588950316195806==" +MIME-Version: 1.0 + +--===============0630588950316195806== +Content-Type: text/cloud-config; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="tmpo3jv4ny6" + +#cloud-config +vinitparam: + - uuid : {{ uuid }} + - otp : {{ otp }} + - org : {{ organization_name }} + - vbond: {{ vbond }} + + +--===============0630588950316195806== +Content-Type: text/cloud-boothook; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="config-{{ uuid }}.txt" + +#cloud-boothook + system + ztp-status success + pseudo-confirm-commit 300 + personality vedge + device-model vedge-C8000V + chassis-number {{ uuid }} + system-ip {{ system_ip }} + overlay-id 1 + site-id {{ site_id }} + no transport-gateway enable + port-offset 1 + control-session-pps 300 + admin-tech-on-failure + sp-organization-name "{{ organization_name }}" + organization-name "{{ organization_name }}" + port-hop + track-transport + track-default-gateway + console-baud-rate 19200 + config-template-name Default_Azure_vWAN_C8000V_Template_V01 + no on-demand enable + on-demand idle-timeout 10 + vbond {{ vbond }} port {{ vbond_port }} + ! + bfd color lte + hello-interval 1000 + no pmtu-discovery + multiplier 1 + ! + bfd default-dscp 48 + bfd app-route multiplier 2 + bfd app-route poll-interval 123400 + security + ipsec + rekey 86400 + replay-window 512 + authentication-type ah-sha1-hmac sha1-hmac + integrity-type ip-udp-esp esp + ! + ! + sslproxy + no enable + rsa-key-modulus 2048 + certificate-lifetime 730 + eckey-type P256 + ca-tp-label PROXY-SIGNING-CA + settings expired-certificate drop + settings untrusted-certificate drop + settings unknown-status drop + settings certificate-revocation-check none + settings unsupported-protocol-versions drop + settings unsupported-cipher-suites drop + settings failure-mode close + settings minimum-tls-ver TLSv1 + dual-side optimization enable + ! + sdwan + interface GigabitEthernet1 + tunnel-interface + encapsulation ipsec weight 1 + no border + color default + no last-resort-circuit + no low-bandwidth-link + no vbond-as-stun-server + vmanage-connection-preference 5 + port-hop + carrier default + nat-refresh-interval 5 + hello-interval 1000 + hello-tolerance 12 + no allow-service all + no allow-service bgp + allow-service dhcp + allow-service dns + allow-service icmp + allow-service sshd + no allow-service netconf + no allow-service ntp + no allow-service ospf + no allow-service stun + allow-service https + no allow-service snmp + no allow-service bfd + exit + exit + interface GigabitEthernet2 + exit + appqoe + no tcpopt enable + no dreopt enable + no httpopt enable + ! + omp + no shutdown + send-path-limit 4 + ecmp-limit 4 + graceful-restart + no as-dot-notation + timers + holdtime 15 + advertisement-interval 1 + graceful-restart-timer 120 + eor-timer 300 + exit + address-family ipv4 + advertise connected + advertise static + ! + address-family ipv6 + advertise connected + advertise static + ! + ! + ! + service tcp-keepalives-in + service tcp-keepalives-out + no service tcp-small-servers + no service udp-small-servers + hostname {{ hostname }} + username admin privilege 15 secret 0 {{ admin_password }} + vrf definition Mgmt-intf + rd 1:512 + address-family ipv4 + route-target export 1:512 + route-target import 1:512 + exit-address-family + ! + address-family ipv6 + exit-address-family + ! + ! + ip arp proxy disable + no ip finger + no ip rcmd rcp-enable + no ip rcmd rsh-enable + no ip dhcp use class + no ip ftp passive + ip bootp server + no ip source-route + no ip ssh bulk-mode + no ip http server + no ip http secure-server + no ip http ctc authentication + ip nat settings central-policy + interface GigabitEthernet1 + no shutdown + arp timeout 1200 + ip address dhcp client-id GigabitEthernet1 + no ip redirects + ip dhcp client default-router distance 1 + ip mtu 1500 + load-interval 30 + mtu 1500 + negotiation auto + exit + interface GigabitEthernet2 + no shutdown + arp timeout 1200 + ip address dhcp client-id GigabitEthernet2 + no ip redirects + ip dhcp client default-router distance 1 + ip mtu 1500 + load-interval 30 + mtu 1500 + negotiation auto + exit + interface Tunnel1 + no shutdown + ip unnumbered GigabitEthernet1 + no ip redirects + ipv6 unnumbered GigabitEthernet1 + no ipv6 redirects + tunnel source GigabitEthernet1 + tunnel mode sdwan + exit + clock timezone UTC 0 0 + logging persistent size 104857600 filesize 10485760 + no logging monitor + logging buffered 512000 + logging console + aaa authentication login default local + aaa authorization exec default local + aaa server radius dynamic-author + ! + no crypto ikev2 diagnose error + no crypto isakmp diagnose error + no network-clock revertive + snmp-server ifindex persist + fhrp version vrrp v2 + line con 0 + speed 19200 + stopbits 1 + ! + line vty 0 4 + transport input ssh + ! + line vty 5 80 + transport input ssh + ! + lldp run + nat64 translation timeout tcp 3600 + nat64 translation timeout udp 300 + ! +! + +--===============0630588950316195806==-- diff --git a/roles/template_cloudinit/templates/userdata_vbond.j2 b/roles/template_cloudinit/templates/userdata_vbond.j2 index 4aa6b7e..4a884ac 100644 --- a/roles/template_cloudinit/templates/userdata_vbond.j2 +++ b/roles/template_cloudinit/templates/userdata_vbond.j2 @@ -32,7 +32,7 @@ write_files: {{ organization_name }} {{ site_id }} - {{ vbond_transport_private_ip }} + {{ vbond_transport_private_ip | default(default_vbond_ip) }} @@ -46,25 +46,35 @@ write_files: 0 - - ge0/0 - - true - - - - ipsec - - - default - - - true - true - - - false - + + ge0/0 + + true + + + + ipsec + + + default + + + true + true + + + false + +{% if cloud_provider == 'azure' %} + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+{% endif %}
512 diff --git a/roles/template_cloudinit/templates/userdata_vmanage.j2 b/roles/template_cloudinit/templates/userdata_vmanage.j2 index 06b800b..43376e1 100644 --- a/roles/template_cloudinit/templates/userdata_vmanage.j2 +++ b/roles/template_cloudinit/templates/userdata_vmanage.j2 @@ -71,24 +71,34 @@ write_files: 0 - - eth1 - - true - - - - true - true - true - true - true - true - true - - - false - + + eth1 + + true + + + + true + true + true + true + true + true + true + + + false + +{% if cloud_provider == 'azure' %} + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+{% endif %}
512 diff --git a/roles/template_cloudinit/templates/userdata_vsmart.j2 b/roles/template_cloudinit/templates/userdata_vsmart.j2 index c5f8e7d..e58aeb5 100644 --- a/roles/template_cloudinit/templates/userdata_vsmart.j2 +++ b/roles/template_cloudinit/templates/userdata_vsmart.j2 @@ -44,25 +44,35 @@ write_files: 0 - - eth1 - - true - - - - ipsec - - - default - - - true - true - - - false - + + eth1 + + true + + + + ipsec + + + default + + + true + true + + + false + +{% if cloud_provider == 'azure' %} + + + 0.0.0.0/0 + +
{{ vpn0_default_gateway }}
+
+
+
+{% endif %}
512 From 2dc9cf56afa74868f292b3188c318edb95dd87b8 Mon Sep 17 00:00:00 2001 From: acichon Date: Mon, 8 Apr 2024 16:37:16 +0200 Subject: [PATCH 11/20] fs setup for cloudinit --- .../templates/userdata_vmanage.j2 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/roles/template_cloudinit/templates/userdata_vmanage.j2 b/roles/template_cloudinit/templates/userdata_vmanage.j2 index 43376e1..fa2eaab 100644 --- a/roles/template_cloudinit/templates/userdata_vmanage.j2 +++ b/roles/template_cloudinit/templates/userdata_vmanage.j2 @@ -16,18 +16,33 @@ chpasswd: - root:root - {{ admin_username }}:{{ admin_password }} disk_setup: +{% if cloud_provider == 'aws' %} /dev/nvme1n1: +{% endif %} +{% if cloud_provider == 'azure' %} + /dev/disk/azure/scsi1/lun10 +{% endif %} table_type: mbr layout: false overwrite: false fs_setup: +{% if cloud_provider == 'aws' %} - device: /dev/nvme1n1 +{% endif %} +{% if cloud_provider == 'azure' %} +- device: /dev/disk/azure/scsi1/lun10 +{% endif %} label: data partition: none filesystem: ext4 overwrite: false mounts: +{% if cloud_provider == 'aws' %} - [ /dev/nvme1n1, /opt/data ] +{% endif %} +{% if cloud_provider == 'azure' %} +- [ /dev/disk/azure/scsi1/lun10, /opt/data ] +{% endif %} write_files: - path: /opt/web-app/etc/persona From b482f5d836e18c981981253e21943a57c1778747 Mon Sep 17 00:00:00 2001 From: acichon Date: Tue, 9 Apr 2024 13:41:16 +0200 Subject: [PATCH 12/20] idempotence for NSG --- playbooks/azure_sdwan_config.yml | 28 ++----------------- .../tasks/azure_vbond_vm.yml | 3 +- .../tasks/azure_vmanage_vm.yml | 3 +- .../tasks/azure_vsmart_vm.yml | 3 +- roles/azure_edges/tasks/azure_cedge_vm.yml | 3 +- 5 files changed, 11 insertions(+), 29 deletions(-) diff --git a/playbooks/azure_sdwan_config.yml b/playbooks/azure_sdwan_config.yml index 6f01f87..9026c10 100644 --- a/playbooks/azure_sdwan_config.yml +++ b/playbooks/azure_sdwan_config.yml @@ -11,7 +11,7 @@ organization_name: null # General Azure configuration # ####################################### -az_location: null +az_location: eastus # e.g. eastus az_resources_prefix: "{{ organization_name }}" @@ -69,9 +69,8 @@ az_cedge_vm_size: "Standard_D2_v2" az_cedge_image_offer: "cisco-c8000v-byol" az_cedge_image_publisher: "cisco" -az_cedge_image_sku: "17_13_01a-byol" -az_cedge_image_version: "17.13.0120231222" - +az_cedge_image_sku: "17_09_05a-byol" +az_cedge_image_version: "17.09.0520240304" # edge_instances: [] @@ -79,27 +78,6 @@ az_cedge_image_version: "17.13.0120231222" # based on the PnP Portal information. # See `deployment_edges_config` to inspect result - -edge_instances: -- hostname: acich-az-cedge-1 - otp: cc29db740f344f4b9968982d47d35768 - site_id: '1001' - system_ip: 192.168.101.1 - uuid: C8K-43B1056C-147C-35EF-154F-EACACA81D8DC - vbond: 137.135.122.118 -- hostname: acich-az-cedge-2 - otp: 511946c2f8374ea493a6733e75231be7 - site_id: '1002' - system_ip: 192.168.102.1 - uuid: C8K-7EFB9954-74EA-8985-80B4-39AA14D12573 - vbond: 137.135.122.118 -- hostname: acich-az-cedge-3 - otp: 3540b073b37d40458b90af6b587ca370 - site_id: '1003' - system_ip: 192.168.103.1 - uuid: C8K-A6139414-8C6C-BB10-BD15-17BBB772E569 - vbond: 137.135.122.118 - ########################################## # Reusable deployment facts # ########################################## diff --git a/roles/azure_controllers/tasks/azure_vbond_vm.yml b/roles/azure_controllers/tasks/azure_vbond_vm.yml index 9eaeb8b..fda980e 100644 --- a/roles/azure_controllers/tasks/azure_vbond_vm.yml +++ b/roles/azure_controllers/tasks/azure_vbond_vm.yml @@ -19,7 +19,7 @@ loop_var: subnet_item register: public_ip_addresses -- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" +- name: "Get info about NSG: {{ az_network_security_group }}" azure.azcollection.azure_rm_securitygroup_info: resource_group: "{{ az_resource_group }}" name: "{{ az_network_security_group }}" @@ -47,6 +47,7 @@ loop_var: public_ip_state index_var: my_idx label: public_ip_state.state.name + when: public_ip_state.state.name not in az_res_gr.securitygroups | map(attribute='rules') | flatten | map(attribute='name') | list - name: "Create virtual network interface cards" azure.azcollection.azure_rm_networkinterface: diff --git a/roles/azure_controllers/tasks/azure_vmanage_vm.yml b/roles/azure_controllers/tasks/azure_vmanage_vm.yml index 33bc182..46be798 100644 --- a/roles/azure_controllers/tasks/azure_vmanage_vm.yml +++ b/roles/azure_controllers/tasks/azure_vmanage_vm.yml @@ -19,7 +19,7 @@ loop_var: subnet_item register: public_ip_addresses -- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" +- name: "Get info about NSG: {{ az_network_security_group }}" azure.azcollection.azure_rm_securitygroup_info: resource_group: "{{ az_resource_group }}" name: "{{ az_network_security_group }}" @@ -47,6 +47,7 @@ loop_var: public_ip_state index_var: my_idx label: public_ip_state.state.name + when: public_ip_state.state.name not in az_res_gr.securitygroups | map(attribute='rules') | flatten | map(attribute='name') | list - name: "Create virtual network interface cards" azure.azcollection.azure_rm_networkinterface: diff --git a/roles/azure_controllers/tasks/azure_vsmart_vm.yml b/roles/azure_controllers/tasks/azure_vsmart_vm.yml index 7c31d7a..5d8ff63 100644 --- a/roles/azure_controllers/tasks/azure_vsmart_vm.yml +++ b/roles/azure_controllers/tasks/azure_vsmart_vm.yml @@ -19,7 +19,7 @@ loop_var: subnet_item register: public_ip_addresses -- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" +- name: "Get info about NSG: {{ az_network_security_group }}" azure.azcollection.azure_rm_securitygroup_info: resource_group: "{{ az_resource_group }}" name: "{{ az_network_security_group }}" @@ -47,6 +47,7 @@ loop_var: public_ip_state index_var: my_idx label: public_ip_state.state.name + when: public_ip_state.state.name not in az_res_gr.securitygroups | map(attribute='rules') | flatten | map(attribute='name') | list - name: "Create virtual network interface cards" azure.azcollection.azure_rm_networkinterface: diff --git a/roles/azure_edges/tasks/azure_cedge_vm.yml b/roles/azure_edges/tasks/azure_cedge_vm.yml index 1e078d6..56ef52b 100644 --- a/roles/azure_edges/tasks/azure_cedge_vm.yml +++ b/roles/azure_edges/tasks/azure_cedge_vm.yml @@ -19,7 +19,7 @@ loop_var: subnet_item register: public_ip_addresses -- name: "Get number of existing rules for NSG: {{ az_network_security_group }}" +- name: "Get info about NSG: {{ az_network_security_group }}" azure.azcollection.azure_rm_securitygroup_info: resource_group: "{{ az_resource_group }}" name: "{{ az_network_security_group }}" @@ -47,6 +47,7 @@ loop_var: public_ip_state index_var: my_idx label: public_ip_state.state.name + when: public_ip_state.state.name not in az_res_gr.securitygroups | map(attribute='rules') | flatten | map(attribute='name') | list - name: "Create virtual network interface cards" azure.azcollection.azure_rm_networkinterface: From 9a6ad4e62115b7eca205a4fa21db959ee586ff43 Mon Sep 17 00:00:00 2001 From: acichon Date: Tue, 9 Apr 2024 14:52:53 +0200 Subject: [PATCH 13/20] update README for Azure deployment --- README.md | 78 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e66c1cd..e339702 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Cisco SD-WAN Deployment on AWS using Ansible +# Cisco SD-WAN Deployment on AWS and Azure using Ansible -Ansible roles and playbooks for deployment and teardown of Cisco SD-WAN on AWS. +Ansible roles and playbooks for deployment and teardown of Cisco SD-WAN on AWS and Azure. ## Table of Contents @@ -9,6 +9,7 @@ Ansible roles and playbooks for deployment and teardown of Cisco SD-WAN on AWS. - [Prerequisites](#prerequisites) - [Getting Started](#getting-started) - [Troubleshooting](#troubleshooting) +- [Useful Links](#useful-links) - [Contact Information](#contact-information) - [License](#license) - [Contributing](#contributing) @@ -24,14 +25,19 @@ This repository includes: - `aws_edges` - `aws_teardown` - `common` +- `azure_controllers` +- `azure_edges` +- `azure_teardown` +- `azure_controllers` +- `template_cloudinit` Ansible roles, which can be used to automate the deployment (and teardown) of SD-WAN systems on the AWS cloud. -In order to have more convenient way of handling next onboarding processes, the `aws` role is generating files via: +In order to have more convenient way of handling next onboarding processes, the `aws` and `azure` roles are generating files via: -- `roles/aws_controllers/tasks/generate_deployment_facts.yml` and +- `roles/common/tasks/generate_deployment_facts_controllers.yml` and -- `roles/aws_edges/tasks/generate_deployment_facts.yml` +- `roles/common/tasks/generate_deployment_facts_edges.yml` Path of this output file customizable via `results_dir` `results_path_controllers` and `results_path_edges` variables in input config file. @@ -51,6 +57,7 @@ Current coverage: - [x] Local installation via Ansible Galaxy - [x] Installation via git repository link - [x] Migration to CiscoDevNet/Cisco Open +- [x] Separate role for cloudinit templating Future Goals: @@ -59,7 +66,6 @@ Future Goals: - [ ] Deployment on GCP - [ ] Support for cluster deployment - [ ] Enhance cloud-init configuration (complex bringup) -- [ ] Separate roles for cloudinit templating --- @@ -69,8 +75,8 @@ Before you begin, ensure you have met the following requirements: - You have installed Ansible - You have installed Python -- You have an AWS account with the necessary permissions. -- You have access to a Cisco SD-WAN AMIs on AWS. +- You have an AWS or Azure account with the necessary permissions. +- You have access to a Cisco SD-WAN AMIs on AWS or images on Azure --- @@ -118,10 +124,10 @@ pip install -r requirements.txt There are configuration files which has been initially filled with values: - `.playbooks/aws_sdwan_config_20_12.yml` - - `.playbooks/aws_sdwan_config_20_13.yml` +- `.playbooks/azure_sdwan_config.yml` -Both files are supplemented by config from `roles/aws_*/vars/example_main.yml` and defaults from `roles/aws_*/defaults/main.yml` +Both files are supplemented by config defaults from all roles. NOTE: You can call the variables file any name, but remember to choose one option: @@ -145,48 +151,52 @@ ansible-playbook playbooks/aws_deploy_controllers_20_12.yml -e "@./playbooks/aws (notice @ that suggest we are reffering to the file) -### Deploying Cisco SD-WAN on AWS +### Deploying Cisco SD-WAN + +To deploy Cisco SD-WAN on AWS or Azure, run the example playbook using roles: -To deploy Cisco SD-WAN on AWS, run the example playbook using roles: +For AWS: - `aws_network_infrastructure` - `aws_controllers` - `aws_edges` +For Azure: + +- `azure_network_infrastructure` +- `azure_controllers` +- `azure_edges` +
-Current version of this solution assumes that you have used `aws configure` command (AWS CLI) to set your credentials. #TODO other auth methods +Current version of this solution assumes that users will authenticate with their cloud providers in order to run ansible playbooks. See [Useful Links](#useful-links). We provided example playbooks that you can execute with: ```bash -ansible-playbook playbooks/deploy_controllers_20_12.yml +ansible-playbook playbooks/aws_deploy_controllers.yml +ansible-playbook playbooks/aws_deploy_edges.yml ``` or ```bash -ansible-playbook playbooks/deploy_controllers_20_13.yml -``` - -and: - -```bash -ansible-playbook deploy_edges_20_12.yml +ansible-playbook playbooks/azure_deploy_controllers.yml +ansible-playbook playbooks/azure_deploy_edges.yml ``` For desired changes, please update configuration files. ### Tearing down Cisco SD-WAN on AWS -To teardown the deployed system, run the example playbook using the `aws_teardown` role. +To teardown the deployed system, run the example playbook using the `aws_teardown` role or `azure_teardown`. ```bash -ansible-playbook ./playbooks/teardown_20_12.yml +ansible-playbook ./playbooks/aws_teardown_20_12.yml or -ansible-playbook ./playbooks/teardown_20_13.yml +ansible-playbook ./playbooks/azure_teardown.yml ``` If you want to teardown only specific ec2 instances (with their EiPs and NICs associated): @@ -224,11 +234,29 @@ If vManage is not starting NMS service: ## Compatibility Note that azure collection python requirements include package `uamqp` which can generate wheel issues. -For MacOS you need to install cmake: `brew install cmake` and: `pip install cmake`. +For MacOS you migth install cmake: `brew install cmake` and: `pip install cmake`. Then install working `uamqp` package (which is below `v1.6.9`) with: `pip install uamqp==1.6.8`. --- +## Useful links + +### AWS CLI + +- [Installing AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) +- [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) + +### AWS Authentication + +- [Understanding and Getting Your Security Credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html) +- [Configuring AWS Credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) + +### Azure Authentication + +- [Authenticating with Azure](https://docs.ansible.com/ansible/latest/scenario_guides/guide_azure.html#authenticating-with-azure) + +--- + ## Contact Information For any questions or concerns, please open an issue on this repository. From 17122bf41d5de798b7b4f5a92cf86f42d0d4afcf Mon Sep 17 00:00:00 2001 From: acichon Date: Tue, 9 Apr 2024 15:33:17 +0200 Subject: [PATCH 14/20] add note about Generating cloud-init configuration --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index e339702..b4b2869 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,12 @@ teardown_specific_instances: - "acich-ansible-cedge-222" ``` +### Generating cloud-init configuration + +Role `template_cloudinit` provide tasks that can generate `cloudinit` (also known as `userdata`) configuration, without deployment of any machines. +Examples usage of `template_cloudinit` role can be taken from `playbooks/template_cloudinit.yml`. Note, that in this example playbook, configuration file +is used from `playbooks/template_cloudinit.yml`. + --- ## Troubleshooting From 7748aba06b272bd92f8d54f88cb304ae8466cb7a Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 11 Apr 2024 11:16:28 +0200 Subject: [PATCH 15/20] support display of templates generation --- README.md | 2 +- playbooks/template_cloudinit_config.yml | 14 +++++++------- roles/common/defaults/required_vars_cloudinit.yml | 2 ++ roles/template_cloudinit/defaults/main.yml | 11 +++++++---- roles/template_cloudinit/tasks/main.yml | 13 +++++++++++++ .../tasks/template_cloudinit.yml | 4 ++++ roles/template_cloudinit/vars/main.yml | 12 ------------ 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b4b2869..f605514 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ is "allow-listed". See `aws_allowed_subnets` in `roles/aws_controllers/defaults/ If vManage is not starting NMS service: - check if your disk /opt/data is more than 20% free. Otherwise that case shutdown application as well -- remember to use at least `c5.9xlarge` instance type for vManage in AWS +- remember to make sure the sdwan manager and other sdwan virtual machines are right sized for your deployment needs - cisco's server recommendations are available here: [server-requirements](https://www.cisco.com/c/en/us/td/docs/routers/sdwan/release/notes/compatibility-and-server-recommendations/server-requirements.html) --- diff --git a/playbooks/template_cloudinit_config.yml b/playbooks/template_cloudinit_config.yml index a92e5ba..7a9a98e 100644 --- a/playbooks/template_cloudinit_config.yml +++ b/playbooks/template_cloudinit_config.yml @@ -1,5 +1,12 @@ --- +###################################### +# Generated files paths # +###################################### + +results_dir: "{{ playbook_dir }}/results" + + ####################################### # Required configuration data # ####################################### @@ -56,10 +63,3 @@ vsmart_instances: ################################ cedge_instances: [] - - -########################################## -# Reusable deployment facts # -########################################## - -results_dir: "{{ playbook_dir }}/results" diff --git a/roles/common/defaults/required_vars_cloudinit.yml b/roles/common/defaults/required_vars_cloudinit.yml index 0db4adc..f527ad3 100644 --- a/roles/common/defaults/required_vars_cloudinit.yml +++ b/roles/common/defaults/required_vars_cloudinit.yml @@ -7,3 +7,5 @@ required_variables: organization_name: "{{ organization_name }}" admin_username: "{{ admin_username }}" admin_password: "{{ admin_password }}" + vbond_transport_private_ip: "{{ vbond_transport_private_ip }}" + vbond_transport_public_ip: "{{ vbond_transport_public_ip }}" diff --git a/roles/template_cloudinit/defaults/main.yml b/roles/template_cloudinit/defaults/main.yml index 36ecd99..e28d55c 100644 --- a/roles/template_cloudinit/defaults/main.yml +++ b/roles/template_cloudinit/defaults/main.yml @@ -4,13 +4,16 @@ --- organization_name: null # has to be set by user - -aws_tag_creator: "{{ organization_name }}" +aws_key_name: null -aws_resources_prefix: "{{ organization_name }}" +# Deployment results path +results_dir: "{{ playbook_dir }}/results" -aws_key_name: null +# Path to templated userdata config +userdata_vmanage_path: "{{ results_dir }}/.userdata_vmanage" +userdata_vbond_path: "{{ results_dir }}/.userdata_vbond" +userdata_vsmart_path: "{{ results_dir }}/.userdata_vsmart" ########################################## diff --git a/roles/template_cloudinit/tasks/main.yml b/roles/template_cloudinit/tasks/main.yml index 115e6fa..86feb1f 100644 --- a/roles/template_cloudinit/tasks/main.yml +++ b/roles/template_cloudinit/tasks/main.yml @@ -40,6 +40,10 @@ state: directory mode: "0755" +- name: "Define facts to display for user information about generated files" + ansible.builtin.set_fact: + generated_files: [] + # cloud-init vBond data requires information about private IP assigned to mgmt interface # cloud-init templates require information about vBond IP # vbond_mgmt_private_ip & ec2_vbond_mgmt_public_ip @@ -100,3 +104,12 @@ loop_control: loop_var: instance_item when: cedge_instances is defined + +- name: "Display location of generated files" + ansible.builtin.debug: + msg: | + Generated files directory path: + {{ results_dir }} + + List of generated files: + {{ generated_files | to_nice_yaml }} diff --git a/roles/template_cloudinit/tasks/template_cloudinit.yml b/roles/template_cloudinit/tasks/template_cloudinit.yml index 8442008..ca76a9d 100644 --- a/roles/template_cloudinit/tasks/template_cloudinit.yml +++ b/roles/template_cloudinit/tasks/template_cloudinit.yml @@ -12,3 +12,7 @@ src: "{{ template_path }}" dest: "{{ generated_cloudinit_path if generated_cloudinit_path != '' else default_path }}" mode: "0644" + +- name: "Update generated_files list" + ansible.builtin.set_fact: + generated_files: "{{ generated_files + [generated_cloudinit_path if generated_cloudinit_path != '' else default_path] }}" diff --git a/roles/template_cloudinit/vars/main.yml b/roles/template_cloudinit/vars/main.yml index f2d38c0..50c2186 100644 --- a/roles/template_cloudinit/vars/main.yml +++ b/roles/template_cloudinit/vars/main.yml @@ -4,15 +4,3 @@ --- # vars/ are used by the role and not likely to be changed - - -# Deployment results path -results_dir: "{{ playbook_dir }}/results" - -aws_deployed_controllers_data: "{{ results_dir }}/.aws_deployed_controllers_data.yml" - - -# Path to templated userdata config -userdata_vmanage_path: "{{ results_dir }}/.userdata_vmanage" -userdata_vbond_path: "{{ results_dir }}/.userdata_vbond" -userdata_vsmart_path: "{{ results_dir }}/.userdata_vsmart" From 5bfe3b091acc2fa16537333858b58e1e50d39c26 Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 11 Apr 2024 11:32:50 +0200 Subject: [PATCH 16/20] vbond values required --- roles/template_cloudinit/defaults/main.yml | 4 ++-- roles/template_cloudinit/tasks/main.yml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/roles/template_cloudinit/defaults/main.yml b/roles/template_cloudinit/defaults/main.yml index e28d55c..e4f48f7 100644 --- a/roles/template_cloudinit/defaults/main.yml +++ b/roles/template_cloudinit/defaults/main.yml @@ -25,8 +25,8 @@ admin_username: admin admin_password: Cisco#123@Viptela vbond_port: 12346 default_vbond_ip: 192.168.1.199 # default ips from official Cisco guides -# vpn0_interface_color: default - +vbond_transport_private_ip: null +vbond_transport_public_ip: null ############################### # Controllers # diff --git a/roles/template_cloudinit/tasks/main.yml b/roles/template_cloudinit/tasks/main.yml index 86feb1f..4ba46b7 100644 --- a/roles/template_cloudinit/tasks/main.yml +++ b/roles/template_cloudinit/tasks/main.yml @@ -28,7 +28,7 @@ when: - cloud_provider not in ['aws', 'azure'] -- name: "Assert all required variables for AWS cloudinit generation" +- name: "Assert all required variables for cloudinit generation" ansible.builtin.include_role: name: common tasks_from: required_variables @@ -86,7 +86,6 @@ vpn0_default_gateway: "{{ instance_item.vpn0_default_gateway }}" template_path: "./userdata_vsmart.j2" generated_cloudinit_path: "{{ cloudinit_path | default('') }}" - loop: "{{ vsmart_instances }}" loop_control: loop_var: instance_item From 9170d2e35a939fa87424bf44fe7ebc99f988b1dc Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 11 Apr 2024 11:35:00 +0200 Subject: [PATCH 17/20] null values for vbond ips --- playbooks/template_cloudinit_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/template_cloudinit_config.yml b/playbooks/template_cloudinit_config.yml index 7a9a98e..0cdae8e 100644 --- a/playbooks/template_cloudinit_config.yml +++ b/playbooks/template_cloudinit_config.yml @@ -20,8 +20,8 @@ cloud_provider: null # can be either aws or azure admin_username: admin admin_password: Cisco#123@Viptela vbond_port: 12346 -# vbond_transport_private_ip: null # note that default: 192.168.1.199 -# vbond_transport_public_ip: null # note that default: 192.168.1.199 +vbond_transport_private_ip: null +vbond_transport_public_ip: null ############################### From f19e65a0f957931e77ddfcd7564bcba364a56a0b Mon Sep 17 00:00:00 2001 From: acichon Date: Thu, 11 Apr 2024 19:28:13 +0200 Subject: [PATCH 18/20] ensure that edges from pnp bootstrap generation will use hyphens --- roles/azure_edges/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/azure_edges/tasks/main.yml b/roles/azure_edges/tasks/main.yml index 80e2201..6dd9203 100644 --- a/roles/azure_edges/tasks/main.yml +++ b/roles/azure_edges/tasks/main.yml @@ -48,7 +48,7 @@ - name: Create ec2 instance - cEdge (C8000V) ansible.builtin.include_tasks: azure_cedge_vm.yml vars: - hostname: "{{ instance_item.hostname }}" + hostname: "{{ instance_item.hostname | replace('_', '-') }}" uuid: "{{ instance_item.uuid }}" otp: "{{ instance_item.otp }}" vbond: "{{ instance_item.vbond }}" From 1e27997040d73fe26f4ed6204461faef426efc34 Mon Sep 17 00:00:00 2001 From: acichon Date: Mon, 15 Apr 2024 12:24:35 +0200 Subject: [PATCH 19/20] add missing colon in template role --- roles/template_cloudinit/templates/userdata_vmanage.j2 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/roles/template_cloudinit/templates/userdata_vmanage.j2 b/roles/template_cloudinit/templates/userdata_vmanage.j2 index fa2eaab..a06bb58 100644 --- a/roles/template_cloudinit/templates/userdata_vmanage.j2 +++ b/roles/template_cloudinit/templates/userdata_vmanage.j2 @@ -20,7 +20,7 @@ disk_setup: /dev/nvme1n1: {% endif %} {% if cloud_provider == 'azure' %} - /dev/disk/azure/scsi1/lun10 + /dev/disk/azure/scsi1/lun10: {% endif %} table_type: mbr layout: false @@ -53,11 +53,6 @@ write_files: content: "vmanage\n" - path: /etc/default/inited content: "1\n" -# These are only for internal usage -# - path: /etc/viptela/testbed -# content: "\n" -# - path: /boot/testbed -# content: "\n" - path: /etc/confd/init/zcloud.xml content: | From a186116c53ae658ad905de1af88efc856b398aad Mon Sep 17 00:00:00 2001 From: acichon Date: Tue, 16 Apr 2024 08:57:41 +0200 Subject: [PATCH 20/20] update README with reqs note --- README.md | 7 ++++--- playbooks/template_cloudinit_config.yml | 12 ++++++------ roles/azure_edges/tasks/main.yml | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f605514..10d4e0e 100644 --- a/README.md +++ b/README.md @@ -71,11 +71,12 @@ Future Goals: ## Prerequisites +This collection is based on `ansible-core==2.16`, see [ansible-core-support-matrix](https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix). + Before you begin, ensure you have met the following requirements: -- You have installed Ansible -- You have installed Python -- You have an AWS or Azure account with the necessary permissions. +- You have installed Python 3.10 - 3.12 +- You have an AWS or Azure account with the necessary permissions - You have access to a Cisco SD-WAN AMIs on AWS or images on Azure --- diff --git a/playbooks/template_cloudinit_config.yml b/playbooks/template_cloudinit_config.yml index 0cdae8e..8130b47 100644 --- a/playbooks/template_cloudinit_config.yml +++ b/playbooks/template_cloudinit_config.yml @@ -32,29 +32,29 @@ vbond_transport_public_ip: null site_id_vmanage: 100 vmanage_instances: - - hostname: "{{ resources_prefix }}-vManage" + - hostname: terraformvmanage1 # "{{ resources_prefix }}-vManage" system_ip: 192.168.1.1 site_id: "{{ site_id_vmanage }}" - vpn0_default_gateway: # has to be set if cloud_provider == "azure" + vpn0_default_gateway: 10.0.2.1 # has to be set if cloud_provider == "azure" # vBond site_id_vbond: 200 vbond_instances: - - hostname: "{{ resources_prefix }}-vBond" + - hostname: terraformvbond1 # "{{ resources_prefix }}-vBond" system_ip: 192.168.3.1 site_id: "{{ site_id_vbond }}" - vpn0_default_gateway: # has to be set if cloud_provider == "azure" + vpn0_default_gateway: 10.0.2.1 # has to be set if cloud_provider == "azure" # vSmart site_id_vsmart: 300 vsmart_instances: - - hostname: "{{ resources_prefix }}-vSmart" + - hostname: terraformvsmart1 # "{{ resources_prefix }}-vSmart" system_ip: 192.168.2.1 site_id: "{{ site_id_vsmart }}" - vpn0_default_gateway: # has to be set if cloud_provider == "azure" + vpn0_default_gateway: 10.0.2.1 # has to be set if cloud_provider == "azure" diff --git a/roles/azure_edges/tasks/main.yml b/roles/azure_edges/tasks/main.yml index 6dd9203..f61e244 100644 --- a/roles/azure_edges/tasks/main.yml +++ b/roles/azure_edges/tasks/main.yml @@ -45,7 +45,7 @@ deployment_facts: deployed_edge_instances: [] -- name: Create ec2 instance - cEdge (C8000V) +- name: Create VM instance - cEdge (C8000V) ansible.builtin.include_tasks: azure_cedge_vm.yml vars: hostname: "{{ instance_item.hostname | replace('_', '-') }}"