├── examples ├── bms1.md ├── bms2.md ├── aws │ ├── contrail_with_k8s.yaml │ ├── all_in_one_with_openstack.yaml │ └── contrail_ha_with_openstack.yaml ├── aws_k8s.md ├── gce1.md ├── kvm1.md └── aws2.md ├── playbooks ├── roles │ ├── instance │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ ├── RedHat.yml │ │ │ ├── Debian.yml │ │ │ ├── ntp.yml │ │ │ ├── main.yml │ │ │ └── copy_root_ca.yml │ │ ├── templates │ │ │ └── ntp.conf.j2 │ │ └── files │ │ │ └── satellite.englab.juniper.net.crt │ ├── heat │ │ ├── files │ │ │ ├── contrail-plugin.pth │ │ │ ├── config_opensdn.sh │ │ │ ├── config.json │ │ │ └── heat.conf │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── config_opensdn.yml │ │ │ ├── init_opensdn.yml │ │ │ └── restart_containers.yml │ │ └── defaults │ │ │ └── main.yml │ ├── nova │ │ ├── files │ │ │ ├── contrail-plugin.pth │ │ │ ├── config.json │ │ │ ├── rootwrap.conf │ │ │ └── config_opensdn.sh │ │ ├── tasks │ │ │ ├── config_opensdn.yml │ │ │ ├── main.yml │ │ │ ├── init_opensdn.yml │ │ │ └── restart_containers.yml │ │ └── defaults │ │ │ └── main.yml │ ├── neutron │ │ ├── files │ │ │ ├── contrail-plugin.pth │ │ │ ├── ContrailPlugin.ini │ │ │ └── api-paste.ini │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── init_opensdn.yml │ │ │ ├── config_opensdn.yml │ │ │ └── restart_containers.yml │ │ ├── defaults │ │ │ └── main.yml │ │ └── templates │ │ │ └── ContrailPlugin.ini.j2 │ ├── kvm │ │ ├── tasks │ │ │ ├── main.yml │ │ │ └── build_kvm_instances.yml │ │ └── templates │ │ │ ├── additional_interface.j2 │ │ │ ├── virt-install.sh.j2 │ │ │ └── virt-customize.sh.j2 │ ├── opensdn │ │ ├── templates │ │ │ ├── common.env.j2 │ │ │ └── defaults.env.j2 │ │ └── tasks │ │ │ ├── common_Linux.yml │ │ │ ├── delete.yml │ │ │ └── deregister.yml │ ├── docker │ │ ├── tasks │ │ │ ├── start_docker_Linux.yml │ │ │ ├── auth_registry.yaml │ │ │ ├── private_registry_Linux.yml │ │ │ ├── RedHat.yml │ │ │ ├── Rocky.yml │ │ │ ├── insecure_registry_Linux.yml │ │ │ └── Debian.yml │ │ └── defaults │ │ │ └── main.yml │ ├── opensdn_rsyslogd │ │ ├── vars │ │ │ └── main.yml │ │ ├── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-rsyslogd.yaml.j2 │ ├── pip │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ ├── aws_deployer │ │ └── tasks │ │ │ └── main.yml │ ├── gce_deployer │ │ └── tasks │ │ │ └── main.yml │ ├── test │ │ ├── templates │ │ │ └── test.sh.j2 │ │ └── tasks │ │ │ └── get_master.yml │ ├── opensdn_control_only │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── stop.yml │ │ │ └── update_images.yml │ │ └── templates │ │ │ └── contrail-control-only.yaml.j2 │ ├── opensdn_redis │ │ ├── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-redis.yaml.j2 │ ├── opensdn_webui │ │ ├── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-webui.yaml.j2 │ ├── opensdn_analytics │ │ ├── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-analytics.yaml.j2 │ ├── opensdn_config │ │ └── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ ├── opensdn_control │ │ └── tasks │ │ │ ├── stop.yml │ │ │ └── update_images.yml │ ├── opensdn_analytics_snmp │ │ ├── tasks │ │ │ ├── stop.yml │ │ │ ├── main.yml │ │ │ └── update_images.yml │ │ └── templates │ │ │ └── contrail-analytics-snmp.yaml.j2 │ ├── openstack │ │ ├── tasks │ │ │ ├── inventory.yml │ │ │ ├── passwords.yml │ │ │ ├── kolla_baremetal.yml │ │ │ └── manage_etc_hosts.yml │ │ ├── templates │ │ │ ├── globals.yml.j2 │ │ │ └── host_vars.yml.j2 │ │ └── vars │ │ │ └── main.yml │ ├── opensdn_analytics_alarm │ │ └── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ ├── opensdn_analytics_database │ │ └── tasks │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── main.yml │ ├── opensdn_config_database │ │ └── tasks │ │ │ ├── stop.yml │ │ │ └── update_images.yml │ ├── kolla_deployer │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── install_kolla_dependencies.yml │ │ │ └── RedHat.yml │ │ └── defaults │ │ │ └── main.yml │ ├── opensdn_toragent │ │ ├── tasks │ │ │ ├── main.yml │ │ │ ├── update_images.yml │ │ │ ├── delete.yml │ │ │ └── toragent.yml │ │ └── templates │ │ │ └── contrail-toragent.yaml.j2 │ ├── opensdn_compute_legacy │ │ ├── templates │ │ │ └── contrail-compute-legacy.yaml.j2 │ │ └── tasks │ │ │ ├── update_images.yml │ │ │ └── main.yml │ ├── opensdn_deployer │ │ ├── tasks │ │ │ ├── set_default_variables.yml │ │ │ ├── generate_ca.yml │ │ │ ├── cluster_node_role_lists.yml │ │ │ ├── configure_certs.yml │ │ │ ├── set_global_variables.yml │ │ │ └── main.yml │ │ ├── defaults │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail_openssl.cfg.j2 │ ├── opensdn_k8s_cni │ │ ├── tasks │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-cni.yaml.j2 │ ├── haproxy │ │ ├── tasks │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── haproxy.yaml.j2 │ ├── k8s │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ ├── Debian.yml │ │ │ ├── configure_k8s_join_node.yml │ │ │ ├── create_k8s_dashboard.yml │ │ │ ├── Rocky.yml │ │ │ ├── RedHat.yml │ │ │ ├── configure_kubelet.yml │ │ │ └── configure_k8s_master_node.yml │ ├── opensdn_k8s_kubemanager │ │ ├── tasks │ │ │ ├── update_images.yml │ │ │ └── main.yml │ │ └── templates │ │ │ └── contrail-kubemanager.yaml.j2 │ ├── kvm_deployer │ │ └── tasks │ │ │ ├── get_container_hosts.yml │ │ │ ├── combine_kvm_container_hosts.yml │ │ │ └── main.yml │ ├── destroy │ │ └── tasks │ │ │ └── main.yml │ ├── openstack_deployer │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ └── cluster_node_role_lists.yml │ ├── opensdn_vrouter │ │ ├── tasks │ │ │ ├── delete.yml │ │ │ ├── stop.yml │ │ │ ├── update_images.yml │ │ │ └── deregister.yml │ │ └── templates │ │ │ └── common_vrouter.env.j2 │ ├── opensdn_k8s_master │ │ ├── templates │ │ │ └── contrail-kubemanager-serviceaccount.yaml.j2 │ │ └── tasks │ │ │ └── main.yml │ └── k8s_deployer │ │ └── tasks │ │ └── main.yml ├── ziu_openstack.yml ├── ziu.yml ├── provision_instances.yml ├── contrail_destroy.yml ├── configure_instances.yml ├── install_k8s.yml ├── openstack_destroy.yml └── config_openstack.yml ├── setup.py ├── .gitignore ├── .gitreview ├── ansible.cfg ├── config ├── instances.yaml ├── instances.yaml.bms_example ├── instances.yaml.aws_example ├── instances.yaml.kvm_example ├── instances.yaml.xflow_single_node ├── instances.yaml.bms_win_no_openstack_example ├── instances.yaml.ml2.bms_example ├── instances.yaml.xflow_multi_node ├── instances.json ├── instances.yaml.xflow_in_band ├── instances.yaml.bms_win_full_example ├── instances.yaml.bms_win_example ├── instances.yaml.openstack_example ├── instances.yaml.bms_with_qos_example ├── instances.yaml.bms_with_tor_tsn_ha ├── instances.yaml.openstack_on_aws_example ├── instances.yaml.gce_example └── instances.yaml.bms_tor_agent ├── inventory └── hosts ├── tox.ini └── README_ziu.md /examples/bms1.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/bms2.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playbooks/roles/instance/defaults/main.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /playbooks/roles/heat/files/contrail-plugin.pth: -------------------------------------------------------------------------------- 1 | /opt/plugin/site-packages 2 | -------------------------------------------------------------------------------- /playbooks/roles/nova/files/contrail-plugin.pth: -------------------------------------------------------------------------------- 1 | /opt/plugin/site-packages 2 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/files/contrail-plugin.pth: -------------------------------------------------------------------------------- 1 | /opt/plugin/site-packages 2 | -------------------------------------------------------------------------------- /playbooks/ziu_openstack.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - import_playbook: "install_openstack.yml" -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | 4 | setup( 5 | name='tf-ansible-deployer', 6 | ) 7 | -------------------------------------------------------------------------------- /playbooks/roles/kvm/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create KVM instance 2 | include_tasks: build_kvm_instances.yml 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | playbooks/*.retry 2 | *.pyc 3 | playbooks/test.yml 4 | .project 5 | .vscode 6 | *.egg-info 7 | __pycache__ 8 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=gerrit.opensdn.io 3 | port=29418 4 | project=opensdn-io/tf-ansible-deployer.git 5 | defaultbranch=master -------------------------------------------------------------------------------- /playbooks/ziu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # ZIU have three stages: controller -> openstack -> compute 3 | - import_playbook: "ziu_{{ stage }}.yml" -------------------------------------------------------------------------------- /playbooks/roles/opensdn/templates/common.env.j2: -------------------------------------------------------------------------------- 1 | {% for k,v in contrail_configuration.items() %} 2 | {{ k }}={{ v }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn/templates/defaults.env.j2: -------------------------------------------------------------------------------- 1 | {% for k,v in default_configuration.items() %} 2 | {{ k }}={{ v }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /playbooks/roles/instance/tasks/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set selinux to permissive 3 | selinux: 4 | policy: targeted 5 | state: permissive 6 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/start_docker_Linux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: start docker daemon 3 | service: 4 | enabled: yes 5 | name: docker 6 | state: started 7 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_rsyslogd/vars/main.yml: -------------------------------------------------------------------------------- 1 | rsyslogd_common_volumes: 2 | - "/var/run:/var/run" 3 | 4 | rsyslogd_volumes: "{{ common_volumes + rsyslogd_common_volumes }}" 5 | -------------------------------------------------------------------------------- /playbooks/roles/pip/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # while default python is 2.7 we have to use pip compatibe to python2 4 | get_pip_url: "https://bootstrap.pypa.io/pip/3.6/get-pip.py" 5 | -------------------------------------------------------------------------------- /playbooks/roles/aws_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create AWS instance 2 | include_tasks: build_aws_instances.yml 3 | when: item.value.provider=='aws' 4 | with_dict: "{{ instances }}" 5 | -------------------------------------------------------------------------------- /playbooks/roles/gce_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create GCE instance 2 | include_tasks: build_gce_instances.yml 3 | when: item.value.provider=='gce' 4 | with_dict: "{{ instances }}" 5 | -------------------------------------------------------------------------------- /playbooks/roles/docker/defaults/main.yml: -------------------------------------------------------------------------------- 1 | nix_docker_config_directory: /etc/docker 2 | nix_docker_config_file: "{{ nix_docker_config_directory }}/daemon.json" 3 | nix_docker_certs_directory: /etc/docker/certs.d 4 | -------------------------------------------------------------------------------- /playbooks/roles/test/templates/test.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo \ 3 | {% for container_host in hostvars[inventory_hostname].groups.container_hosts %} 4 | {{ container_host }} \ 5 | {% endfor %} 6 | > /tmp/blaX 7 | -------------------------------------------------------------------------------- /playbooks/roles/test/tasks/get_master.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - debug: 3 | msg: "I am not master, master is {{ master }}" 4 | when: inventory_hostname != master 5 | 6 | - debug: 7 | msg: "I am master" 8 | when: inventory_hostname == master 9 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | host_key_checking = False 3 | log_path = /var/log/ansible.log 4 | jinja2_extensions=jinja2.ext.do 5 | display_skipped_hosts = False 6 | forks=100 7 | 8 | [ssh_connection] 9 | pipelining = True 10 | retries = 3 11 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control_only/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: call control only 3 | include_tasks: "step2.yml" 4 | with_dict: "{{ remote_locations }}" 5 | loop_control: 6 | loop_var: location 7 | when: remote_locations is defined 8 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_redis/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "stop redis" 3 | docker_compose: 4 | project_src: /etc/contrail/redis 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_webui/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | - name: "stop contrail webui" 2 | docker_compose: 3 | project_src: /etc/contrail/webui 4 | state: absent 5 | environment: 6 | DOCKER_CLIENT_TIMEOUT: '120' 7 | COMPOSE_HTTP_TIMEOUT: '120' 8 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_rsyslogd/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "stop rsyslogd" 3 | docker_compose: 4 | project_src: /etc/contrail/rsyslogd 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail analytics 3 | docker_compose: 4 | project_src: /etc/contrail/analytics 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_config/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail config service 3 | docker_compose: 4 | project_src: /etc/contrail/config 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Stop contrail control" 3 | docker_compose: 4 | project_src: /etc/contrail/control 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /config/instances.yaml: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | instances: 4 | bms1: 5 | provider: bms 6 | ip: 192.168.1.100 7 | global_configuration: 8 | CONTAINER_REGISTRY: michaelhenkel 9 | contrail_configuration: 10 | CONTRAIL_VERSION: queens-5.0-20180219195722 11 | -------------------------------------------------------------------------------- /playbooks/roles/heat/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: run heat_engine init container 4 | include: init_opensdn.yml 5 | 6 | - name: config heat_engine container 7 | include: config_opensdn.yml 8 | 9 | - name: restart containers 10 | include: restart_containers.yml 11 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_snmp/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail analytics_snmp 3 | docker_compose: 4 | project_src: /etc/contrail/analytics_snmp 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/tasks/inventory.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Populate openstack inventory 3 | template: 4 | src: "{{ role_path }}/templates/inventory.j2" 5 | dest: "{{ kolla_dir }}/ansible/inventory/{{ inventory_name }}" 6 | delegate_to: localhost 7 | run_once: yes 8 | -------------------------------------------------------------------------------- /playbooks/roles/heat/tasks/config_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Copy heat config script to all hosts 4 | copy: 5 | src: "{{ role_path }}/files/" 6 | dest: "/tmp/" 7 | mode: 0755 8 | 9 | - name: Execute heat config script 10 | command: "/tmp/config_opensdn.sh" 11 | -------------------------------------------------------------------------------- /playbooks/roles/instance/tasks/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install chrony instead of timesyncd 4 | apt: 5 | name: chrony 6 | state: latest 7 | install_recommends: yes 8 | update_cache: true 9 | register: res 10 | retries: 5 11 | until: res is success 12 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: run neutron init container 4 | include: init_opensdn.yml 5 | 6 | - name: config neutron_server container 7 | include: config_opensdn.yml 8 | 9 | - name: delete containers 10 | include: restart_containers.yml 11 | -------------------------------------------------------------------------------- /playbooks/roles/nova/tasks/config_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Copy nova config script to all hosts 4 | copy: 5 | src: "{{ role_path }}/files/" 6 | dest: "/tmp/" 7 | mode: 0755 8 | 9 | - name: Execute nova config script 10 | command: "/tmp/config_opensdn.sh" 11 | -------------------------------------------------------------------------------- /playbooks/roles/nova/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: run nova_compute init container 4 | include: init_opensdn.yml 5 | 6 | - name: config nova_compute container 7 | include: config_opensdn.yml 8 | 9 | - name: restart containers 10 | include: restart_containers.yml 11 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_alarm/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail analytics_alarm 3 | docker_compose: 4 | project_src: /etc/contrail/analytics_alarm 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_database/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail analyticsdb 3 | docker_compose: 4 | project_src: /etc/contrail/analytics_database 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_config_database/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: stop contrail config database 3 | docker_compose: 4 | project_src: /etc/contrail/config_database 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | -------------------------------------------------------------------------------- /playbooks/roles/kolla_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install_kolla_dependencies 4 | include_tasks: install_kolla_dependencies.yml 5 | tags: 6 | - kolla 7 | 8 | - name: create kolla playbooks 9 | include_tasks: create_kolla_playbooks.yml 10 | tags: 11 | - kolla 12 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_toragent/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Create toragent-s 4 | include_tasks: "toragent.yml toragent_name={{ 'toragent_' + toragent.key }} toragent_data={{ toragent.value }}" 5 | with_dict: "{{ roles[instance_name].toragent }}" 6 | loop_control: 7 | loop_var: toragent 8 | -------------------------------------------------------------------------------- /playbooks/roles/kolla_deployer/tasks/install_kolla_dependencies.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: OS specific package install 3 | include_tasks: RedHat.yml 4 | when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' 5 | 6 | - name: install git to operate on kolla branches 7 | package: 8 | name: git 9 | state: present 10 | become: yes 11 | -------------------------------------------------------------------------------- /playbooks/roles/instance/templates/ntp.conf.j2: -------------------------------------------------------------------------------- 1 | tinker panic 0 2 | 3 | disable monitor 4 | restrict default kod nomodify notrap nopeer noquery 5 | restrict -6 default kod nomodify notrap nopeer noquery 6 | restrict 127.0.0.1 7 | restrict -6 ::1 8 | server {{ provider_data.ntpserver }} iburst 9 | 10 | 11 | # Driftfile. 12 | driftfile /var/lib/ntp/drift 13 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_compute_legacy/templates/contrail-compute-legacy.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | openstack-compute-legacy: 4 | image: "{{ container_registry }}/opensdn-openstack-compute-init:{{ contrail_version_tag }}" 5 | network_mode: "host" 6 | volumes: 7 | - /usr/bin:/opt/plugin/bin 8 | - {{ pythonpath.stdout }}:/opt/plugin/site-packages 9 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/set_default_variables.yml: -------------------------------------------------------------------------------- 1 | - name: set contrail configuration param 2 | set_fact: 3 | default_configuration: {} 4 | when: default_configuration is undefined 5 | tags: 6 | - always 7 | 8 | - name: set orchestrator param 9 | set_fact: 10 | default_configuration: "{{ default_configuration }}" 11 | tags: 12 | - always 13 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/auth_registry.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # this file is parameterized 4 | # it takes 'docker_registry','docker_registry_username','docker_registry_password' as parameters 5 | 6 | - name: activate docker login 7 | shell: "docker login --username {{ docker_registry_username }} --password {{ docker_registry_password }} {{ docker_registry }}" 8 | tags: 9 | - always 10 | -------------------------------------------------------------------------------- /inventory/hosts: -------------------------------------------------------------------------------- 1 | localhost: 2 | hosts: 3 | localhost: 4 | config_file: ../config/instances.yaml 5 | connection: local 6 | ansible_connection: local 7 | #container_hosts: 8 | # hosts: 9 | # 192.168.1.100: 10 | # ansible_ssh_pass: contrail123 11 | # 192.168.1.101: 12 | # ansible_ssh_pass: contrail123 13 | # 192.168.1.102: 14 | # ansible_ssh_pass: contrail123 15 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control_only/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Stop control only 3 | docker_compose: 4 | project_src: "/etc/contrail/control_only_{{ location.key }}" 5 | state: absent 6 | environment: 7 | DOCKER_CLIENT_TIMEOUT: '120' 8 | COMPOSE_HTTP_TIMEOUT: '120' 9 | with_dict: "{{ remote_locations }}" 10 | loop_control: 11 | loop_var: location 12 | when: remote_locations is defined 13 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_cni/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail k8s_cni image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-kubernetes-cni-init 8 | when: 9 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 10 | - roles[instance_name].k8s_node is defined 11 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_cni/templates/contrail-cni.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | vrouter-cni: 4 | image: "{{ container_registry }}/opensdn-kubernetes-cni-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common_cni.env 6 | network_mode: "host" 7 | volumes: 8 | - /var/lib/contrail:/var/lib/contrail 9 | - /etc/cni:/host/etc_cni 10 | - /opt/cni/bin:/host/opt_cni_bin 11 | - /var/log/contrail/cni:/var/log/contrail/cni 12 | -------------------------------------------------------------------------------- /playbooks/roles/haproxy/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update haproxy image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-external-haproxy 9 | when: 10 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 11 | - roles[instance_name].tsn_haproxy is defined 12 | -------------------------------------------------------------------------------- /playbooks/roles/heat/files/config_opensdn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | sudo docker cp /tmp/contrail-plugin.pth heat_engine:/usr/lib/python3.6/site-packages/ 4 | if !(grep -q "plugin_dirs = /opt/plugin/site-packages/vnc_api/gen/heat/resources,/opt/plugin/site-packages/contrail_heat/resources" /etc/kolla/heat-engine/heat.conf); then 5 | sed -i '2a plugin_dirs = /opt/plugin/site-packages/vnc_api/gen/heat/resources,/opt/plugin/site-packages/contrail_heat/resources' /etc/kolla/heat-engine/heat.conf 6 | fi 7 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_compute_legacy/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update compute_legacy image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-openstack-compute-init 8 | when: 9 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 10 | - roles[instance_name].openstack_compute_legacy is defined 11 | -------------------------------------------------------------------------------- /playbooks/roles/heat/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | default_openstack_version: yoga 4 | openstack_version: >- 5 | {%- if contrail_configuration.OPENSTACK_VERSION is defined -%} 6 | {{ contrail_configuration.OPENSTACK_VERSION }} 7 | {%- elif kolla_config.kolla_globals is defined and kolla_config.kolla_globals.openstack_release is defined -%} 8 | {{ kolla_config.kolla_globals.openstack_release }} 9 | {%- else -%} 10 | {{ default_openstack_version }} 11 | {%- endif %} 12 | -------------------------------------------------------------------------------- /playbooks/roles/kvm/templates/additional_interface.j2: -------------------------------------------------------------------------------- 1 | DEVICE=eth{{interface_var.0 + 1 }} 2 | {% if interface_var.1.ip is defined %} 3 | IPADDR={{ interface_var.1.ip }} 4 | {% endif %} 5 | {% if interface_var.1.mask is defined %} 6 | NETMASK={{ interface_var.1.mask }} 7 | {% endif %} 8 | {% if interface_var.1.gateway is defined %} 9 | GATEWAY={{ interface_var.1.gateway }} 10 | {% endif %} 11 | {% if interface_var.1.dns is defined %} 12 | DNS1={{ interface_var.1.dns }} 13 | {% endif %} 14 | ONBOOT=yes 15 | -------------------------------------------------------------------------------- /playbooks/roles/nova/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | default_openstack_version: yoga 4 | openstack_version: >- 5 | {%- if contrail_configuration.OPENSTACK_VERSION is defined -%} 6 | {{ contrail_configuration.OPENSTACK_VERSION }} 7 | {%- elif kolla_config.kolla_globals is defined and kolla_config.kolla_globals.openstack_release is defined -%} 8 | {{ kolla_config.kolla_globals.openstack_release }} 9 | {%- else -%} 10 | {{ default_openstack_version }} 11 | {%- endif %} 12 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_rsyslogd/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail rsyslogd image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-external-rsyslogd 8 | when: 9 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 10 | - roles[instance_name].vrouter is defined and ansible_system == 'Linux' 11 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | default_openstack_version: rocky 4 | openstack_version: >- 5 | {%- if contrail_configuration.OPENSTACK_VERSION is defined -%} 6 | {{ contrail_configuration.OPENSTACK_VERSION }} 7 | {%- elif kolla_config.kolla_globals is defined and kolla_config.kolla_globals.openstack_release is defined -%} 8 | {{ kolla_config.kolla_globals.openstack_release }} 9 | {%- else -%} 10 | {{ default_openstack_version }} 11 | {%- endif %} 12 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_webui/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail webui image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-controller-webui-web 8 | - opensdn-controller-webui-job 9 | when: 10 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 11 | - roles[instance_name].webui is defined 12 | -------------------------------------------------------------------------------- /playbooks/roles/heat/files/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "heat-engine", 3 | "config_files": [ 4 | { 5 | "source": "/var/lib/kolla/config_files/heat.conf", 6 | "dest": "/etc/heat/heat.conf", 7 | "owner": "heat", 8 | "perm": "0600" 9 | } ], 10 | "permissions": [ 11 | { 12 | "path": "/var/log/kolla/heat", 13 | "owner": "heat:heat", 14 | "recurse": true 15 | } 16 | ] 17 | } 18 | 19 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: 4 | ssh_user: 5 | ssh_public_key: 6 | ssh_private_key: 7 | ntpserver: 192.168.1.1 8 | instances: 9 | bms1: 10 | provider: bms 11 | ip: 192.168.1.100 12 | bms2: 13 | provider: bms 14 | ip: 192.168.1.101 15 | bms3: 16 | provider: bms 17 | ip: 192.168.1.102 18 | global_configuration: 19 | CONTAINER_REGISTRY: michaelhenkel 20 | contrail_configuration: 21 | CONTRAIL_VERSION: ocata-5.0.0-134 22 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_toragent/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail toragent image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-tor-agent 9 | - opensdn-provisioner 10 | when: 11 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 12 | - roles[instance_name].toragent is defined 13 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | kube_pod_subnet: >- 4 | {%- if contrail_configuration is defined -%} 5 | {{ contrail_configuration.get('KUBERNETES_POD_SUBNETS', '10.32.0.0/12') }} 6 | {%- else -%} 7 | {{ '10.32.0.0/12' }} 8 | {%- endif -%} 9 | 10 | kube_service_subnet: >- 11 | {%- if contrail_configuration is defined -%} 12 | {{ contrail_configuration.get('KUBERNETES_SERVICE_SUBNETS', '10.96.0.0/12') }} 13 | {%- else -%} 14 | {{ '10.96.0.0/12' }} 15 | {%- endif -%} 16 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_redis/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail redis image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-external-redis 8 | - opensdn-external-stunnel 9 | when: 10 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 11 | - roles[instance_name].webui is defined or roles[instance_name].analytics is defined 12 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_rsyslogd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/rsyslogd 3 | file: 4 | path: /etc/contrail/rsyslogd 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "create rsyslogd compose file" 9 | template: 10 | src: contrail-rsyslogd.yaml.j2 11 | dest: "/etc/contrail/rsyslogd/docker-compose.yaml" 12 | 13 | - name: "start rsyslogd" 14 | docker_compose: 15 | project_src: /etc/contrail/rsyslogd 16 | environment: 17 | DOCKER_CLIENT_TIMEOUT: '120' 18 | COMPOSE_HTTP_TIMEOUT: '120' 19 | -------------------------------------------------------------------------------- /playbooks/roles/kolla_deployer/tasks/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: install gcc package required by kolla playbooks 4 | yum: 5 | name: "gcc" 6 | state: present 7 | 8 | - name: install python-devel package required by kolla playbooks (py2) 9 | yum: 10 | name: "python-devel" 11 | state: present 12 | when: ansible_python.version.major < 3 13 | 14 | - name: install python3-devel package required by kolla playbooks (py3) 15 | yum: 16 | name: python3-devel 17 | state: present 18 | when: ansible_python.version.major == 3 19 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_kubemanager/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail k8s kube-manager image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-kubernetes-kube-manager 8 | when: 9 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 10 | - roles[instance_name].kubemanager is defined and k8s_master_ip is defined and k8s_master_name is defined 11 | -------------------------------------------------------------------------------- /playbooks/roles/heat/tasks/init_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove init container 3 | docker_container: 4 | name: contrail-openstack-heat-init 5 | state: absent 6 | ignore_errors: true 7 | 8 | - name: Copy heat plugin to shared volume 9 | docker_container: 10 | name: contrail-openstack-heat-init 11 | image: "{{ container_registry }}/opensdn-openstack-heat-init:{{ contrail_version_tag }}" 12 | volumes: 13 | - "opensdn:/opt/plugin/" 14 | env: 15 | OPENSTACK_VERSION: "{{ openstack_version }}" 16 | -------------------------------------------------------------------------------- /playbooks/roles/nova/tasks/init_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove init container 3 | docker_container: 4 | name: contrail-openstack-compute-init 5 | state: absent 6 | ignore_errors: true 7 | 8 | - name: Copy nova plugin to shared volume 9 | docker_container: 10 | name: contrail-openstack-compute-init 11 | image: "{{ container_registry }}/opensdn-openstack-compute-init:{{ contrail_version_tag }}" 12 | volumes: 13 | - "opensdn:/opt/plugin/" 14 | env: 15 | OPENSTACK_VERSION: "{{ openstack_version }}" 16 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_rsyslogd/templates/contrail-rsyslogd.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | rsyslogd: 4 | image: "{{ container_registry }}/opensdn-external-rsyslogd:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common.env 6 | network_mode: "host" 7 | volumes: 8 | {{ rsyslogd_volumes | to_yaml | indent(width=6) }} 9 | logging: 10 | driver: "{{ rsyslogd_log_driver }}" 11 | options: 12 | max-size: "{{ rsyslogd_log_max_size }}" 13 | max-file: "{{ rsyslogd_log_max_file }}" 14 | restart: always 15 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/tasks/init_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove init container 3 | docker_container: 4 | name: opensdn-openstack-neutron-init 5 | state: absent 6 | ignore_errors: true 7 | 8 | - name: Copy neutron plugin to shared volume 9 | docker_container: 10 | name: opensdn-openstack-neutron-init 11 | image: "{{ container_registry }}/opensdn-openstack-neutron-init:{{ contrail_version_tag }}" 12 | volumes: 13 | - "opensdn:/opt/plugin/" 14 | env: 15 | OPENSTACK_VERSION: "{{ openstack_version }}" 16 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control_only/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail control_only image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-provisioner 10 | - opensdn-controller-control-control 11 | when: 12 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 13 | - roles[instance_name].control_only is defined 14 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/tasks/config_opensdn.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Generate ContrailPlugin.ini from Jinja2 template 4 | become: true 5 | template: 6 | src: "{{ role_path }}/templates/ContrailPlugin.ini.j2" 7 | dest: "{{ role_path }}/files/ContrailPlugin.ini" 8 | mode: "0664" 9 | register: contrailplugin_ini 10 | 11 | - name: Copy neutron_server config script to all hosts 12 | copy: 13 | src: "{{ role_path }}/files/" 14 | dest: "/tmp/" 15 | mode: 0755 16 | 17 | - name: Execute neutron_server config script 18 | command: "/tmp/config_opensdn.sh" 19 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail analytics images 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-analytics-api 10 | - opensdn-analytics-collector 11 | - opensdn-provisioner 12 | when: 13 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 14 | - roles[instance_name].analytics is defined 15 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/tasks/passwords.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Create password file from template 4 | no_log: True 5 | template: 6 | src: "{{ role_path }}/templates/passwords_{{ openstack_sku }}.yml.j2" 7 | dest: "{{ kolla_dir }}/etc/kolla/passwords.yml" 8 | delegate_to: localhost 9 | run_once: yes 10 | 11 | - name: Generate kolla passwords 12 | command: "{{ kolla_dir }}/tools/generate_passwords.py -p {{ kolla_dir }}/etc/kolla/passwords.yml" 13 | register: pw_output 14 | failed_when: pw_output.rc != 0 15 | delegate_to: localhost 16 | run_once: yes 17 | no_log: True 18 | -------------------------------------------------------------------------------- /playbooks/roles/heat/tasks/restart_containers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart heat_engine container 4 | shell: "sudo docker restart heat_engine" 5 | no_log: false 6 | ignore_errors: true 7 | args: 8 | chdir: "{{ role_path }}" 9 | 10 | - name: restart heat_api container 11 | shell: "sudo docker restart heat_api" 12 | no_log: false 13 | ignore_errors: true 14 | args: 15 | chdir: "{{ role_path }}" 16 | 17 | - name: restart heat_api_cfn container 18 | shell: "sudo docker restart heat_api_cfn" 19 | no_log: false 20 | ignore_errors: true 21 | args: 22 | chdir: "{{ role_path }}" 23 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_alarm/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update alarm, external-kafka image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-analytics-alarm-gen 10 | - opensdn-external-kafka 11 | - opensdn-provisioner 12 | when: 13 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 14 | - roles[instance_name].analytics_alarm is defined 15 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_snmp/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/analytics_snmp 3 | file: 4 | path: /etc/contrail/analytics_snmp 5 | state: directory 6 | recurse: yes 7 | 8 | - name: create contrail analytics_snmp docker-compose file 9 | template: 10 | src: contrail-analytics-snmp.yaml.j2 11 | dest: /etc/contrail/analytics_snmp/docker-compose.yaml 12 | 13 | - name: start contrail analytics_snmp 14 | docker_compose: 15 | project_src: /etc/contrail/analytics_snmp 16 | environment: 17 | DOCKER_CLIENT_TIMEOUT: '120' 18 | COMPOSE_HTTP_TIMEOUT: '120' 19 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/templates/globals.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | # You can use this file to override _any_ variable throughout Kolla. 3 | # Additional options can be found in the 4 | # 'kolla-ansible/ansible/group_vars/all.yml' file. 5 | 6 | {% for key, value in final_kolla_globals.items() %} 7 | {% if value is mapping %} 8 | {{ key }}: 9 | {% for k, v in value.items() %} 10 | {{ k }}: {{ v }} 11 | {% endfor %} 12 | {% elif value is iterable and value is not string %} 13 | {{ key }}: 14 | {% for v in value %} 15 | - {{ v }} 16 | {% endfor %} 17 | {% else %} 18 | {{ key }}: {{ value }} 19 | {% endif %} 20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_database/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail analytics database image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-analytics-query-engine 10 | - opensdn-external-cassandra 11 | - opensdn-provisioner 12 | when: 13 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 14 | - roles[instance_name].analytics_database is defined 15 | -------------------------------------------------------------------------------- /config/instances.yaml.aws_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | aws: 3 | ec2_access_key: 4 | ec2_secret_key: 5 | ssh_public_key: 6 | ssh_private_key: 7 | ssh_user: centos 8 | instance_type: t2.xlarge 9 | image: 10 | region: 11 | security_group: 12 | vpc_subnet_id: 13 | assign_public_ip: yes 14 | volume_size: 50 15 | key_pair: 16 | instances: 17 | aws1: 18 | provider: aws 19 | aws2: 20 | provider: aws 21 | aws3: 22 | provider: aws 23 | global_configuration: 24 | CONTAINER_REGISTRY: michaelhenkel 25 | contrail_configuration: 26 | CONTRAIL_VERSION: queens-5.0.0-134 27 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail control image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-controller-control-control 10 | - opensdn-controller-control-named 11 | - opensdn-controller-control-dns 12 | - opensdn-provisioner 13 | when: 14 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 15 | - roles[instance_name].control is defined 16 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_config_database/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail config_database image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-external-cassandra 10 | - opensdn-external-zookeeper 11 | - opensdn-external-rabbitmq 12 | - opensdn-provisioner 13 | when: 14 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 15 | - roles[instance_name].config_database is defined 16 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_snmp/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail-snmp-collector and contrail-analytics-snmp-topology image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-analytics-snmp-topology 10 | - opensdn-analytics-snmp-collector 11 | - opensdn-provisioner 12 | when: 13 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 14 | - roles[instance_name].analytics_snmp is defined 15 | -------------------------------------------------------------------------------- /playbooks/roles/kvm_deployer/tasks/get_container_hosts.yml: -------------------------------------------------------------------------------- 1 | - debug: 2 | msg: "{{ kvm_host_dict }}" 3 | 4 | - debug: 5 | msg: "{{ kvm_item.key }}" 6 | with_dict: "{{ kvm_host_dict }}" 7 | loop_control: 8 | loop_var: kvm_item 9 | 10 | - name: create container host dicts 11 | set_fact: 12 | container_host_dict: "{{ container_host_dict|default({})|combine({item.key: item.value.ip}) }}" 13 | 14 | - name: add container hosts to kvm dict 15 | set_fact: 16 | kvm_container_host_dict: "{{ kvm_item.value + [ 'bla' ] }}" 17 | when: kvm_item.key == item.value.host 18 | with_dict: "{{ kvm_host_dict }}" 19 | loop_control: 20 | loop_var: kvm_item 21 | -------------------------------------------------------------------------------- /playbooks/roles/destroy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: find all directories 3 | find: 4 | path: /etc/contrail 5 | file_type: directory 6 | register: dir_out 7 | 8 | - name: skip invalid dir which doesn't have compose file 9 | stat: 10 | path: "{{ item.path }}/docker-compose.yaml" 11 | register: rc 12 | with_items: "{{ dir_out.files }}" 13 | 14 | - docker_compose: 15 | project_src: "{{ item.item.path }}" 16 | state: absent 17 | remove_images: all 18 | remove_volumes: yes 19 | environment: 20 | DOCKER_CLIENT_TIMEOUT: '120' 21 | COMPOSE_HTTP_TIMEOUT: '120' 22 | with_items: "{{ rc.results }}" 23 | when: item.stat.exists == true 24 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: split k8s_version by dots 4 | set_fact: 5 | k8s_repo_version: "{{ k8s_version.split('.') }}" 6 | 7 | - name: add k8s repo key 8 | shell: | 9 | curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --batch --yes --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg 10 | when: k8s_package_version is defined 11 | 12 | - name: create k8s repo 13 | apt_repository: 14 | repo: "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v{{ k8s_repo_version[0] }}.{{ k8s_repo_version[1] }}/deb/ /" 15 | state: present 16 | when: k8s_package_version is defined 17 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn/tasks/common_Linux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /var/log/contrail 3 | file: 4 | path: /var/log/contrail 5 | state: directory 6 | recurse: yes 7 | tags: 8 | - always 9 | 10 | - name: create /etc/contrail/compose 11 | file: 12 | path: /etc/contrail/compose 13 | state: directory 14 | recurse: yes 15 | tags: 16 | - always 17 | 18 | - name: populate common.env 19 | template: 20 | src: common.env.j2 21 | dest: /etc/contrail/common.env 22 | mode: "0640" 23 | tags: 24 | - always 25 | 26 | - name: populate defaults.env 27 | template: 28 | src: defaults.env.j2 29 | dest: /etc/contrail/defaults.env 30 | tags: 31 | - always 32 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_redis/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/redis 3 | file: 4 | path: /etc/contrail/redis 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "Set variables for Stunnel" 9 | set_fact: 10 | redis_ssl_enable: "{{ contrail_configuration.REDIS_SSL_ENABLE | default(contrail_configuration.SSL_ENABLE | default('no')) | bool }}" 11 | 12 | - name: "create redis compose file" 13 | template: 14 | src: contrail-redis.yaml.j2 15 | dest: "/etc/contrail/redis/docker-compose.yaml" 16 | 17 | - name: "start redis" 18 | docker_compose: 19 | project_src: /etc/contrail/redis 20 | environment: 21 | DOCKER_CLIENT_TIMEOUT: '120' 22 | COMPOSE_HTTP_TIMEOUT: '120' 23 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_config/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: update contrail config image 2 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 3 | register: res 4 | retries: 5 5 | until: res.rc == 0 6 | with_items: 7 | - opensdn-node-init 8 | - opensdn-nodemgr 9 | - opensdn-controller-config-api 10 | - opensdn-controller-config-svcmonitor 11 | - opensdn-controller-config-schema 12 | - opensdn-controller-config-devicemgr 13 | - opensdn-controller-config-dnsmasq 14 | - opensdn-provisioner 15 | when: 16 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 17 | - roles[instance_name].config is defined 18 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn/tasks/delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: delete contrail toragent 3 | include_role: 4 | name: opensdn_toragent 5 | tasks_from: delete 6 | vars: 7 | - toragent_config: "{{ toragent_dict }}" 8 | with_items: "{{ node_roles_dict[instance_name].deleted_roles }}" 9 | loop_control: 10 | loop_var: toragent_dict 11 | when: 12 | - instance_name in node_roles_dict 13 | - (toragent_dict != 'vrouter' ) 14 | - ansible_system == 'Linux' 15 | 16 | - name: delete contrail vrouter 17 | include_role: 18 | name: opensdn_vrouter 19 | tasks_from: delete 20 | when: 21 | - instance_name in node_roles_dict 22 | - ('vrouter' in node_roles_dict[instance_name].deleted_roles) 23 | - ansible_system == 'Linux' 24 | tags: 25 | - vrouter 26 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_redis/templates/contrail-redis.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | redis: 4 | image: "{{ container_registry }}/opensdn-external-redis:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common.env 6 | network_mode: "host" 7 | restart: always 8 | 9 | {% if redis_ssl_enable %} 10 | stunnel: 11 | image: "{{ container_registry }}/opensdn-external-stunnel:{{ contrail_version_tag }}" 12 | env_file: /etc/contrail/common.env 13 | network_mode: "host" 14 | restart: always 15 | logging: 16 | driver: "{{ stunnel_log_driver }}" 17 | options: 18 | max-size: "{{ stunnel_log_max_size }}" 19 | max-file: "{{ stunnel_log_max_file }}" 20 | volumes: 21 | - /etc/contrail/ssl:/etc/contrail/ssl 22 | {% endif %} 23 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn/tasks/deregister.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: deregister contrail toragent - Linux 3 | include_role: 4 | name: opensdn_toragent 5 | tasks_from: deregister 6 | vars: 7 | - toragent_config: "{{ toragent_dict }}" 8 | with_items: "{{ node_roles_dict[instance_name].deleted_roles }}" 9 | loop_control: 10 | loop_var: toragent_dict 11 | when: 12 | - instance_name in node_roles_dict 13 | - (toragent_dict != 'vrouter' ) 14 | - ansible_system == 'Linux' 15 | 16 | - name: deregister contrail vrouter - Linux 17 | include_role: 18 | name: opensdn_vrouter 19 | tasks_from: deregister 20 | vars: 21 | - delted_nodes_dict: "{{ deleted_nodes_dict }}" 22 | when: 23 | - instance_name in node_roles_dict 24 | - ansible_system == 'Linux' 25 | tags: 26 | - vrouter 27 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/templates/host_vars.yml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | {% if instance_data.roles is defined and instance_data.roles is mapping() -%} 3 | {%- set excludes = ['VROUTER_GATEWAY', 'PHYSICAL_INTERFACE', 'network_interface', 'kolla_internal_address', 'kolla_external_vip_interface', 'QOS_LOGICAL_QUEUES'] -%} 4 | {%- for role,vars in instance_data.roles.items() -%} 5 | {%- if vars is mapping() -%} 6 | {%- for a, b in vars.items() -%} 7 | {%- if a not in excludes -%} 8 | {%- print a + ': ' + b|string() + '\n' -%} 9 | {%- endif -%} 10 | {%- endfor -%} 11 | {%- endif -%} 12 | {%- endfor -%} 13 | {%- endif -%} 14 | 15 | kolla_internal_address: {{ host_internal_address }} 16 | network_interface: {{ host_internal_interface }} 17 | kolla_external_vip_interface: {{ host_external_interface }} 18 | -------------------------------------------------------------------------------- /playbooks/roles/openstack_deployer/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | openstack_role_groups: 4 | control: 5 | - openstack_control 6 | network: 7 | - openstack_network 8 | compute: 9 | - openstack_compute 10 | - vrouter 11 | monitoring: 12 | - openstack_monitoring 13 | storage: 14 | - openstack_storage 15 | 16 | openstack_role_subgroups: 17 | baremetal: 18 | - control 19 | - network 20 | - compute 21 | - storage 22 | - monitoring 23 | collectd: 24 | - compute 25 | grafana: 26 | - monitoring 27 | etcd: 28 | - control 29 | influxd: 30 | - monitoring 31 | karbor: 32 | - control 33 | kibana: 34 | - control 35 | telegraf: 36 | - compute 37 | - control 38 | - monitoring 39 | - network 40 | - storage 41 | elasticsearch: 42 | - control 43 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/files/ContrailPlugin.ini: -------------------------------------------------------------------------------- 1 | [APISERVER] 2 | api_server_port = 8082 3 | api_server_ip = 10.0.2.15 4 | multi_tenancy = True 5 | contrail_extensions = ipam:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_ipam.NeutronPluginContrailIpam,policy:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_policy.NeutronPluginContrailPolicy,route-table:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_vpc.NeutronPluginContrailVpc,contrail:None,service-interface:None,vf-binding:None 6 | 7 | [COLLECTOR] 8 | analytics_api_ip = 10.0.2.15 9 | analytics_api_port = 8081 10 | 11 | [keystone_authtoken] 12 | auth_host = 10.0.2.15 13 | auth_port = 5000 14 | auth_protocol = 'http' 15 | admin_user = admin 16 | admin_password = contrail123 17 | admin_tenant_name = admin 18 | insecure = True 19 | region_name = RegionOne 20 | 21 | -------------------------------------------------------------------------------- /playbooks/roles/openstack_deployer/tasks/cluster_node_role_lists.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - set_fact: 3 | cluster_roles_dict: {} 4 | 5 | - name: Calculate Existing Roles 6 | set_fact: 7 | cluster_roles_dict: "{{ cluster_roles_dict | calculate_openstack_roles(instances, global_configuration|default({}), contrail_configuration, kolla_config, hostvars) }}" 8 | 9 | - name: Fail if there was an Exception in getting data 10 | fail: 11 | msg: 12 | - "There was an exception when contacting the cluster:" 13 | - "{{ cluster_roles_dict['Exception'] }}" 14 | when: "'Exception' in cluster_roles_dict" 15 | 16 | - name: Calculate node roles Dict 17 | set_fact: 18 | node_roles_dict: "{{ cluster_roles_dict['node_roles_dict'] }}" 19 | 20 | - name: Calculate deleted nodes Dict 21 | set_fact: 22 | deleted_nodes_dict: "{{ cluster_roles_dict['deleted_nodes_dict'] }}" 23 | -------------------------------------------------------------------------------- /playbooks/provision_instances.yml: -------------------------------------------------------------------------------- 1 | - name: Create GCE instance(s) 2 | hosts: localhost 3 | connection: local 4 | gather_facts: no 5 | roles: 6 | - gce_deployer 7 | vars_files: 8 | - "{{ config_file }}" 9 | tags: 10 | - gce_deployer 11 | 12 | - name: Create AWS instance(s) 13 | hosts: localhost 14 | connection: local 15 | gather_facts: no 16 | roles: 17 | - aws_deployer 18 | vars_files: 19 | - "{{ config_file }}" 20 | tags: 21 | - aws_deployer 22 | 23 | - name: Create KVM instances 24 | hosts: localhost 25 | connection: local 26 | gather_facts: no 27 | roles: 28 | - kvm_deployer 29 | vars_files: 30 | - "{{ config_file }}" 31 | tags: 32 | - kvm_deployer 33 | 34 | - name: Provision KVM instances 35 | hosts: kvm_instances 36 | roles: 37 | - kvm 38 | vars_files: 39 | - "{{ hostvars['localhost'].config_file }}" 40 | tags: 41 | - kvm 42 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_compute_legacy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # run openstack-compute-init container with mounted volumes: 3 | # /usr/bin:/opt/plugin/bin 4 | # PYTHONPATH:/opt/plugin/site-packages 5 | 6 | - name: create /etc/contrail/compute-legacy 7 | file: 8 | path: /etc/contrail/compute-legacy 9 | state: directory 10 | recurse: yes 11 | 12 | - name: Getting PYTHONPATH 13 | shell: python2 -c "import sys; paths = [path for path in sys.path if 'packages' in path] ; print(paths[-1])" 14 | register: pythonpath 15 | 16 | - name: "create contrail compute-legacy compose file" 17 | template: 18 | src: contrail-compute-legacy.yaml.j2 19 | dest: "/etc/contrail/compute-legacy/docker-compose.yaml" 20 | 21 | - name: "start contrail compute-legacy" 22 | docker_compose: 23 | project_src: /etc/contrail/compute-legacy 24 | environment: 25 | DOCKER_CLIENT_TIMEOUT: '120' 26 | COMPOSE_HTTP_TIMEOUT: '120' 27 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | kolla_globals: "{{ kolla_config.kolla_globals if kolla_config.kolla_globals is defined else default_kolla_globals}}" 3 | 4 | os_nodes_storage: >- 5 | {%- set node_list = [] -%} 6 | {%- for k,v in hostvars['localhost']['instances'].items() -%} 7 | {%- if v.roles is not defined or v.roles.openstack is defined or v.roles.openstack_control is defined or v.roles.openstack_storage is defined -%} 8 | {%- if hostvars[v.ip]['ansible_' + hostvars[v.ip]['network_interface_detected']].get('ipv4',{}).get('address') -%} 9 | {{ node_list.append(hostvars[v.ip]['ansible_' + hostvars[v.ip]['network_interface_detected']].get('ipv4',{}).get('address')) | default("",True) }} 10 | {%- endif -%} 11 | {%- endif -%} 12 | {%- endfor -%} 13 | {{ node_list|join(',') }} 14 | 15 | instance_data: "{{ instances[hostvars[inventory_hostname].instance_name] }}" 16 | -------------------------------------------------------------------------------- /playbooks/roles/nova/files/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": "nova-compute --config-file /etc/nova/nova.conf --config-file /etc/nova/rootwrap.conf", 3 | "config_files": [ 4 | { 5 | "source": "/var/lib/kolla/config_files/nova.conf", 6 | "dest": "/etc/nova/nova.conf", 7 | "owner": "nova", 8 | "perm": "0600" 9 | }, 10 | { 11 | "source": "/var/lib/kolla/config_files/release", 12 | "dest": "/etc/nova/release", 13 | "owner": "nova", 14 | "perm": "0600", 15 | "optional": true 16 | } ], 17 | "permissions": [ 18 | { 19 | "path": "/var/log/kolla/nova", 20 | "owner": "nova:nova", 21 | "recurse": true 22 | }, 23 | { 24 | "path": "/var/lib/nova", 25 | "owner": "nova:nova", 26 | "recurse": true 27 | } 28 | ] 29 | } 30 | 31 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py3,pep8 3 | skipsdist = True 4 | 5 | [testenv] 6 | usedevelop = True 7 | setenv = VIRTUAL_ENV={envdir} 8 | LANG=en_US.UTF-8 9 | LANGUAGE=en_US:en 10 | LC_ALL=C 11 | deps = mock 12 | requests 13 | flake8 14 | 15 | [testenv:py3] 16 | commands = python3 unit_tests/calculate_roles.py 17 | 18 | [testenv:pep8] 19 | basepython = python3 20 | commands = 21 | flake8 {posargs} 22 | 23 | [testenv:venv] 24 | basepython = python3 25 | commands = {posargs} 26 | 27 | [flake8] 28 | # E712 is ignored on purpose, since it is normal to use 'column == true' 29 | # in sqlalchemy. 30 | # TODO Hacking 0.6 checks to fix 31 | # H102 Apache 2.0 license header not found 32 | 33 | ignore = E402,E501,W504 34 | # H106: Don't put vim configuration in source files 35 | # H203: Use assertIs(Not)None to check for None 36 | enable-extensions = H106,H203 37 | exclude = .venv,.git,.tox,dist,envname,*lib/python*,*egg 38 | max-complexity=25 39 | -------------------------------------------------------------------------------- /config/instances.yaml.kvm_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | kvm: 3 | image: CentOS-7-x86_64-GenericCloud-1710.qcow2.xz 4 | image_url: https://cloud.centos.org/centos/7/images/ 5 | ssh_pwd: 6 | ssh_user: 7 | ssh_public_key: 8 | ssh_private_key: 9 | vcpu: 12 10 | vram: 64000 11 | vdisk: 100G 12 | subnet_prefix: 192.168.1.0 13 | subnet_netmask: 255.255.255.0 14 | gateway: 192.168.1.1 15 | nameserver: 10.84.5.100 16 | ntpserver: 192.168.1.1 17 | domainsuffix: local 18 | instances: 19 | kvm1: 20 | provider: kvm 21 | host: 10.87.64.31 22 | bridge: br1 23 | ip: 192.168.1.100 24 | kvm2: 25 | provider: kvm 26 | host: 10.87.64.32 27 | bridge: br1 28 | ip: 192.168.1.101 29 | kvm3: 30 | provider: kvm 31 | host: 10.87.64.33 32 | bridge: br1 33 | ip: 192.168.1.102 34 | global_configuration: 35 | CONTAINER_REGISTRY: michaelhenkel 36 | contrail_configuration: 37 | CONTRAIL_VERSION: queens-5.0.0-134 38 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_vrouter/tasks/delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Get name of the vrouter container 3 | command: docker ps --filter name=vrouter-agent --format {%raw%}"{{.Names}}"{%endraw%} 4 | register: result_name 5 | tags: 6 | - cleanup 7 | 8 | - name: Send QUIT signal to vrouter 9 | command: 10 | docker kill -s QUIT "{{ result_name.stdout }}" 11 | when: 12 | - result_name.stdout 13 | tags: 14 | - cleanup 15 | 16 | - name: Stop and remove Vrouter Container and volumes 17 | docker_compose: 18 | project_src: /etc/contrail/vrouter 19 | state: absent 20 | remove_images: all 21 | remove_volumes: yes 22 | environment: 23 | DOCKER_CLIENT_TIMEOUT: '120' 24 | COMPOSE_HTTP_TIMEOUT: '120' 25 | when: 26 | - result_name.stdout 27 | 28 | - name: Delete all files and folders used by vrouter 29 | file: 30 | path: /etc/contrail/common_vrouter.env 31 | state: absent 32 | 33 | - file: 34 | path: /etc/contrail/vrouter/ 35 | state: absent 36 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/private_registry_Linux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # this file is parameterized 4 | # it takes 'docker_registry' as a parameter 5 | 6 | - name: get registry name 7 | set_fact: 8 | registry_name: "{{ docker_registry.split(':') }}" 9 | 10 | - name: get fqdn 11 | set_fact: 12 | fqdn_name: "{{ registry_name[0] }}" 13 | 14 | - name: create docker cert directory 15 | file: 16 | path: "{{ nix_docker_certs_directory }}/{{ docker_registry }}" 17 | state: directory 18 | 19 | - name: copy cert to docker cert directory 20 | copy: 21 | src: "{{ fqdn_name }}.crt" 22 | dest: "{{ nix_docker_certs_directory }}/{{ docker_registry }}/{{ fqdn_name }}.crt" 23 | register: docker_cert 24 | 25 | - name: copy cert to trust directory 26 | copy: 27 | src: "{{ fqdn_name }}.crt" 28 | dest: "/etc/pki/ca-trust/source/anchors//{{ fqdn_name }}.crt" 29 | register: pki_cert 30 | 31 | - name: update ca trust 32 | shell: update-ca-trust 33 | when: docker_cert.changed or pki_cert.changed 34 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/templates/ContrailPlugin.ini.j2: -------------------------------------------------------------------------------- 1 | [APISERVER] 2 | api_server_port = {{ opencontrail_api_server_port }} 3 | api_server_ip = {{ opencontrail_api_server_ip }} 4 | multi_tenancy = True 5 | contrail_extensions = ipam:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_ipam.NeutronPluginContrailIpam,policy:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_policy.NeutronPluginContrailPolicy,route-table:neutron_plugin_contrail.plugins.opencontrail.contrail_plugin_vpc.NeutronPluginContrailVpc,contrail:None,service-interface:None,vf-binding:None 6 | 7 | [COLLECTOR] 8 | analytics_api_ip = {{ opencontrail_collector_ip.split(' ')[0] }} 9 | analytics_api_port = {{ opencontrail_collector_port }} 10 | 11 | [keystone_authtoken] 12 | auth_host = {{ opencontrail_api_server_ip }} 13 | auth_port = {{ contrail_plugin_keystone_port }} 14 | auth_protocol = '{{ contrail_plugin_internal_protocol }}' 15 | admin_user = admin 16 | admin_password = contrail123 17 | admin_tenant_name = admin 18 | insecure = True 19 | region_name = RegionOne 20 | -------------------------------------------------------------------------------- /config/instances.yaml.xflow_single_node: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: c0ntrail123 4 | ssh_user: root 5 | ntpserver: 10.84.5.100 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 10.84.13.36 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | analytics_snmp: 18 | analytics_alarm: 19 | webui: 20 | vrouter: 21 | openstack: 22 | openstack_compute: 23 | appformix_flows: 24 | contrail_configuration: 25 | AUTH_MODE: keystone 26 | KEYSTONE_AUTH_URL_VERSION: /v3 27 | CONTRAIL_VERSION: master-835 28 | global_configuration: 29 | CONTAINER_REGISTRY: ci-repo.englab.juniper.net:5010 30 | REGISTRY_PRIVATE_INSECURE: True 31 | kolla_config: 32 | kolla_globals: 33 | enable_haproxy: no 34 | enable_ironic: "no" 35 | enable_swift: "no" 36 | kolla_passwords: 37 | keystone_admin_password: c0ntrail123 38 | xflow_configuration: 39 | loadbalancer_collector_vip: 10.84.13.37 40 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/tasks/restart_containers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart neutron_server container 4 | shell: "sudo docker restart neutron_server" 5 | no_log: false 6 | ignore_errors: true 7 | args: 8 | chdir: "{{ role_path }}" 9 | 10 | - name: delete metadata_container 11 | shell: "sudo docker rm -f neutron_metadata_agent" 12 | no_log: false 13 | ignore_errors: true 14 | args: 15 | chdir: "{{ role_path }}" 16 | run_once: true 17 | 18 | - name: delete l3 container 19 | shell: "sudo docker rm -f neutron_l3_agent" 20 | no_log: false 21 | ignore_errors: true 22 | args: 23 | chdir: "{{ role_path }}" 24 | run_once: true 25 | 26 | - name: delete dhcp container 27 | shell: "sudo docker rm -f neutron_dhcp_agent" 28 | no_log: false 29 | ignore_errors: true 30 | args: 31 | chdir: "{{ role_path }}" 32 | run_once: true 33 | 34 | - name: delete openvswitch container 35 | shell: "sudo docker rm -f neutron_openvswitch_agent" 36 | no_log: false 37 | ignore_errors: true 38 | args: 39 | chdir: "{{ role_path }}" 40 | run_once: true 41 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_kubemanager/templates/contrail-kubemanager.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | kubemanager: 14 | image: "{{ container_registry }}/opensdn-kubernetes-kube-manager:{{ contrail_version_tag }}" 15 | network_mode: host 16 | environment: 17 | - K8S_TOKEN={{ hostvars[k8s_master_name].kubemanagertoken }} 18 | env_file: /etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env 19 | volumes_from: 20 | - node-init 21 | depends_on: 22 | - node-init 23 | restart: always 24 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 25 | tty: {{ contrail_configuration.TTY }} 26 | -------------------------------------------------------------------------------- /playbooks/roles/instance/tasks/ntp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install ntp packages 3 | package: 4 | name: 5 | - ntpdate 6 | - ntp 7 | state: latest 8 | register: res 9 | retries: 5 10 | until: res is success 11 | 12 | - name: set ntp service name 13 | set_fact: 14 | ntp_svc_name: "{{ 'ntp' if ansible_os_family == 'Debian' else 'ntpd' }}" 15 | 16 | - name: stop ntp service 17 | service: name={{ ntp_svc_name }} state=stopped enabled=yes 18 | 19 | - name: set ntp server 20 | template: 21 | src: ntp.conf.j2 22 | dest: /etc/ntp.conf 23 | 24 | - name: initial time sync 25 | shell: "ntpdate {{ provider_data.ntpserver }}" 26 | ignore_errors: yes 27 | 28 | - name: start ntp service 29 | service: name={{ ntp_svc_name }} state=started enabled=yes 30 | 31 | # centos(redhat?) uses chronyd by default and run it after restart instead of ntpd 32 | # service can be absent - so ignore it 33 | - name: disable service chronyd 34 | systemd: 35 | name: chronyd 36 | enabled: no 37 | ignore_errors: yes 38 | when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' 39 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_win_no_openstack_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: Contrail123! 4 | ssh_user: root 5 | domainsuffix: example.com 6 | 7 | bms_win: 8 | ansible_user: Administrator 9 | ansible_password: Contrail123! 10 | domainsuffix: example.com 11 | 12 | instances: 13 | ctrl: 14 | provider: bms 15 | ip: 192.168.1.100 16 | roles: 17 | config_database: 18 | config: 19 | control: 20 | analytics_database: 21 | analytics: 22 | webui: 23 | 24 | win_compute1: 25 | provider: bms_win 26 | ip: 192.168.1.101 27 | roles: 28 | vrouter: 29 | win_cnm_plugin: 30 | 31 | win_compute2: 32 | provider: bms_win 33 | ip: 192.168.1.102 34 | roles: 35 | vrouter: 36 | win_cnm_plugin: 37 | 38 | global_configuration: 39 | CONTAINER_REGISTRY: opensdn 40 | 41 | contrail_configuration: 42 | CLOUD_ORCHESTRATOR: none 43 | CONTRAIL_VERSION: latest 44 | #CONTROL_NODES: 172.0.0.100 45 | WINDOWS_PHYSICAL_INTERFACE: Ethernet1 46 | WINDOWS_ENABLE_TEST_SIGNING: 47 | WINDOWS_DEBUG_DLLS_PATH: ~/dlls 48 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create docker repo 3 | yum_repository: 4 | name: dockerrepo 5 | description: Docker Repository 6 | baseurl: https://download.docker.com/linux/centos/7/$basearch/stable 7 | gpgkey: https://download.docker.com/linux/centos/gpg 8 | gpgcheck: yes 9 | when: docker_mirror_url is not defined 10 | 11 | - name: configure docker mirror 12 | yum_repository: 13 | name: docker_mirror 14 | description: Docker Mirror 15 | baseurl: '{{ docker_mirror_url }}' 16 | gpgcheck: no 17 | when: docker_mirror_url is defined 18 | 19 | # docker-ce-18 requries pigz which is available starting from rhel8 20 | # so, use epel 21 | - name: configure epel 22 | yum: 23 | name: https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm 24 | when: ansible_distribution_major_version|int < 8 25 | register: res 26 | retries: 5 27 | until: res is success 28 | 29 | - name: install docker 30 | yum: 31 | name: docker-ce-18.03.1.ce 32 | register: res 33 | retries: 5 34 | until: res is success 35 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_alarm/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/analytics_alarm 3 | file: 4 | path: /etc/contrail/analytics_alarm 5 | state: directory 6 | recurse: yes 7 | 8 | - name: set zookeeper nodes to CONFIGDB_NODES if defined 9 | set_fact: 10 | zookeeper_nodes: "{{ contrail_configuration.CONFIGDB_NODES }}" 11 | when: contrail_configuration.CONFIGDB_NODES is defined 12 | 13 | - name: set zookeeper nodes to CONTROLLER_NODES if CONFIGDB_NODES not defined 14 | set_fact: 15 | zookeeper_nodes: "{{ contrail_configuration.CONTROLLER_NODES }}" 16 | when: contrail_configuration.CONTROLLER_NODES is defined and contrail_configuration.CONFIGDB_NODES is undefined 17 | 18 | - name: create contrail analytics_alarm docker-compose file 19 | template: 20 | src: contrail-analytics-alarm.yaml.j2 21 | dest: /etc/contrail/analytics_alarm/docker-compose.yaml 22 | 23 | - name: start contrail analytics_alarm 24 | docker_compose: 25 | project_src: /etc/contrail/analytics_alarm 26 | environment: 27 | DOCKER_CLIENT_TIMEOUT: '120' 28 | COMPOSE_HTTP_TIMEOUT: '120' 29 | -------------------------------------------------------------------------------- /playbooks/roles/nova/files/rootwrap.conf: -------------------------------------------------------------------------------- 1 | # Configuration for nova-rootwrap 2 | # This file should be owned by (and only-writeable by) the root user 3 | 4 | [DEFAULT] 5 | # List of directories to load filter definitions from (separated by ','). 6 | # These directories MUST all be only writeable by root ! 7 | filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap 8 | 9 | # List of directories to search executables in, in case filters do not 10 | # explicitly specify a full path (separated by ',') 11 | # If not specified, defaults to system PATH environment variable. 12 | # These directories MUST all be only writeable by root ! 13 | exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/sbin,/usr/local/bin,/opt/plugin/bin 14 | 15 | # Enable logging to syslog 16 | # Default value is False 17 | use_syslog=False 18 | 19 | # Which syslog facility to use. 20 | # Valid values include auth, authpriv, syslog, local0, local1... 21 | # Default value is 'syslog' 22 | syslog_log_facility=syslog 23 | 24 | # Which messages to log. 25 | # INFO means log all usage 26 | # ERROR means only log unsuccessful attempts 27 | syslog_log_level=ERROR 28 | 29 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_master/templates/contrail-kubemanager-serviceaccount.yaml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | kind: Namespace 3 | apiVersion: v1 4 | metadata: 5 | name: contrail 6 | --- 7 | kind: ClusterRole 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | metadata: 10 | name: contrail-kubemanager 11 | namespace: contrail 12 | rules: 13 | - apiGroups: ["*"] 14 | resources: ["*"] 15 | verbs: ["*"] 16 | --- 17 | apiVersion: v1 18 | kind: ServiceAccount 19 | metadata: 20 | name: contrail-kubemanager 21 | namespace: contrail 22 | --- 23 | apiVersion: rbac.authorization.k8s.io/v1 24 | kind: ClusterRoleBinding 25 | metadata: 26 | name: contrail-kubemanager 27 | roleRef: 28 | apiGroup: rbac.authorization.k8s.io 29 | kind: ClusterRole 30 | name: contrail-kubemanager 31 | subjects: 32 | - kind: ServiceAccount 33 | name: contrail-kubemanager 34 | namespace: contrail 35 | --- 36 | apiVersion: v1 37 | kind: Secret 38 | metadata: 39 | name: contrail-kubemanager-token 40 | namespace: contrail 41 | annotations: 42 | kubernetes.io/service-account.name: contrail-kubemanager 43 | type: kubernetes.io/service-account-token 44 | --- -------------------------------------------------------------------------------- /config/instances.yaml.ml2.bms_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: 4 | ssh_user: 5 | ssh_public_key: 6 | ssh_private_key: 7 | ntpserver: 192.168.1.1 8 | domainsuffix: local 9 | 10 | instances: 11 | contrail-bms-server: 12 | provider: bms 13 | ip: 192.168.1.101 14 | roles: 15 | config_database: 16 | config: 17 | control: 18 | analytics_database: 19 | analytics: 20 | analytics_snmp: 21 | analytics_alarm: 22 | webui: 23 | 24 | openstack-control-bms-server: 25 | provider: bms 26 | ip: 192.168.1.102 27 | roles: 28 | openstack_control: 29 | 30 | openstack-compute-bms-server: 31 | provider: bms 32 | ip: 192.168.1.103 33 | roles: 34 | openstack_compute: 35 | 36 | global_configuration: 37 | CONTAINER_REGISTRY: opensdn 38 | 39 | contrail_configuration: 40 | CONTRAIL_VERSION: latest 41 | 42 | kolla_globals: 43 | neutron_plugin_agent: opencontrail-ml2 44 | enable_opencontrail_rbac: no 45 | contrail_dm_integration: True 46 | neutron_type_drivers: "local,vlan,gre,vxlan" 47 | neutron_tenant_network_types: "local,vlan" -------------------------------------------------------------------------------- /README_ziu.md: -------------------------------------------------------------------------------- 1 | # ZIU Ansible 2 | Sequence of steps to perform Zero impact upgrade unsing ansible: 3 | 1. Upgrade contrail_container_tag in instances.yaml to set proper version of contrail 4 | 2. Run `controller` stage of `ziu.yml` playbook to upgrade the control plane: 5 | ```sh 6 | sudo -E ansible-playbook -v -e stage=controller -e orchestrator=openstack -e config_file=../instances.yaml playbooks/ziu.yml 7 | ``` 8 | 3. Run `openstack` stage of `ziu.yml` playbook to upgrade openstack plugin 9 | ```sh 10 | sudo -E ansible-playbook -v -e stage=openstack -e orchestrator=openstack -e config_file=../instances.yaml playbooks/ziu.yml 11 | ``` 12 | 4. Run opensdn-status to check all works well 13 | 5. Migrate workloads VM from one group of compute nodes. Leave them uncommented in the instances.yaml. Comment other computes not ready to upgrаde in instances.yaml. 14 | 6. Run `compute` stage of `ziu.yml` playbook to upgrade compute nodes (group that uncommented in instances.yml). 15 | ```sh 16 | sudo -E ansible-playbook -v -e stage=compute -e orchestrator=openstack -e config_file=../instances.yaml playbooks/ziu.yml 17 | ``` 18 | 7. Repeat steps 5 and 6 for all groups of compute nodes -------------------------------------------------------------------------------- /playbooks/roles/haproxy/templates/haproxy.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/tsn_haproxy.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | tsn_haproxy: 14 | image: "{{ container_registry }}/opensdn-external-haproxy:{{ contrail_version_tag }}" 15 | env_file: /etc/contrail/tsn_haproxy.env 16 | network_mode: "host" 17 | privileged: true 18 | volumes: 19 | - /etc/contrail/ssl:/etc/contrail/ssl 20 | - /etc/hosts:/etc/hosts 21 | depends_on: 22 | - node-init 23 | restart: always 24 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 25 | tty: {{ contrail_configuration.TTY }} 26 | logging: 27 | driver: "{{ control_log_driver }}" 28 | options: 29 | max-size: "{{ control_log_max_size }}" 30 | max-file: "{{ control_log_max_file }}" 31 | -------------------------------------------------------------------------------- /playbooks/roles/kvm_deployer/tasks/combine_kvm_container_hosts.yml: -------------------------------------------------------------------------------- 1 | - set_fact: 2 | tmp_list: [] 3 | - name: create_tmp_list 4 | set_fact: 5 | tmp_list: "{{ tmp_list + [ container_host_item ] }}" 6 | when: container_host_item.value.host == item.key 7 | with_dict: "{{ container_host_dict }}" 8 | loop_control: 9 | loop_var: container_host_item 10 | 11 | - set_fact: 12 | tmp_dict: {} 13 | - name: create_tmp_dict 14 | set_fact: 15 | # tmp_dict: "{{ tmp_dict | combine({container_host_item.key: container_host_item.value}) }}" 16 | tmp_dict: "{{ tmp_dict | combine({container_host_item.key:instances[container_host_item.key]}) }}" 17 | when: container_host_item.value.host == item.key 18 | with_dict: "{{ container_host_dict }}" 19 | loop_control: 20 | loop_var: container_host_item 21 | 22 | - debug: 23 | msg: "{{ tmp_dict }}" 24 | 25 | - name: create kvm_container host list 26 | set_fact: 27 | kvm_host_dict: "{{ kvm_host_dict|default({})|combine({item.key: tmp_dict}) }}" 28 | when: container_host_item.value.host == item.key 29 | with_dict: "{{ container_host_dict }}" 30 | loop_control: 31 | loop_var: container_host_item 32 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/tasks/kolla_baremetal.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure sudo group is present 3 | group: 4 | name: sudo 5 | state: present 6 | become: True 7 | 8 | - name: Ensure kolla group is present 9 | group: 10 | name: kolla 11 | state: present 12 | become: True 13 | 14 | - name: Create kolla user 15 | user: 16 | name: kolla 17 | state: present 18 | group: kolla 19 | groups: "sudo" 20 | become: True 21 | 22 | - name: Grant kolla user passwordless sudo 23 | lineinfile: 24 | dest: /etc/sudoers 25 | state: present 26 | regexp: '^kolla' 27 | line: 'kolla ALL=(ALL) NOPASSWD: ALL' 28 | become: True 29 | no_log: True 30 | 31 | - name: Packages needed for swift 32 | package: 33 | name: "{{ item }}" 34 | state: present 35 | with_items: 36 | - parted 37 | - xfsprogs 38 | when: 39 | - kolla_globals.enable_swift | default('yes') | bool 40 | register: res 41 | retries: 5 42 | until: res is success 43 | 44 | - name: Install configfs module needed for ironic on Debian hosts 45 | modprobe: 46 | name: configfs 47 | state: present 48 | when: ansible_os_family == 'Debian' 49 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/defaults/main.yml: -------------------------------------------------------------------------------- 1 | supported_orchestrators: 2 | - openstack 3 | - kubernetes 4 | - none 5 | contrail_configuration_keystone_default: 6 | KEYSTONE_AUTH_ADMIN_TENANT: admin 7 | KEYSTONE_AUTH_ADMIN_USER: admin 8 | opencontrail_api_server_ip: "{{ contrail_configuration.CONFIG_NODES | default(contrail_configuration.CONTROLLER_NODES | default(config_nodes_list | join(','))) | replace (',', ' ') }}" 9 | opencontrail_collector_ip: "{{ contrail_configuration.ANALYTICS_NODES | default(contrail_configuration.CONTROLLER_NODES | default(analytics_nodes_list | join(','))) | replace (',', ' ') }}" 10 | KEYSTONE_AUTH_PROTO: http 11 | KEYSTONE_AUTH_PUBLIC_PORT: 5000 12 | ANALYTICS_API_PORT: 8081 13 | CONFIG_API_PORT: 8082 14 | default_openstack_version: yoga 15 | openstack_version: >- 16 | {%- if contrail_configuration.OPENSTACK_VERSION is defined -%} 17 | {{ contrail_configuration.OPENSTACK_VERSION }} 18 | {%- elif kolla_config.kolla_globals is defined and kolla_config.kolla_globals.openstack_release is defined -%} 19 | {{ kolla_config.kolla_globals.openstack_release }} 20 | {%- else -%} 21 | {{ default_openstack_version }} 22 | {%- endif %} 23 | -------------------------------------------------------------------------------- /examples/aws/contrail_with_k8s.yaml: -------------------------------------------------------------------------------- 1 | provider_config: 2 | aws: 3 | ec2_access_key: "${ACCESS_KEY}" 4 | ec2_secret_key: "${SECRET_KEY}" 5 | ssh_public_key: /root/.ssh/id_rsa.pub 6 | ssh_private_key: /root/.ssh/id_rsa 7 | ssh_user: centos 8 | instance_type: "${INSTANCE_TYPE}" 9 | image: "${IMAGE_ID}" 10 | region: "${REGION}" 11 | security_group: "${SECURITY_GROUP}" 12 | vpc_subnet_id: "${SUBNET}" 13 | assign_public_ip: yes 14 | volume_size: 50 15 | key_pair: "contrail-${STACK_NAME}" 16 | instances: 17 | ${STACK_NAME}_contrail_control1: 18 | provider: aws 19 | roles: 20 | config_database: 21 | config: 22 | control: 23 | analytics_database: 24 | analytics: 25 | webui: 26 | kubemanager: 27 | ${STACK_NAME}_k8s_control: 28 | provider: aws 29 | roles: 30 | k8s_master: 31 | ${STACK_NAME}_k8s_compute1: 32 | provider: aws 33 | roles: 34 | vrouter: 35 | k8s_node: 36 | ${STACK_NAME}_k8s_compute2: 37 | provider: aws 38 | roles: 39 | vrouter: 40 | k8s_node: 41 | contrail_configuration: 42 | CONTAINER_REGISTRY: opensdn 43 | CONTRAIL_VERSION: latest 44 | UPGRADE_KERNEL: true 45 | -------------------------------------------------------------------------------- /playbooks/roles/kvm/templates/virt-install.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | virt-install --name {{ container_vm_hostname }} \ 3 | --disk /var/lib/libvirt/images/{{ container_vm_hostname }}.qcow2 \ 4 | --cpu host-passthrough \ 5 | --vcpus={{ vcpu }} \ 6 | --ram={{ vram }} \ 7 | {% if item.value.port_group is defined %} 8 | --network network={{ item.value.bridge }},model=virtio,portgroup={{ item.value.port_group }} \ 9 | {% else %} 10 | --network network={{ item.value.bridge }},model=virtio \ 11 | {% endif %} 12 | {% if item.value.additional_interfaces is defined %} 13 | {% for additional_interface in item.value.additional_interfaces %} 14 | {% if additional_interface.bridge is defined %} 15 | {% if additional_interface.port_group is defined %} 16 | --network network={{ additional_interface.bridge }},model=virtio,portgroup={{ additional_interface.port_group }} \ 17 | {% else %} 18 | --network network={{ additional_interface.bridge }},model=virtio \ 19 | {% endif %} 20 | {% endif %} 21 | {% endfor %} 22 | {% else %} 23 | --network network=default,model=virtio \ 24 | {% endif %} 25 | --virt-type kvm \ 26 | --import \ 27 | --os-variant rhel7 \ 28 | --graphics vnc \ 29 | --serial pty \ 30 | --noautoconsole \ 31 | --console pty,target_type=virtio 32 | -------------------------------------------------------------------------------- /config/instances.yaml.xflow_multi_node: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: c0ntrail123 4 | ssh_user: root 5 | ntpserver: 10.84.5.100 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 10.84.13.36 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | analytics_snmp: 18 | analytics_alarm: 19 | webui: 20 | vrouter: 21 | openstack: 22 | openstack_compute: 23 | appformix_flows: 24 | bms2: 25 | provider: bms 26 | ip: 10.84.13.35 27 | roles: 28 | compute: 29 | openstack_compute: 30 | appformix_flows: 31 | contrail_configuration: 32 | AUTH_MODE: keystone 33 | KEYSTONE_AUTH_URL_VERSION: /v3 34 | CONTRAIL_VERSION: master-835 35 | global_configuration: 36 | CONTAINER_REGISTRY: ci-repo.englab.juniper.net:5010 37 | REGISTRY_PRIVATE_INSECURE: True 38 | kolla_config: 39 | kolla_globals: 40 | enable_haproxy: no 41 | enable_ironic: "no" 42 | enable_swift: "no" 43 | kolla_passwords: 44 | keystone_admin_password: c0ntrail123 45 | xflow_configuration: 46 | loadbalancer_collector_vip: 10.84.13.37 47 | 48 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/configure_k8s_join_node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: initialize node_exists with false 3 | set_fact: 4 | node_exists: false 5 | 6 | - name: check if node already exists 7 | set_fact: 8 | node_exists: true 9 | when: ansible_hostname.lower() in hostvars[k8s_master_name].node_list 10 | 11 | - name: get listen interface 12 | shell: ip route get {{ k8s_master_ip }} | grep -o "dev.*" | awk '{print $2}' 13 | register: listen_nic 14 | 15 | - name: get listen ip 16 | set_fact: 17 | listen_ip: "{{ hostvars[inventory_hostname]['ansible_%s' % listen_nic.stdout].ipv4.address }}" 18 | when: listen_nic is defined 19 | 20 | - name: Configure kubelet 21 | include_tasks: configure_kubelet.yml 22 | 23 | - name: enable kubelet service 24 | systemd: 25 | name: kubelet 26 | state: restarted 27 | daemon_reload: yes 28 | enabled: True 29 | when: node_exists == false 30 | 31 | - name: debug join 32 | debug: 33 | msg: "master token: {{ hostvars[k8s_master_name].mastertoken }}" 34 | 35 | - name: join k8s cluster 36 | shell: "kubeadm join --token {{ hostvars[k8s_master_name].mastertoken }} --discovery-token-unsafe-skip-ca-verification {{ k8s_master_ip }}:6443" 37 | when: node_exists == false 38 | -------------------------------------------------------------------------------- /playbooks/roles/pip/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # NOTE: Do not use easy_install for RedHat. There is a bug that might cause 4 | # easy_install to hang: 5 | # https://github.com/ansible/ansible/issues/15769 6 | # https://bugzilla.redhat.com/show_bug.cgi?id=1702797 7 | # Use shell to intall pip for RedHat to work around the bug 8 | 9 | - name: check if pip present 10 | shell: python3 -m pip --version 11 | ignore_errors: true 12 | register: pip_check 13 | 14 | - name: Install pip 15 | block: 16 | - name: Download pip 17 | get_url: 18 | url: "{{ get_pip_url }}" 19 | dest: /tmp/get-pip.py 20 | force: yes 21 | mode: 0400 22 | - name: Install pip 23 | shell: "python3 /tmp/get-pip.py" 24 | become: yes 25 | when: 26 | - pip_check.rc != 0 27 | 28 | # if pip was already there then it should be updated if it's version is less than 10.0 29 | # (it doesn't support python2/3 metadata) 30 | - name: upgrade pip 31 | shell: python3 -m pip install --upgrade 'pip>=20' 32 | become: yes 33 | register: res 34 | retries: 5 35 | until: res is success 36 | environment: 37 | PIP_BREAK_SYSTEM_PACKAGES: 1 38 | when: 39 | - ansible_distribution != 'Ubuntu' or ansible_distribution_version != '24.04' 40 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/create_k8s_dashboard.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create k8s dashboard manifest 3 | template: 4 | src: k8s-dashboard.yaml.j2 5 | dest: /tmp/k8s-dashboard.yaml.j2 6 | 7 | - name: start k8s dashboard 8 | shell: kubectl apply -f /tmp/k8s-dashboard.yaml.j2 9 | 10 | - name: look for a privileged token for full k8s dashboard access 11 | shell: kubectl -n kube-system get secret | grep namespace-controller-token | awk '{print $1}' 12 | register: privileged_token_output 13 | 14 | - name: setting custom k8s dashboard token file 15 | set_fact: 16 | k8s_dashboard_token_path: "{{ global_configuration.K8S_DASHBORD_TOKEN_PATH }}" 17 | when: global_configuration.K8S_DASHBORD_TOKEN_PATH is defined 18 | 19 | - name: setting default k8s dashboard token file 20 | set_fact: 21 | k8s_dashboard_token_path: "/root/k8s_dashboard_token.txt" 22 | when: global_configuration.K8S_DASHBORD_TOKEN_PATH is undefined 23 | 24 | - name: printing token file path 25 | debug: 26 | msg: "{{ k8s_dashboard_token_path }}" 27 | 28 | - name: store privileged token for full k8s dashboard access 29 | shell: kubectl describe secret {{ privileged_token_output.stdout }} -n kube-system | grep "token:" | awk '{print $2}' > {{ k8s_dashboard_token_path }} 30 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/generate_ca.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: install openssl tools 3 | package: 4 | name: openssl 5 | state: present 6 | register: res 7 | retries: 5 8 | until: res is success 9 | 10 | - name: create certs directories 11 | become: yes 12 | file: 13 | state: directory 14 | path: "{{ item.dir }}" 15 | mode: "{{ item.mode }}" 16 | with_items: 17 | - dir: "{{ certs_dir }}" 18 | mode: "0755" 19 | - dir: "{{ private_keys_dir }}" 20 | mode: "0700" 21 | 22 | - name: set openssl config file path 23 | set_fact: 24 | contrail_openssl_config: "{{ ssl_dir }}/contrail_openssl.cfg" 25 | 26 | - name: "create contrail openssl config file" 27 | template: 28 | src: contrail_openssl.cfg.j2 29 | dest: "{{ contrail_openssl_config }}" 30 | 31 | - name: prepare working files for cert generation 32 | shell: "touch {{ ssl_dir }}/index.txt {{ ssl_dir }}/index.txt.attr && echo 01 > {{ ssl_dir }}/serial.txt" 33 | 34 | - name: generate CA private key 35 | shell: "openssl genrsa -out {{ root_ca_key }} 4096 && chmod 0600 {{ root_ca_key }}" 36 | 37 | - name: generate CA 38 | shell: "openssl req -config {{ contrail_openssl_config }} -days 365 -new -x509 -extensions v3_ca -key {{ root_ca_key }} -out {{ root_ca }}" 39 | -------------------------------------------------------------------------------- /playbooks/contrail_destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create container host group for Contrail destroyer 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | pre_tasks: 7 | - name: Expose instances 8 | set_fact: 9 | instances: "{{ instances }}" 10 | when: hostvars['localhost']['instances'] is undefined 11 | - name: Expose global configuration 12 | set_fact: 13 | global_configuration: "{{ global_configuration | default({}) }}" 14 | when: hostvars['localhost']['global_configuration'] is undefined 15 | - name: Expose remote_locations configuration 16 | set_fact: 17 | remote_locations: "{{ remote_locations | default({}) }}" 18 | when: hostvars['localhost']['remote_locations'] is undefined 19 | - name: Expose provider config 20 | set_fact: 21 | provider_config: "{{ provider_config | default({}) }}" 22 | when: hostvars['localhost']['provider_config'] is undefined 23 | roles: 24 | - opensdn_deployer 25 | vars_files: 26 | - "{{ config_file }}" 27 | 28 | - name: Apply role destroy to Contrail 29 | hosts: container_hosts 30 | roles: 31 | - destroy 32 | vars: 33 | - instances: "{{ hostvars['localhost'].instances }}" 34 | - roles: "{{ hostvars['localhost'].roles }}" 35 | 36 | -------------------------------------------------------------------------------- /playbooks/roles/nova/tasks/restart_containers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: restart nova_compute container 4 | shell: "sudo docker restart nova_compute" 5 | no_log: false 6 | ignore_errors: true 7 | args: 8 | chdir: "/tmp/" 9 | 10 | - name: restart nova_libvirt container 11 | shell: "sudo docker restart nova_libvirt" 12 | no_log: false 13 | ignore_errors: true 14 | args: 15 | chdir: "/tmp/" 16 | 17 | - name: restart nova_ssh container 18 | shell: "sudo docker restart nova_ssh" 19 | no_log: false 20 | ignore_errors: true 21 | args: 22 | chdir: "/tmp/" 23 | 24 | - name: restart nova_novncproxy container 25 | shell: "sudo docker restart nova_novncproxy" 26 | no_log: false 27 | ignore_errors: true 28 | args: 29 | chdir: "/tmp/" 30 | 31 | - name: restart nova_conductor container 32 | shell: "sudo docker restart nova_conductor" 33 | no_log: false 34 | ignore_errors: true 35 | args: 36 | chdir: "/tmp/" 37 | 38 | - name: restart nova_api container 39 | shell: "sudo docker restart nova_api" 40 | no_log: false 41 | ignore_errors: true 42 | args: 43 | chdir: "/tmp/" 44 | 45 | - name: restart nova_scheduler container 46 | shell: "sudo docker restart nova_scheduler" 47 | no_log: false 48 | ignore_errors: true 49 | args: 50 | chdir: "/tmp/" 51 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/cluster_node_role_lists.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - set_fact: 3 | cluster_roles_dict: {} 4 | 5 | - name: Calculate Existing Roles 6 | set_fact: 7 | cluster_roles_dict: "{{ cluster_roles_dict | calculate_opensdn_roles(config_nodes_list, instances, global_configuration, contrail_configuration, kolla_config | default(None), hostvars) }}" 8 | 9 | - name: build deleted toragent roles 10 | set_fact: 11 | cluster_roles_dict: "{{ cluster_roles_dict | calculate_deleted_toragent_roles(item) }}" 12 | with_dict: "{{ instances }}" 13 | when: 14 | - global_configuration.ENABLE_DESTROY | default('True') | bool 15 | 16 | - name: Fail if there was an Exception in getting data 17 | fail: 18 | msg: 19 | - "There was an exception when contacting the cluster:" 20 | - "{{ cluster_roles_dict['Exception'] }}" 21 | when: "'Exception' in cluster_roles_dict" 22 | 23 | - name: Calculate node roles Dict 24 | set_fact: 25 | node_roles_dict: "{{ cluster_roles_dict['node_roles_dict'] }}" 26 | 27 | - name: Calculate deleted role Dict 28 | set_fact: 29 | deleted_nodes_dict: "{{ cluster_roles_dict['deleted_nodes_dict'] }}" 30 | 31 | - name: set api_server as validated active API server 32 | set_fact: 33 | api_server: "{{ cluster_roles_dict['api_server_ip'] }}" 34 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_toragent/tasks/delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name : set params 4 | set_fact: 5 | toragent_name: "{{ toragent.key }}" 6 | with_dict: "{{ toragent_config | default({}) }}" 7 | loop_control: 8 | loop_var: toragent 9 | when: 10 | - toragent_config is defined 11 | - toragent.key is defined 12 | 13 | - name: Get name of the toragent container 14 | command: docker ps --filter name=^/{{toragent_name}} --format {%raw%}"{{.Names}}"{%endraw%} 15 | register: result_name 16 | tags: 17 | - cleanup 18 | 19 | - name: Send QUIT signal to toragent 20 | command: 21 | docker kill -s QUIT "{{ result_name.stdout }}" 22 | when: 23 | - result_name.stdout 24 | tags: 25 | - cleanup 26 | 27 | - name: Stop and remove toragent Container and volumes 28 | docker_compose: 29 | project_src: /etc/contrail/{{ toragent_name }} 30 | state: absent 31 | remove_images: all 32 | remove_volumes: yes 33 | environment: 34 | DOCKER_CLIENT_TIMEOUT: '120' 35 | COMPOSE_HTTP_TIMEOUT: '120' 36 | when: 37 | - result_name.stdout 38 | 39 | - name: Delete all files and folders used by toragent 40 | file: 41 | path: /etc/contrail/{{ toragent_name }}.env 42 | state: absent 43 | 44 | - file: 45 | path: /etc/contrail/{{ toragent_name }}/ 46 | state: absent 47 | -------------------------------------------------------------------------------- /examples/aws/all_in_one_with_openstack.yaml: -------------------------------------------------------------------------------- 1 | provider_config: 2 | aws: 3 | ec2_access_key: "${ACCESS_KEY}" 4 | ec2_secret_key: "${SECRET_KEY}" 5 | ssh_public_key: /root/.ssh/id_rsa.pub 6 | ssh_private_key: /root/.ssh/id_rsa 7 | ssh_user: centos 8 | instance_type: "${INSTANCE_TYPE}" 9 | image: "${IMAGE_ID}" 10 | region: "${REGION}" 11 | security_group: "${SECURITY_GROUP}" 12 | vpc_subnet_id: "${SUBNET}" 13 | assign_public_ip: yes 14 | volume_size: 50 15 | key_pair: "contrail-${STACK_NAME}" 16 | instances: 17 | ${STACK_NAME}_all: 18 | provider: aws 19 | roles: 20 | config_database: 21 | config: 22 | control: 23 | analytics_database: 24 | analytics: 25 | webui: 26 | openstack: 27 | vrouter: 28 | openstack_compute: 29 | contrail_configuration: 30 | CONTAINER_REGISTRY: opensdn 31 | CONTRAIL_VERSION: latest 32 | RABBITMQ_NODE_PORT: 5673 33 | AUTH_MODE: keystone 34 | KEYSTONE_AUTH_URL_VERSION: /v3 35 | KEYSTONE_AUTH_ADMIN_PASSWORD: contrail123 36 | UPGRADE_KERNEL: true 37 | kolla_config: 38 | customize: 39 | nova.conf: | 40 | [libvirt] 41 | virt_type=qemu 42 | cpu_mode=none 43 | kolla_globals: 44 | network_interface: "eth0" 45 | enable_haproxy: "no" 46 | enable_ironic: "no" 47 | enable_swift: "no" 48 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_master/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail 3 | file: 4 | path: /etc/contrail 5 | state: directory 6 | recurse: yes 7 | 8 | - name: set kube_cluster_name 9 | set_fact: 10 | kube_cluster_name: "{{ contrail_configuration.get('KUBERNETES_CLUSTER_NAME', 'k8s') }}" 11 | 12 | - name: create contrail kubemanager serviceaccount yaml 13 | template: 14 | src: contrail-kubemanager-serviceaccount.yaml.j2 15 | dest: /etc/contrail/contrail-kubemanager-serviceaccount_{{ kube_cluster_name }}.yaml 16 | 17 | - name: excute contrail kubemanager serviceaccount yaml 18 | shell: kubectl apply -f /etc/contrail/contrail-kubemanager-serviceaccount_{{ kube_cluster_name }}.yaml 19 | 20 | # in some situation kubectl needs some time to get answer with non-empty token 21 | - name: get kubemanager token name from serviceaccount 22 | shell: kubectl describe sa contrail-kubemanager -n contrail | grep -i 'Tokens' | awk '{print $2}' 23 | retries: 5 24 | delay: 5 25 | register: output 26 | until: '"contrail-kubemanager" in output.stdout' 27 | 28 | - name: get kubemanager token 29 | shell: kubectl describe secret "{{ output.stdout }}" -n contrail | grep -i 'token:' | awk '{print $2}' 30 | register: output 31 | 32 | - name: set kubemanager token 33 | set_fact: 34 | kubemanagertoken: "{{ output.stdout }}" -------------------------------------------------------------------------------- /playbooks/roles/nova/files/config_opensdn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | sudo docker cp nova_compute:/etc/nova/rootwrap.conf /tmp/ 4 | sed -i '/exec_dirs/ s/$/,\/opt\/plugin\/bin /' /tmp/rootwrap.conf 5 | sudo docker cp /tmp/rootwrap.conf nova_compute:/etc/nova/ 6 | sudo docker cp /tmp/contrail-plugin.pth nova_compute:/usr/lib/python3.6/site-packages/ 7 | #if !(grep -q "nova-compute --config-file /etc/nova/nova.conf --config-file /etc/nova/rootwrap.conf\"); then 8 | sed -ri 's/"command".*//' /etc/kolla/nova-compute/config.json 9 | sed -i '2i\"command\": \"nova-compute --config-file /etc/nova/nova.conf --config-file /etc/nova/rootwrap.conf\",' /etc/kolla/nova-compute/config.json 10 | if !(grep -q "scheduler_default_filters = RetryFilter, AvailabilityZoneFilter, RamFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, PciPassthroughFilter" /etc/kolla/nova-compute/ nova.conf); then 11 | sed -i '2a scheduler_default_filters = RetryFilter, AvailabilityZoneFilter, RamFilter, ComputeFilter, ComputeCapabilitiesFilter, ImagePropertiesFilter, PciPassthroughFilter' /etc/kolla/nova-compute/nova.conf 12 | fi 13 | 14 | if !(grep -q "scheduler_available_filters = nova.scheduler.filters.all_filters" /etc/kolla/nova-compute/nova.conf); then 15 | sed -i '3a scheduler_available_filters = nova.scheduler.filters.all_filters' /etc/kolla/nova-compute/nova.conf 16 | fi 17 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_vrouter/templates/common_vrouter.env.j2: -------------------------------------------------------------------------------- 1 | 2 | {% for k,v in contrail_configuration.items() %} 3 | {% if ((instances[instance_name].contrail_configuration is defined and 4 | instances[instance_name].contrail_configuration is not none and 5 | k in instances[instance_name].contrail_configuration) or 6 | (roles[instance_name].vrouter is defined and 7 | roles[instance_name].vrouter is not none and 8 | k in roles[instance_name].vrouter)) %} 9 | {# Skip elements that a higher precedence value in either contrail_configuration 10 | under each instance or under the vrouter role definition #} 11 | {% else %} 12 | {{ k }}={{ v }} 13 | {% endif %} 14 | {% endfor %} 15 | 16 | {% if (instances[instance_name].contrail_configuration is defined and 17 | instances[instance_name].contrail_configuration is not none) %} 18 | {% for k, v in instances[instance_name].contrail_configuration.items() %} 19 | {% if (roles[instance_name].vrouter is defined and 20 | roles[instance_name].vrouter is none or 21 | (roles[instance_name].vrouter is not none and 22 | k not in roles[instance_name].vrouter)) %} 23 | {{ k }}={{ v }} 24 | {% endif %} 25 | {% endfor %} 26 | {% endif %} 27 | 28 | {% if (roles[instance_name].vrouter is defined and 29 | roles[instance_name].vrouter is not none) %} 30 | {% for k, v in roles[instance_name].vrouter.items() %} 31 | {{ k }}={{ v }} 32 | {% endfor %} 33 | {% endif %} 34 | 35 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/Rocky.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: add repo to config-manager 3 | shell: "dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo" 4 | 5 | - name: install docker 6 | dnf: 7 | name: 8 | - docker-ce-3:25.0.3-1.el9.x86_64 9 | register: res 10 | retries: 5 11 | until: res is success 12 | 13 | - name: 14 | package: 15 | name: python3-yaml 16 | state: absent 17 | 18 | # pin requests lib due to "urllib3 v2 incompatibility" 19 | # https://github.com/docker/docker-py/issues/3113 20 | # extra_args - to avoid error during install pyyaml on modern ubuntu(22.04) 21 | - name: install wheel 22 | shell: python3 -m pip install --no-build-isolation wheel 23 | register: res 24 | retries: 5 25 | until: res is success 26 | 27 | - name: install python compose 28 | shell: python3 -m pip install --no-build-isolation 'docker-compose==1.28.6' 'requests<2.29' 29 | register: res 30 | retries: 5 31 | until: res is success 32 | 33 | # we mount /etc/timezone from host to containers 34 | # but rocky9 doesn't have such file on host and with some mount it creates folder 35 | # and we have debian based images (like rabbit) which have this file inside 36 | # therefore we get an error during run with mount folder into file 37 | # so let's create file with system content 38 | - name: create file /etc/timezone with system value 39 | copy: 40 | content: "{{ ansible_date_time.tz }}" 41 | dest: "/etc/timezone" 42 | -------------------------------------------------------------------------------- /playbooks/roles/instance/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set contrail configuration to empty if absent 3 | set_fact: 4 | contrail_configuration: {} 5 | when: contrail_configuration is undefined 6 | tags: 7 | - always 8 | 9 | - name: install software 10 | include_tasks: "install_software_{{ ansible_system }}.yml" 11 | 12 | - name: copy root ca 13 | include_tasks: copy_root_ca.yml 14 | when: 15 | - (( contrail_configuration.SSL_ENABLE is defined ) and 16 | ( contrail_configuration.SSL_ENABLE|bool )) or 17 | (( contrail_configuration.CONFIG_API_SSL_ENABLE is defined ) and 18 | ( contrail_configuration.CONFIG_API_SSL_ENABLE|bool )) or 19 | (( contrail_configuration.ANALYTICS_API_SSL_ENABLE is defined ) and 20 | ( contrail_configuration.ANALYTICS_API_SSL_ENABLE|bool )) or 21 | (( contrail_configuration.XMPP_SSL_ENABLE is defined ) and 22 | ( contrail_configuration.XMPP_SSL_ENABLE|bool )) or 23 | (( contrail_configuration.INTROSPECT_SSL_ENABLE is defined ) and 24 | ( contrail_configuration.INTROSPECT_SSL_ENABLE|bool )) or 25 | (( contrail_configuration.SANDESH_SSL_ENABLE is defined ) and 26 | ( contrail_configuration.SANDESH_SSL_ENABLE|bool )) or 27 | (( contrail_configuration.TSN_SSL_ENABLE is defined ) and 28 | ( contrail_configuration.TSN_SSL_ENABLE|bool )) or 29 | (( contrail_configuration.REDIS_SSL_ENABLE is defined ) and 30 | ( contrail_configuration.REDIS_SSL_ENABLE|bool )) 31 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/configure_certs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set default ssl dir path 3 | set_fact: 4 | ssl_dir: "/etc/contrail/ssl" 5 | 6 | - name: set ssl dir path if defined 7 | set_fact: 8 | ssl_dir: "{{ hostvars['localhost'].ssl_dir }}" 9 | when: hostvars['localhost'].ssl_dir is undefined 10 | 11 | - name: set certs & key dir paths 12 | set_fact: 13 | certs_dir: "{{ ssl_dir }}/certs" 14 | 15 | - name: set certs & key dir paths 16 | set_fact: 17 | private_keys_dir: "{{ ssl_dir }}/private" 18 | 19 | - name: default root CA & Key paths 20 | set_fact: 21 | root_ca: "{{ certs_dir }}/ca-cert.pem" 22 | root_ca_csr: "{{ certs_dir }}/ca-cert.csr" 23 | root_ca_key: "{{ private_keys_dir }}/ca-key.pem" 24 | 25 | - name: root CA path if defined 26 | set_fact: 27 | root_ca: "{{ hostvars['localhost'].root_ca }}" 28 | when: hostvars['localhost'].root_ca is defined 29 | 30 | - name: root CA Key path if defined 31 | set_fact: 32 | root_ca_key: "{{ hostvars['localhost'].root_ca_key }}" 33 | when: hostvars['localhost'].root_ca_key is defined 34 | 35 | - name: root ca path stat 36 | stat: 37 | path: "{{ root_ca }}" 38 | register: root_ca_stat 39 | 40 | - name: root ca key path stat 41 | stat: 42 | path: "{{ root_ca_key }}" 43 | register: root_ca_key_stat 44 | 45 | - name: generate root CA 46 | include_tasks: generate_ca.yml 47 | when: root_ca_stat.stat.exists == False or root_ca_key_stat.stat.exists == False 48 | -------------------------------------------------------------------------------- /playbooks/roles/kvm/templates/virt-customize.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LIBGUESTFS_BACKEND=direct 3 | /usr/bin/virt-customize -a /var/lib/libvirt/images/{{ container_vm_hostname }}.qcow2 \ 4 | --run-command 'xfs_growfs /' \ 5 | {% if 'ssh_pwd' in item.value or 'ssh_pwd' in provider_config.kvm %} 6 | --root-password password:{{ item.value.ssh_pwd|default(provider_config.kvm.ssh_pwd) }} \ 7 | {% endif %} 8 | --hostname {{ container_vm_hostname }}.{{ domainsuffix }} \ 9 | --run-command 'sed -i "s/PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config' \ 10 | --run-command 'sed -i "s/#UseDNS yes/UseDNS no/g" /etc/ssh/sshd_config' \ 11 | --run-command 'systemctl enable sshd' \ 12 | --run-command 'rm -f /root/.ssh/id_rsa' \ 13 | --run-command 'cat /dev/zero | ssh-keygen -q -N ""' \ 14 | {% if pub_key is defined %} 15 | --run-command 'echo {{ pub_key }} >> /root/.ssh/authorized_keys' \ 16 | --run-command 'chmod 600 /root/.ssh/authorized_keys' \ 17 | {% endif %} 18 | --install 'ntp' \ 19 | --run-command 'yum remove -y cloud-init' \ 20 | --upload /tmp/ifcfg_{{ container_vm_hostname }}:/etc/sysconfig/network-scripts/ifcfg-eth0 \ 21 | {% if item.value.additional_interfaces is defined %} 22 | {% for additional_interface in item.value.additional_interfaces %} 23 | {% if additional_interface.bridge is defined %} 24 | --upload /tmp/ifcfg_ext_{{loop.index}}_{{ container_vm_hostname }}:/etc/sysconfig/network-scripts/ifcfg-eth{{loop.index}} \ 25 | {% endif %} 26 | {% endfor %} 27 | {% endif %} 28 | --selinux-relabel 29 | -------------------------------------------------------------------------------- /playbooks/roles/kvm_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Build KVM host group 2 | add_host: 3 | hostname: "{{ item.value.host }}" 4 | groupname: kvm_instances 5 | ansible_ssh_pass: "{{ provider_config.kvm.ssh_pwd }}" 6 | ansible_user: "{{ provider_config.kvm.ssh_user }}" 7 | instance_name: "{{ item.key }}" 8 | when: item.value.provider=='kvm' and provider_config.kvm.ssh_pwd is defined and provider_config.kvm.ssh_user is defined 9 | with_dict: "{{ instances }}" 10 | 11 | - name: Build KVM host group 12 | add_host: 13 | hostname: "{{ item.value.host }}" 14 | groupname: kvm_instances 15 | ansible_ssh_private_key_file: "{{ provider_config.kvm.ssh_private_key }}" 16 | ansible_user: "{{ provider_config.kvm.ssh_user }}" 17 | instance_name: "{{ item.key }}" 18 | when: item.value.provider=='kvm' and provider_config.kvm.ssh_private_key is defined 19 | with_dict: "{{ instances }}" 20 | 21 | - name: create kvm host dict 22 | set_fact: 23 | kvm_host_dict: "{{ kvm_host_dict|default({})|combine({item.value.host: []}) }}" 24 | when: item.value.provider=='kvm' 25 | with_dict: "{{ instances }}" 26 | 27 | - name: create container host dict 28 | set_fact: 29 | container_host_dict: "{{ container_host_dict|default({})|combine({item.key: { 'host': item.value.host}}) }}" 30 | when: item.value.provider=='kvm' 31 | with_dict: "{{ instances }}" 32 | 33 | - name: combine kvm container hosts 34 | include_tasks: combine_kvm_container_hosts.yml 35 | with_dict: "{{ kvm_host_dict }}" 36 | when: kvm_host_dict is defined 37 | -------------------------------------------------------------------------------- /config/instances.json: -------------------------------------------------------------------------------- 1 | { 2 | "provider_config": { 3 | "kvm": { 4 | "image": "CentOS-7-x86_64-GenericCloud-1710.qcow2.xz", 5 | "image_url": "http://10.87.64.32/", 6 | "ssh_pwd": "contrail123", 7 | "ssh_user": "root", 8 | "ssh_public_key": "/user/.ssh/id_rsa.pub", 9 | "ssh_private_key": "/user/.ssh/id_rsa", 10 | "vcpu": 12, 11 | "vram": 64000, 12 | "vdisk": "100G", 13 | "subnet_prefix": "192.168.1.0", 14 | "subnet_netmask": "255.255.255.0", 15 | "gateway": "192.168.1.1", 16 | "nameserver": "192.168.1.1", 17 | "ntpserver": "192.168.1.1", 18 | "domainsuffix": "local" 19 | }, 20 | "gce": { 21 | "service_account_email": "your_service_account@developer.gserviceaccount.com", 22 | "credentials_file": "/configs/gce.json", 23 | "project_id": "your_project_id", 24 | "ssh_user": "mhenkel", 25 | "ssh_private_key": "/user/.ssh/id_rsa", 26 | "machine_type": "n1-standard-4", 27 | "image": "centos-7", 28 | "network": "microservice-vn", 29 | "subnetwork": "microservice-sn", 30 | "zone": "us-west1-a", 31 | "disk_size": 50 32 | } 33 | }, 34 | "instances": { 35 | "gce1": { 36 | "provider": "gce" 37 | }, 38 | "gce2": { 39 | "provider": "gce" 40 | }, 41 | "gce3": { 42 | "provider": "gce" 43 | } 44 | }, 45 | "contrail_configuration": { 46 | "CONTRAIL_VERSION": "latest" 47 | }, 48 | "global_configuration": { 49 | "CONTAINER_REGISTRY": "opensdn" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /config/instances.yaml.xflow_in_band: -------------------------------------------------------------------------------- 1 | global_configuration: 2 | CONTAINER_REGISTRY: ci-repo.englab.juniper.net:5010 3 | REGISTRY_PRIVATE_INSECURE: True 4 | contrail_configuration: 5 | AUTH_MODE: keystone 6 | KEYSTONE_AUTH_URL_VERSION: /v3 7 | CONTRAIL_VERSION: master-latest 8 | provider_config: 9 | bms: 10 | ssh_user: root 11 | ssh_pwd: c0ntrail123 12 | ntpserver: 10.84.5.100 13 | instances: 14 | bms1: 15 | ip: 10.84.30.201 16 | roles: 17 | config_database: 18 | config: 19 | control: 20 | analytics: 21 | analytics_alarm: 22 | analytics_database: 23 | analytics_snmp: 24 | webui: 25 | vrouter: 26 | openstack: 27 | openstack_compute: 28 | bms2: 29 | ip: 10.84.30.21 30 | provider: bms 31 | roles: 32 | appformix_flows: 33 | telemetry_in_band_interface_name: "eth0" 34 | bms3: 35 | ip: 10.84.30.22 36 | provider: bms 37 | roles: 38 | appformix_flows: 39 | telemetry_in_band_interface_name: "eth0" 40 | bms4: 41 | ip: 10.84.30.23 42 | provider: bms 43 | roles: 44 | appformix_flows: 45 | telemetry_in_band_interface_name: "eth1" 46 | kolla_config: 47 | kolla_passwords: 48 | keystone_admin_password: contrail_keystone123 49 | xflow_configuration: 50 | clickhouse_retention_period_secs: 7200 51 | clickhouse_retention_size_bytes: 0 52 | telemetry_in_band_cidr: 50.1.1.0/24 53 | loadbalancer_management_vip: 10.84.30.200 54 | loadbalancer_collector_vip: 50.1.1.200 55 | telemetry_in_band_vlan_id: 12 56 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/Rocky.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create k8s yum repo from mirror 4 | yum_repository: 5 | name: Kubernetes 6 | description: k8s repo 7 | baseurl: "{{ global_configuration.K8S_YUM_REPO_URL }}" 8 | repo_gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 9 | gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 10 | when: k8s_package_version is defined and global_configuration.K8S_YUM_REPO_URL is defined 11 | 12 | - name: create k8s yum repo from upstream 13 | yum_repository: 14 | name: Kubernetes 15 | description: k8s repo 16 | baseurl: https://pkgs.k8s.io/core:/stable:/v1.24/rpm/ 17 | gpgkey: https://pkgs.k8s.io/core:/stable:/v1.24/rpm/repodata/repomd.xml.key 18 | repo_gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 19 | gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 20 | when: k8s_package_version is defined and global_configuration.K8S_YUM_REPO_URL is not defined 21 | 22 | # using this to avoid issue https://github.com/ansible/ansible/issues/20711 23 | - name: make cache to import gpg keys 24 | command: "yum -q makecache -y --disablerepo='*' --enablerepo='Kubernetes'" 25 | when: k8s_package_version is defined 26 | 27 | # disable obsolete packages to avoid issue in kubernetes repos 28 | # https://github.com/kubernetes/kubernetes/issues/92242#issuecomment-646588615 29 | - name: Set obsoletes to 0 30 | lineinfile: 31 | path: /etc/yum.conf 32 | regexp: '^obsoletes=1' 33 | line: obsoletes=0 34 | -------------------------------------------------------------------------------- /playbooks/configure_instances.yml: -------------------------------------------------------------------------------- 1 | - name: Create container host group 2 | hosts: localhost 3 | connection: local 4 | gather_facts: yes 5 | pre_tasks: 6 | - name: Set orchestrator if not passed 7 | set_fact: 8 | contrail_configuration: "{{ contrail_configuration | default({}) | combine({'CLOUD_ORCHESTRATOR': orchestrator if orchestrator is defined else 'openstack'}) }}" 9 | when: contrail_configuration is not defined or contrail_configuration.CLOUD_ORCHESTRATOR is not defined 10 | - name: Expose instances 11 | set_fact: 12 | instances: "{{ instances }}" 13 | when: hostvars['localhost']['instances'] is undefined 14 | roles: 15 | - pip 16 | - opensdn_deployer 17 | - { role: kolla_deployer, when: contrail_configuration.CLOUD_ORCHESTRATOR == 'openstack' } 18 | vars_files: 19 | - "{{ config_file }}" 20 | 21 | - name: Configure instance(s) 22 | hosts: container_hosts 23 | gather_facts: yes 24 | pre_tasks: 25 | - name: A bugfix for Ubuntu 20.04 26 | set_fact: 27 | ansible_os_family: "Debian" 28 | when: ansible_os_family is undefined 29 | roles: 30 | - pip 31 | - instance 32 | - docker 33 | vars_files: 34 | - "{{ hostvars['localhost'].config_file }}" 35 | environment: 36 | - https_proxy: "{{ global_configuration.HTTPS_PROXY if global_configuration.HTTPS_PROXY is defined else contrail_configuration.HTTPS_PROXY | default('') }}" 37 | - http_proxy: "{{ global_configuration.HTTP_PROXY if global_configuration.HTTP_PROXY is defined else contrail_configuration.HTTP_PROXY | default('') }}" 38 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_vrouter/tasks/stop.yml: -------------------------------------------------------------------------------- 1 | # We only send SIGQUIT to the vrouter-agent, because there is no 2 | # corresponding handler in other vrouter containers 3 | - name: kill vrouter-agent docker container 4 | shell: "docker-compose -f /etc/contrail/vrouter/docker-compose.yaml kill -s SIGQUIT vrouter-agent" 5 | 6 | - name: get id of vrouter-agent docker container 7 | shell: "docker-compose -f /etc/contrail/vrouter/docker-compose.yaml ps -q vrouter-agent" 8 | register: vrouter_agent_container_output 9 | 10 | - set_fact: vrouter_agent_container={{ vrouter_agent_container_output.stdout }} 11 | 12 | - name: check if container does not running 13 | shell: "{% raw %}docker inspect --format='{{json .State.Status}}'{% endraw %} {{ vrouter_agent_container }}" 14 | register: vrouter_agent_container_status 15 | retries: 10 16 | until: vrouter_agent_container_status.rc != 0 or vrouter_agent_container_status.stdout != "\"running\"" 17 | ignore_errors: yes 18 | 19 | - name: remove all built vrouter.ko on RedHat families 20 | shell: "rm -rf /lib/modules/*/kernel/net/vrouter/vrouter.ko" 21 | when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' 22 | 23 | - name: remove all built vrouter.ko on Debian families 24 | shell: "rm -rf /lib/modules/*/updates/dkms/vrouter.ko" 25 | when: ansible_os_family == 'Debian' 26 | 27 | # and remove compose artefacts - otherwise we catch error exception on update 28 | - name: "stop vrouter" 29 | docker_compose: 30 | project_src: /etc/contrail/vrouter 31 | state: absent 32 | environment: 33 | DOCKER_CLIENT_TIMEOUT: '120' 34 | COMPOSE_HTTP_TIMEOUT: '120' 35 | -------------------------------------------------------------------------------- /playbooks/roles/kolla_deployer/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | kolla_config: {} 4 | default_openstack_sku: "yoga" 5 | openstack_sku: >- 6 | {%- if contrail_configuration.OPENSTACK_VERSION is defined -%} 7 | {{ contrail_configuration.OPENSTACK_VERSION }} 8 | {%- elif kolla_config.kolla_globals is defined and kolla_config.kolla_globals.openstack_release is defined -%} 9 | {{ kolla_config.kolla_globals.openstack_release }} 10 | {%- else -%} 11 | {{ default_openstack_sku }} 12 | {%- endif -%} 13 | 14 | # dynamic map - must be edited twice per year 15 | kolla_vanilla_tags: 16 | "xena": "xena-eol" 17 | "yoga": "yoga-eol" 18 | "zed": "zed-eol" 19 | "2023.1": "unmaintained/2023.1" 20 | "2023.2": "stable/2023.2" 21 | "2024.1": "stable/2024.1" 22 | "2024.2": "stable/2024.2" 23 | 24 | contrail_kolla_dir: "{{ playbook_dir }}/../../contrail-kolla-ansible" 25 | vanilla_kolla_dir: "{{ playbook_dir}}/../../kolla-ansible" 26 | kolla_mode: >- 27 | {%- if contrail_configuration.KOLLA_MODE is defined -%} 28 | {{ contrail_configuration.KOLLA_MODE }} 29 | {%- else -%} 30 | {{ 'patched' }} 31 | {%- endif -%} 32 | force_clone: >- 33 | {%- if kolla_config.kolla_globals is defined and kolla_config.kolla_globals.force_clone is defined -%} 34 | {{ kolla_config.kolla_globals.force_clone }} 35 | {%- else -%} 36 | no 37 | {%- endif -%} 38 | skip_checkout: >- 39 | {%- if kolla_config.kolla_globals is defined and kolla_config.kolla_globals.skip_checkout is defined -%} 40 | {{ kolla_config.kolla_globals.skip_checkout }} 41 | {%- else -%} 42 | no 43 | {%- endif -%} 44 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: create k8s repo centos from mirror 4 | yum_repository: 5 | name: Kubernetes 6 | description: k8s repo 7 | baseurl: "{{ global_configuration.K8S_YUM_REPO_URL }}" 8 | repo_gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 9 | gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 10 | when: k8s_package_version is defined and global_configuration.K8S_YUM_REPO_URL is defined 11 | 12 | - name: create k8s repo centos from upstream 13 | yum_repository: 14 | name: Kubernetes 15 | description: k8s repo 16 | baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 17 | gpgkey: https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg 18 | repo_gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 19 | gpgcheck: "{{ global_configuration.K8S_YUM_REPO_GPGCHECK | default('no') }}" 20 | when: k8s_package_version is defined and global_configuration.K8S_YUM_REPO_URL is not defined 21 | 22 | # using this to avoid issue https://github.com/ansible/ansible/issues/20711 23 | - name: make cache to import gpg keys 24 | command: "yum -q makecache -y --disablerepo='*' --enablerepo='Kubernetes'" 25 | when: k8s_package_version is defined 26 | 27 | # disable obsolete packages to avoid issue in kubernetes repos 28 | # https://github.com/kubernetes/kubernetes/issues/92242#issuecomment-646588615 29 | - name: Set obsoletes to 0 30 | lineinfile: 31 | path: /etc/yum.conf 32 | regexp: '^obsoletes=1' 33 | line: obsoletes=0 34 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_webui/templates/contrail-webui.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common_webui.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | web: 14 | image: "{{ container_registry }}/opensdn-controller-webui-web:{{ contrail_version_tag }}" 15 | network_mode: "host" 16 | env_file: /etc/contrail/common_webui.env 17 | volumes_from: 18 | - node-init 19 | depends_on: 20 | - node-init 21 | restart: always 22 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 23 | tty: {{ contrail_configuration.TTY }} 24 | logging: 25 | driver: "{{ webui_log_driver }}" 26 | options: 27 | max-size: "{{ webui_log_max_size }}" 28 | max-file: "{{ webui_log_max_file }}" 29 | job: 30 | image: "{{ container_registry }}/opensdn-controller-webui-job:{{ contrail_version_tag }}" 31 | network_mode: "host" 32 | env_file: /etc/contrail/common_webui.env 33 | volumes_from: 34 | - node-init 35 | depends_on: 36 | - node-init 37 | restart: always 38 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 39 | tty: {{ contrail_configuration.TTY }} 40 | logging: 41 | driver: "{{ webui_log_driver }}" 42 | options: 43 | max-size: "{{ webui_log_max_size }}" 44 | max-file: "{{ webui_log_max_file }}" 45 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_win_full_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: Contrail123! 4 | ssh_user: root 5 | domainsuffix: example.com 6 | 7 | bms_win: 8 | ansible_user: Administrator 9 | ansible_password: Contrail123! 10 | domainsuffix: example.com 11 | 12 | instances: 13 | ctrl: 14 | provider: bms 15 | ip: 192.168.1.100 16 | roles: 17 | config_database: 18 | config: 19 | control: 20 | analytics_database: 21 | analytics: 22 | webui: 23 | vrouter: 24 | openstack_control: 25 | openstack_network: 26 | openstack_storage: 27 | openstack_monitoring: 28 | openstack_compute: 29 | 30 | win_compute1: 31 | provider: bms_win 32 | ip: 192.168.1.101 33 | roles: 34 | vrouter: 35 | win_cnm_plugin: 36 | 37 | win_compute2: 38 | provider: bms_win 39 | ip: 192.168.1.102 40 | roles: 41 | vrouter: 42 | win_cnm_plugin: 43 | 44 | global_configuration: 45 | CONTAINER_REGISTRY: opensdn 46 | 47 | contrail_configuration: 48 | CONTRAIL_VERSION: latest 49 | CLOUD_ORCHESTRATOR: openstack 50 | #CONTROL_NODES: 172.0.0.100 # fill if ctrl/data plane is separate from mgmt 51 | RABBITMQ_NODE_PORT: 5673 52 | WINDOWS_PHYSICAL_INTERFACE: Ethernet1 53 | WINDOWS_ENABLE_TEST_SIGNING: 54 | WINDOWS_DEBUG_DLLS_PATH: ~/dlls 55 | AUTH_MODE: keystone 56 | KEYSTONE_AUTH_ADMIN_PASSWORD: c0ntrail123 57 | KEYSTONE_AUTH_HOST: 192.168.1.100 58 | 59 | kolla_config: 60 | kolla_globals: 61 | network_interface: "ens192" 62 | kolla_external_vip_interface: "ens192" 63 | enable_haproxy: "no" 64 | kolla_passwords: 65 | keystone_admin_password: c0ntrail123 66 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_vrouter/tasks/update_images.yml: -------------------------------------------------------------------------------- 1 | - name: set vrouter kernel init image name 2 | set_fact: 3 | vrouter_kernel_init_img_name: opensdn-vrouter-kernel-build-init 4 | when: 5 | - ansible_os_family == 'Debian' 6 | 7 | - name: set vrouter kernel init image name 8 | set_fact: 9 | vrouter_kernel_init_img_name: opensdn-vrouter-kernel-init 10 | when: 11 | - ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' 12 | 13 | - name: update image 14 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 15 | register: res 16 | retries: 5 17 | until: res.rc == 0 18 | with_items: 19 | - opensdn-node-init 20 | - opensdn-nodemgr 21 | - opensdn-provisioner 22 | - "{{ vrouter_kernel_init_img_name }}" 23 | - opensdn-vrouter-agent 24 | when: 25 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 26 | - roles[instance_name].vrouter.AGENT_MODE is undefined or roles[instance_name].vrouter.AGENT_MODE != 'dpdk' 27 | 28 | - name: update image for dpdk vrouter 29 | shell: "docker pull {{ container_registry }}/{{ item }}:{{ contrail_version_tag }}" 30 | register: res 31 | retries: 5 32 | until: res.rc == 0 33 | with_items: 34 | - opensdn-node-init 35 | - opensdn-nodemgr 36 | - opensdn-provisioner 37 | - opensdn-vrouter-kernel-init-dpdk 38 | - opensdn-vrouter-agent-dpdk 39 | - opensdn-vrouter-agent 40 | when: 41 | - contrail_configuration.UPDATE_IMAGES is undefined or contrail_configuration.UPDATE_IMAGES != false 42 | - roles[instance_name].vrouter.AGENT_MODE is defined 43 | - roles[instance_name].vrouter.AGENT_MODE == 'dpdk' 44 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/insecure_registry_Linux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # this file is parameterized 4 | # it takes 'docker_registry' as a parameter that should be added to insecure_registry list 5 | 6 | - name: create docker config directory 7 | file: 8 | path: "{{ nix_docker_config_directory }}" 9 | state: directory 10 | mode: 0755 11 | 12 | - name: ensure docker config file exists 13 | file: 14 | path: "{{ nix_docker_config_file }}" 15 | state: touch 16 | 17 | - name: read docker config file 18 | shell: "cat {{ nix_docker_config_file }}" 19 | register: docker_daemon_file 20 | 21 | - name: convert entries to json 22 | set_fact: 23 | docker_daemon: "{{ docker_daemon_file.stdout | default('{}', true) | from_json }}" 24 | 25 | - name: register insecure-registries 26 | set_fact: 27 | insecure_registries: "{{ docker_daemon['insecure-registries'] | default([]) }}" 28 | 29 | - name: add new docker_registry to docker config 30 | block: 31 | - name: insert updated insecure-registries to docker daemon 32 | set_fact: 33 | docker_daemon: "{{ docker_daemon | combine({ 'insecure-registries': insecure_registries + [docker_registry.split('/')[0]] }) }}" 34 | 35 | - name: write config to daemon.json 36 | copy: 37 | content: "{{ docker_daemon | to_nice_json }}" 38 | dest: "{{ nix_docker_config_file }}" 39 | 40 | - name: reload systemd 41 | shell: systemctl daemon-reload 42 | when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' 43 | 44 | - name: restart docker daemon 45 | service: 46 | enabled: yes 47 | name: docker 48 | state: restarted 49 | 50 | when: docker_registry.split('/')[0] not in insecure_registries 51 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_win_example: -------------------------------------------------------------------------------- 1 | # lines with comments require changes/attention 2 | 3 | provider_config: 4 | bms_win: 5 | ansible_user: Administrator 6 | ansible_password: Contrail123! # supply Administrator password 7 | #domainsuffix: example.com # supply DNS suffix if it's present on mgmt interface 8 | 9 | instances: 10 | win_compute1: # supply compute's hostname 11 | provider: bms_win 12 | ip: 192.168.1.101 # supply mgmt interface IP 13 | roles: 14 | vrouter: 15 | win_cnm_plugin: 16 | 17 | global_configuration: 18 | CONTAINER_REGISTRY: opensdn 19 | 20 | contrail_configuration: 21 | CLOUD_ORCHESTRATOR: none 22 | CONTRAIL_VERSION: latest 23 | CONTROLLER_NODES: 192.168.1.100 # supply mgmt interface IP of controller 24 | #CONTROL_NODES: 172.0.0.100 # supply ctrl/data interface IP of controller if it's separate from mgmt 25 | WINDOWS_PHYSICAL_INTERFACE: Ethernet1 # supply alias of dataplane interface 26 | 27 | WINDOWS_ENABLE_TEST_SIGNING: 28 | WINDOWS_DEBUG_DLLS_PATH: ~/dlls # this folder should contain debug DLLs (required for images with debug build) 29 | 30 | # WINDOWS_USE_SIGNED_VROUTER enables usage of container image with signed vRouter (kernel module). 31 | # Image with signed vRouter is only available for selected versions of Contrail. 32 | # Signed vRouter does not require enabling test signing and disabling secure boot in BIOS. 33 | # WINDOWS_USE_SIGNED_VROUTER: 34 | 35 | AUTH_MODE: keystone # Defaults to noauth. Specify if controller uses keystone for authentication 36 | KEYSTONE_AUTH_HOST: 192.168.1.100 # Optional. Supply IP of keystone host if AUTH_MODE is keystone 37 | KEYSTONE_AUTH_ADMIN_PASSWORD: c0ntrail123 # Optional. Supply real admin password if AUTH_MODE is keystone 38 | -------------------------------------------------------------------------------- /playbooks/install_k8s.yml: -------------------------------------------------------------------------------- 1 | # orchestrator MUST be passed as a command line argument like so: 2 | # 3 | # ansible-playbook -i inventory/ -e orchestrator=openstack playbook/install_k8s.yml 4 | # 5 | # orchestrator can be openstack or kubernetes 6 | # 7 | 8 | - name: Create container host group and evaluate variables for k8s 9 | hosts: localhost 10 | connection: local 11 | gather_facts: no 12 | pre_tasks: 13 | - name: Expose instances 14 | set_fact: 15 | instances: "{{ instances | default({}) }}" 16 | when: hostvars['localhost']['instances'] is undefined 17 | - name: Expose global configuration 18 | set_fact: 19 | global_configuration: "{{ global_configuration | default({}) }}" 20 | when: hostvars['localhost']['global_configuration'] is undefined 21 | roles: 22 | - opensdn_deployer 23 | - k8s_deployer 24 | vars_files: 25 | - "{{ config_file }}" 26 | 27 | - name: Install Kubernetes 28 | hosts: k8s_hosts 29 | gather_facts: yes 30 | roles: 31 | - k8s 32 | vars: 33 | - contrail_configuration: "{{ hostvars['localhost'].contrail_configuration }}" 34 | - global_configuration: "{{ hostvars['localhost'].global_configuration }}" 35 | - instances: "{{ hostvars['localhost'].instances }}" 36 | - roles: "{{ hostvars['localhost'].roles }}" 37 | - k8s_master_ip: "{{ hostvars['localhost'].k8s_master_ip }}" 38 | - k8s_master_name: "{{ hostvars['localhost'].k8s_master_name }}" 39 | environment: 40 | - https_proxy: "{{ global_configuration.HTTPS_PROXY if global_configuration.HTTPS_PROXY is defined else contrail_configuration.HTTPS_PROXY | default('') }}" 41 | - http_proxy: "{{ global_configuration.HTTP_PROXY if global_configuration.HTTP_PROXY is defined else contrail_configuration.HTTP_PROXY | default('') }}" 42 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_toragent/templates/contrail-toragent.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/{{ toragent_name }}.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | provisioner: 14 | image: "{{ container_registry }}/opensdn-provisioner:{{ contrail_version_tag }}" 15 | env_file: 16 | - "/etc/contrail/{{ toragent_name }}.env" 17 | - /etc/contrail/defaults.env 18 | environment: 19 | - NODE_TYPE=toragent 20 | network_mode: "host" 21 | volumes_from: 22 | - node-init 23 | depends_on: 24 | - node-init 25 | restart: always 26 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 27 | tty: {{ contrail_configuration.TTY }} 28 | logging: 29 | driver: "{{ compute_log_driver }}" 30 | options: 31 | max-size: "{{ compute_log_max_size }}" 32 | max-file: "{{ compute_log_max_file }}" 33 | toragent: 34 | image: "{{ container_registry }}/opensdn-tor-agent:{{ contrail_version_tag }}" 35 | network_mode: host 36 | env_file: "/etc/contrail/{{ toragent_name }}.env" 37 | volumes_from: 38 | - node-init 39 | depends_on: 40 | - node-init 41 | restart: always 42 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 43 | tty: {{ contrail_configuration.TTY }} 44 | logging: 45 | driver: "{{ compute_log_driver }}" 46 | options: 47 | max-size: "{{ compute_log_max_size }}" 48 | max-file: "{{ compute_log_max_file }}" 49 | -------------------------------------------------------------------------------- /playbooks/openstack_destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create container host group for OpenStack destroyer 3 | hosts: localhost 4 | connection: local 5 | gather_facts: no 6 | pre_tasks: 7 | - name: Expose instances 8 | set_fact: 9 | instances: "{{ instances }}" 10 | when: hostvars['localhost']['instances'] is undefined 11 | roles: 12 | - openstack_deployer 13 | vars_files: 14 | - "{{ config_file }}" 15 | 16 | - name: Apply destroy role for OpenStack 17 | hosts: openstack_nodes 18 | tasks: 19 | - name: Import group variables 20 | no_log: True 21 | include_vars: 22 | dir: "{{ playbook_dir }}/../../contrail-kolla-ansible/ansible/group_vars" 23 | extensions: ['yml'] 24 | 25 | - name: Import global variables 26 | no_log: True 27 | include_vars: 28 | dir: "{{ playbook_dir }}/../../contrail-kolla-ansible/etc/kolla" 29 | extensions: ['yml'] 30 | ignore_files: 31 | - passwords.yml.original 32 | - globals.yml.original 33 | 34 | - name: set tmphost 35 | set_fact: 36 | tmp_host: "{{ inventory_hostname }}" 37 | 38 | - stat: 39 | path: "{{ playbook_dir }}/../../contrail-kolla-ansible/ansible/host_vars/{{ tmp_host }}.yml" 40 | register: st 41 | delegate_to: localhost 42 | 43 | - name: Import host variables 44 | include_vars: 45 | file: "{{ playbook_dir }}/../../contrail-kolla-ansible/ansible/host_vars/{{ inventory_hostname }}.yml" 46 | when: st.stat.exists is defined and st.stat.exists 47 | 48 | - name: include kolla ansisble destroy directly 49 | include_role: 50 | name: "{{ playbook_dir }}/../../contrail-kolla-ansible/ansible/roles/destroy" 51 | vars: 52 | dir: "{{ playbook_dir }}/../../contrail-kolla-ansible/etc/kolla" 53 | extensions: ['yml'] 54 | contrail_cleanup: true 55 | -------------------------------------------------------------------------------- /playbooks/roles/neutron/files/api-paste.ini: -------------------------------------------------------------------------------- 1 | [composite:neutron] 2 | use = egg:Paste#urlmap 3 | /: neutronversions_composite 4 | /v2.0: neutronapi_v2_0 5 | 6 | [composite:neutronapi_v2_0] 7 | use = call:neutron.auth:pipeline_factory 8 | noauth = cors http_proxy_to_wsgi request_id catch_errors extensions neutronapiapp_v2_0 9 | keystone = user_token cors http_proxy_to_wsgi request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0 10 | 11 | [composite:neutronversions_composite] 12 | use = call:neutron.auth:pipeline_factory 13 | noauth = cors http_proxy_to_wsgi neutronversions 14 | keystone = user_token cors http_proxy_to_wsgi neutronversions 15 | 16 | [filter:request_id] 17 | paste.filter_factory = oslo_middleware:RequestId.factory 18 | 19 | [filter:user_token] 20 | paste.filter_factory = neutron_plugin_contrail.plugins.opencontrail.neutron_middleware:token_factory 21 | 22 | [filter:catch_errors] 23 | paste.filter_factory = oslo_middleware:CatchErrors.factory 24 | 25 | [filter:cors] 26 | paste.filter_factory = oslo_middleware.cors:filter_factory 27 | oslo_config_project = neutron 28 | 29 | [filter:http_proxy_to_wsgi] 30 | paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory 31 | 32 | [filter:keystonecontext] 33 | paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory 34 | 35 | [filter:authtoken] 36 | paste.filter_factory = keystonemiddleware.auth_token:filter_factory 37 | 38 | [filter:extensions] 39 | paste.filter_factory = neutron.api.extensions:plugin_aware_extension_middleware_factory 40 | 41 | [app:neutronversions] 42 | paste.app_factory = neutron.pecan_wsgi.app:versions_factory 43 | 44 | [app:neutronapiapp_v2_0] 45 | paste.app_factory = neutron.api.v2.router:APIRouter.factory 46 | 47 | [filter:osprofiler] 48 | paste.filter_factory = osprofiler.web:WsgiMiddleware.factory 49 | 50 | -------------------------------------------------------------------------------- /config/instances.yaml.openstack_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: 4 | ssh_user: root 5 | ntpserver: 10.84.5.100 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 192.168.1.51 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | webui: 18 | vrouter: 19 | openstack_control: 20 | openstack_network: 21 | openstack_storage: 22 | openstack_monitoring: 23 | openstack_compute: 24 | bms2: 25 | provider: bms 26 | ip: 192.168.1.52 27 | roles: 28 | config_database: 29 | config: 30 | control: 31 | analytics_database: 32 | analytics: 33 | webui: 34 | vrouter: 35 | openstack_control: 36 | openstack_network: 37 | openstack_storage: 38 | openstack_monitoring: 39 | openstack_compute: 40 | bms3: 41 | provider: bms 42 | ip: 192.168.1.53 43 | roles: 44 | config_database: 45 | config: 46 | control: 47 | analytics_database: 48 | analytics: 49 | webui: 50 | vrouter: 51 | openstack_control: 52 | openstack_network: 53 | openstack_storage: 54 | openstack_monitoring: 55 | openstack_compute: 56 | global_configuration: 57 | CONTAINER_REGISTRY: opensdn 58 | contrail_configuration: 59 | CONTRAIL_VERSION: queens-master-20180210000007 60 | CLOUD_ORCHESTRATOR: openstack 61 | RABBITMQ_NODE_PORT: 5673 62 | VROUTER_GATEWAY: 192.168.10.1 63 | PHYSICAL_INTERFACE: eth2 64 | kolla_config: 65 | kolla_globals: 66 | kolla_internal_vip_address: 192.168.1.160 67 | kolla_external_vip_address: 192.168.1.60 68 | network_interface: "eth1" 69 | kolla_external_vip_interface: "eth1" 70 | enable_haproxy: "yes" 71 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_vrouter/tasks/deregister.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Make sure config_api container exists on this node 3 | command: docker ps --filter name=config_api --format {%raw%}"{{.Names}}"{%endraw%} 4 | register: config_api_name 5 | 6 | # Config API container already has all necessary Keystone auth params to run this script 7 | 8 | # TODO: run this only on one config node 9 | - name: De-register vrouter from Contrail API 10 | command: > 11 | docker exec config_api_1 12 | /opt/contrail/utils/provision_vrouter.py 13 | --host_name {{ item.key }} 14 | --host_ip {{ item.value }} 15 | --api_server_ip {{ api_server }} 16 | --api_server_use_ssl {{ contrail_configuration.SSL_ENABLE | default(False) }} 17 | --oper del 18 | when: 19 | - config_api_name.stdout 20 | - contrail_configuration.AAA_MODE is not defined or contrail_configuration.AAA_MODE == 'no-auth' 21 | with_dict: "{{ delted_nodes_dict }}" 22 | ignore_errors: yes 23 | 24 | - name: De-register vrouter from Contrail API in Auth mode 25 | command: > 26 | docker exec config_api_1 27 | /opt/contrail/utils/provision_vrouter.py 28 | --host_name {{ item.key }} 29 | --host_ip {{ item.value }} 30 | --api_server_ip {{ api_server }} 31 | --api_server_use_ssl {{ contrail_configuration.SSL_ENABLE | default(False) }} 32 | --oper del 33 | --admin_user {{ contrail_configuration.KEYSTONE_AUTH_ADMIN_USER }} 34 | --admin_tenant_name {{ contrail_configuration.KEYSTONE_AUTH_ADMIN_TENANT }} 35 | --admin_password {{ contrail_configuration.KEYSTONE_AUTH_ADMIN_PASSWORD }} 36 | when: 37 | - config_api_name.stdout 38 | - contrail_configuration.AAA_MODE is defined 39 | - (contrail_configuration.AAA_MODE == 'rbac') or (contrail_configuration.AAA_MODE == 'cloud-admin') 40 | with_dict: "{{ delted_nodes_dict }}" 41 | ignore_errors: yes 42 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/configure_kubelet.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: docker info for getting cgroup driver 4 | shell: docker info 2>/dev/null |grep "Cgroup Driver" |awk '{print $3}' 5 | register: docker_info 6 | 7 | - name: get cgroup driver 8 | set_fact: 9 | cgroup_driver: "{{ docker_info.stdout }}" 10 | 11 | - name: detect kubelet config file path 12 | block: 13 | # this path is present in Ubuntu and in CentOS for old versions of k8s 14 | - name: check if kubelet config is present in common place 15 | stat: 16 | path: "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" 17 | register: st_etc 18 | # this path is in CentOS for new versions of k8s 19 | - name: check if kubelet config is present in new place 20 | stat: 21 | path: "/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf" 22 | register: st_usr 23 | - name: 24 | set_fact: 25 | kubelet_config_file: "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf" 26 | when: st_etc.stat.exists | default(false) 27 | - name: 28 | set_fact: 29 | kubelet_config_file: "/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf" 30 | when: kubelet_config_file is not defined and st_usr.stat.exists | default(false) 31 | - fail: 32 | msg: "Config file for kubelet couldn't be found. Please update code." 33 | when: kubelet_config_file is not defined 34 | 35 | - name: set cgroup driver to cgroupfs 36 | lineinfile: 37 | path: "{{ kubelet_config_file }}" 38 | regexp: '^Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=.*"' 39 | line: 'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver={{ cgroup_driver }}"' 40 | 41 | - name: set InternalIP to listen_ip 42 | lineinfile: 43 | path: "{{ kubelet_config_file }}" 44 | regexp: '^Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=.*"' 45 | line: 'Environment="KUBELET_EXTRA_ARGS=--node-ip={{ listen_ip }}"' 46 | when: listen_ip is defined 47 | -------------------------------------------------------------------------------- /examples/aws_k8s.md: -------------------------------------------------------------------------------- 1 | # AWS k8s with separate control and data plane instaces 2 | This example creates, configures and installs 3 AWS instances. The first instance 3 | is configured as control plane node and the other 2 as data plane nodes. 4 | The provider_config.aws and vpc_subnet_id parameters must be adjusted! 5 | ``` 6 | git clone http://github.com/opensdn-io/tf-ansible-deployer 7 | cd tf-ansible-deployer 8 | cat << EOF > config/instances.yaml 9 | provider_config: 10 | aws: 11 | ec2_access_key: YOUR_EC2_ACCESS_KEY 12 | ec2_secret_key: YOUR_EC2_SECRET_KEY 13 | ssh_public_key: PATH_TO_SSH_PUBLIC_KEY 14 | ssh_private_key: PATH_TO_SSH_PRIVATE_KEY 15 | ssh_user: SSH_USER 16 | instance_type: t2.xlarge 17 | image: ami-337be65c 18 | region: eu-central-1 19 | assign_public_ip: yes 20 | volume_size: 50 21 | key_pair: YOUR_KEY_PAIR 22 | ntpserver: 169.254.169.123 23 | instances: 24 | aws1: 25 | provider: aws 26 | vpc_subnet_id: VPC_SUBNET_ID 27 | roles: 28 | config_database: 29 | config: 30 | control: 31 | analytics_database: 32 | analytics: 33 | webui: 34 | k8s_master: 35 | kubemanager: 36 | aws2: 37 | UPGRADE_KERNEL: true 38 | provider: aws 39 | vpc_subnet_id: VPC_SUBNET_ID 40 | roles: 41 | vrouter: 42 | k8s_node: 43 | aws3: 44 | UPGRADE_KERNEL: true 45 | provider: aws 46 | vpc_subnet_id: VPC_SUBNET_ID 47 | roles: 48 | vrouter: 49 | k8s_node: 50 | contrail_configuration: 51 | CONTRAIL_VERSION: latest 52 | global_configuration: 53 | CONTAINER_REGISTRY: opensdn 54 | EOF 55 | ansible-playbook -i inventory/ -e orchestrator=kubernetes playbooks/provision_instances.yml 56 | ansible-playbook -i inventory/ -e orchestrator=kubernetes playbooks/configure_instances.yml 57 | ansible-playbook -i inventory/ -e orchestrator=kubernetes playbooks/install_contrail.yml 58 | ansible-playbook -i inventory/ -e orchestrator=kubernetes playbooks/install_k8s.yml 59 | ``` 60 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/templates/contrail_openssl.cfg.j2: -------------------------------------------------------------------------------- 1 | [req] 2 | default_bits = 2048 3 | prompt = no 4 | default_md = sha256 5 | default_days = 3750 6 | req_extensions = v3_req 7 | distinguished_name = req_distinguished_name 8 | x509_extensions = v3_ca 9 | 10 | [ req_distinguished_name ] 11 | 0.organizationName = Contrail 12 | commonName = contrail-ansible 13 | 14 | [ v3_req ] 15 | basicConstraints = CA:false 16 | keyUsage = nonRepudiation, digitalSignature, keyEncipherment 17 | subjectAltName = @alt_names 18 | 19 | [ alt_names ] 20 | DNS.1 = {{ hostvars['localhost'].ansible_hostname }} 21 | 22 | [ ca ] 23 | default_ca = CA_default 24 | 25 | [ CA_default ] 26 | 27 | # Directory and file locations. 28 | dir = {{ ssl_dir }} 29 | crl_dir = {{ ssl_dir }}/crl 30 | new_certs_dir = {{ ssl_dir }}/certs 31 | database = {{ ssl_dir }}/index.txt 32 | serial = {{ ssl_dir }}/serial.txt 33 | RANDFILE = {{ ssl_dir }}/.rand 34 | 35 | # For certificate revocation lists. 36 | crlnumber = {{ ssl_dir }}/crlnumber 37 | crl = {{ ssl_dir }}/crl/crl.pem 38 | crl_extensions = crl_ext 39 | 40 | # The root key and root certificate. 41 | private_key = {{ root_ca_key }} 42 | certificate = {{ root_ca }} 43 | 44 | # SHA-1 is deprecated, so use SHA-2 instead. 45 | default_md = sha256 46 | name_opt = ca_default 47 | cert_opt = ca_default 48 | preserve = no 49 | policy = policy_optional 50 | 51 | [ policy_optional ] 52 | countryName = optional 53 | stateOrProvinceName = optional 54 | organizationName = optional 55 | organizationalUnitName = optional 56 | commonName = supplied 57 | emailAddress = optional 58 | 59 | [ v3_ca] 60 | # Extensions for a typical CA 61 | # PKIX recommendation. 62 | subjectKeyIdentifier=hash 63 | authorityKeyIdentifier=keyid:always,issuer:always 64 | basicConstraints = CA:true 65 | 66 | [ crl_ext ] 67 | authorityKeyIdentifier=keyid:always,issuer:always -------------------------------------------------------------------------------- /playbooks/config_openstack.yml: -------------------------------------------------------------------------------- 1 | - name: Create container host group for OpenStack 2 | hosts: localhost 3 | connection: local 4 | gather_facts: no 5 | pre_tasks: 6 | - name: Expose instances 7 | set_fact: 8 | instances: "{{ instances }}" 9 | when: hostvars['localhost']['instances'] is undefined 10 | - name: Expose global_configuration 11 | set_fact: 12 | global_configuration: "{{ global_configuration | default({}) }}" 13 | when: hostvars['localhost']['global_configuration'] is undefined 14 | roles: 15 | - opensdn_deployer 16 | - openstack_deployer 17 | vars_files: 18 | - "{{ config_file }}" 19 | vars: 20 | - container_registry: "{{ hostvars['localhost'].container_registry }}" 21 | - contrail_version_tag: "{{ hostvars['localhost'].contrail_version_tag }}" 22 | tags: always 23 | 24 | - name: config openstack 25 | hosts: container_hosts 26 | gather_facts: yes 27 | tasks: 28 | - include_role: 29 | name: neutron 30 | when: roles[instance_name].openstack is defined 31 | - include_role: 32 | name: nova 33 | when: roles[instance_name].openstack_compute is defined 34 | - include_role: 35 | name: heat 36 | when: roles[instance_name].openstack is defined 37 | vars: 38 | container_registry: "{{ hostvars['localhost'].container_registry }}" 39 | contrail_version_tag: "{{ hostvars['localhost'].contrail_version_tag }}" 40 | roles: "{{ hostvars['localhost'].roles }}" 41 | opencontrail_api_server_port: "{{ hostvars['localhost'].config_api_port }}" 42 | opencontrail_collector_port: "{{ hostvars['localhost'].analytics_api_port }}" 43 | contrail_plugin_keystone_port: "{{ hostvars['localhost'].keystone_auth_public_port }}" 44 | contrail_plugin_internal_protocol: "{{ hostvars['localhost'].keystone_auth_proto }}" 45 | opencontrail_api_server_ip: "{{ hostvars['localhost'].opencontrail_api_server_ip }}" 46 | opencontrail_collector_ip: "{{ hostvars['localhost'].opencontrail_collector_ip }}" 47 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/analytics 3 | file: 4 | path: /etc/contrail/analytics 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/common_analytics.env stat" 9 | stat: 10 | path: "/etc/contrail/common_analytics.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/common_analytics.env if exists" 14 | file: 15 | path: "/etc/contrail/common_analytics.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/common_analytics.env" 20 | file: 21 | path: "/etc/contrail/common_analytics.env" 22 | mode: "0640" 23 | state: touch 24 | 25 | - name: "populate global common_analytics.env" 26 | lineinfile: dest=/etc/contrail/common_analytics.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 27 | with_dict: "{{ contrail_configuration }}" 28 | no_log: True 29 | 30 | - name: "populate instance specific common_analytics.env" 31 | lineinfile: dest=/etc/contrail/common_analytics.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 32 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 33 | when: instances[instance_name].contrail_configuration is defined 34 | ignore_errors: yes 35 | no_log: True 36 | 37 | - name: "populate pod specific common_analytics.env" 38 | lineinfile: dest=/etc/contrail/common_analytics.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 39 | with_dict: "{{ roles[instance_name].analytics }}" 40 | ignore_errors: yes 41 | no_log: True 42 | 43 | - name: create contrail analytics file 44 | template: 45 | src: contrail-analytics.yaml.j2 46 | dest: /etc/contrail/analytics/docker-compose.yaml 47 | 48 | - name: start contrail analytics 49 | docker_compose: 50 | project_src: /etc/contrail/analytics 51 | environment: 52 | DOCKER_CLIENT_TIMEOUT: '120' 53 | COMPOSE_HTTP_TIMEOUT: '120' 54 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_webui/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/webui 3 | file: 4 | path: /etc/contrail/webui 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/common_webui.env stat" 9 | stat: 10 | path: "/etc/contrail/common_webui.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/common_webui.env if exists" 14 | file: 15 | path: "/etc/contrail/common_webui.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/common_webui.env" 20 | file: 21 | path: "/etc/contrail/common_webui.env" 22 | mode: "0640" 23 | state: touch 24 | 25 | - name: "populate cluster wide common_webui.env" 26 | lineinfile: dest=/etc/contrail/common_webui.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 27 | with_dict: "{{ contrail_configuration }}" 28 | no_log: True 29 | 30 | - name: "populate instance specific common_webui.env" 31 | lineinfile: dest=/etc/contrail/common_webui.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 32 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 33 | when: instances[instance_name].contrail_configuration is defined 34 | ignore_errors: yes 35 | no_log: True 36 | 37 | - name: "populate pod specific common_webui.env" 38 | lineinfile: dest=/etc/contrail/common_webui.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 39 | with_dict: "{{ roles[instance_name].webui | default ({}) }}" 40 | when: roles[instance_name].webui is defined 41 | ignore_errors: yes 42 | no_log: True 43 | 44 | - name: "create contrail webui compose file" 45 | template: 46 | src: contrail-webui.yaml.j2 47 | dest: "/etc/contrail/webui/docker-compose.yaml" 48 | 49 | - name: "start contrail webui" 50 | docker_compose: 51 | project_src: /etc/contrail/webui 52 | environment: 53 | DOCKER_CLIENT_TIMEOUT: '120' 54 | COMPOSE_HTTP_TIMEOUT: '120' 55 | -------------------------------------------------------------------------------- /examples/aws/contrail_ha_with_openstack.yaml: -------------------------------------------------------------------------------- 1 | provider_config: 2 | aws: 3 | ec2_access_key: "${ACCESS_KEY}" 4 | ec2_secret_key: "${SECRET_KEY}" 5 | ssh_public_key: /root/.ssh/id_rsa.pub 6 | ssh_private_key: /root/.ssh/id_rsa 7 | ssh_user: centos 8 | instance_type: "${INSTANCE_TYPE}" 9 | image: "${IMAGE_ID}" 10 | region: "${REGION}" 11 | security_group: "${SECURITY_GROUP}" 12 | vpc_subnet_id: "${SUBNET}" 13 | assign_public_ip: yes 14 | volume_size: 50 15 | key_pair: "contrail-${STACK_NAME}" 16 | instances: 17 | ${STACK_NAME}_contrail_control1: 18 | provider: aws 19 | roles: 20 | config_database: 21 | config: 22 | control: 23 | analytics_database: 24 | analytics: 25 | webui: 26 | ${STACK_NAME}_contrail_control2: 27 | provider: aws 28 | roles: 29 | config_database: 30 | config: 31 | control: 32 | analytics_database: 33 | analytics: 34 | webui: 35 | ${STACK_NAME}_contrail_control3: 36 | provider: aws 37 | roles: 38 | config_database: 39 | config: 40 | control: 41 | analytics_database: 42 | analytics: 43 | webui: 44 | ${STACK_NAME}_openstack_control: 45 | provider: aws 46 | roles: 47 | openstack: 48 | ${STACK_NAME}_openstack_compute1: 49 | provider: aws 50 | roles: 51 | vrouter: 52 | openstack_compute: 53 | ${STACK_NAME}_openstack_compute2: 54 | provider: aws 55 | roles: 56 | vrouter: 57 | openstack_compute: 58 | contrail_configuration: 59 | CONTAINER_REGISTRY: opensdn 60 | CONTRAIL_VERSION: latest 61 | RABBITMQ_NODE_PORT: 5673 62 | AUTH_MODE: keystone 63 | KEYSTONE_AUTH_URL_VERSION: /v3 64 | KEYSTONE_AUTH_ADMIN_PASSWORD: contrail123 65 | UPGRADE_KERNEL: true 66 | kolla_config: 67 | customize: 68 | nova.conf: | 69 | [libvirt] 70 | virt_type=qemu 71 | cpu_mode=none 72 | kolla_globals: 73 | network_interface: "eth0" 74 | enable_haproxy: "no" 75 | enable_ironic: "no" 76 | enable_swift: "no" 77 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_with_qos_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: passwd 4 | ssh_user: root 5 | ntpserver: 192.84.5.100 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 192.204.216.44 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | webui: 18 | openstack: 19 | openstack_compute: 20 | vrouter: 21 | # comma separated list of hardwarwe queue ids, default queue is put at last 22 | QOS_QUEUE_ID: 2,6 23 | # Defines the logical queues mapping for corresponding hardware queue in qos_queue_id above 24 | QOS_LOGICAL_QUEUES: "[ 1, 3-8, 10-15];[17-20]" 25 | # When set to True defines the last queue in qos_queue_id list as default hardware queue for Qos 26 | QOS_DEF_HW_QUEUE: True 27 | # Knob to configure priority tagging when in DCB mode. Default value is true 28 | PRIORITY_TAGGING: False 29 | bms2: 30 | provider: bms 31 | ip: 192.204.216.22 32 | roles: 33 | openstack_compute: 34 | vrouter: 35 | PHYSICAL_INTERFACE: enp2s0 36 | # List of priority group ids for qos 37 | PRIORITY_ID: 2,4 38 | # Total hardware queue bandwidth used by corresponding priority group in priority_id list above 39 | PRIORITY_BANDWIDTH: 0,40 40 | # Defines the scheduling algorithm used for corresponding priority group, strict or roundrobin (rr). 41 | PRIORITY_SCHEDULING: strict,rr 42 | QOS_QUEUE_ID: 3,5,8 43 | QOS_LOGICAL_QUEUES: "[1, 6-10, 12-15];[2];[3-5]" 44 | PRIORITY_TAGGING: False 45 | QOS_DEF_HW_QUEUE: True 46 | global_configuration: 47 | CONTAINER_REGISTRY: opensdn 48 | contrail_configuration: 49 | CONTRAIL_VERSION: latest 50 | CLOUD_ORCHESTRATOR: openstack 51 | VROUTER_GATEWAY: 192.204.216.254 52 | RABBITMQ_NODE_PORT: 5673 53 | PHYSICAL_INTERFACE: eno1 54 | AUTH_MODE: keystone 55 | KEYSTONE_AUTH_HOST: 192.204.216.44 56 | KEYSTONE_AUTH_URL_VERSION: /v3 57 | -------------------------------------------------------------------------------- /playbooks/roles/heat/files/heat.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | debug = False 3 | log_dir = /var/log/kolla/heat 4 | log_file = $log_dir/heat-engine.log 5 | heat_metadata_server_url = http://10.0.2.15:8000 6 | heat_waitcondition_server_url = http://10.0.2.15:8000/v1/waitcondition 7 | heat_stack_user_role = heat_stack_user 8 | stack_domain_admin = heat_domain_admin 9 | stack_domain_admin_password = contrail123 10 | stack_user_domain_name = heat_user_domain 11 | num_engine_workers = 5 12 | transport_url = rabbit://openstack:contrail123@10.0.2.15:5672// 13 | region_name_for_services = RegionOne 14 | server_keystone_endpoint_type = public 15 | plugin_dirs = /opt/plugin/site-packages/vnc_api/gen/heat/resources,/opt/plugin/site-packages/contrail_heat/resources 16 | 17 | [database] 18 | connection = mysql+pymysql://heat:contrail123@10.0.2.15:3306/heat 19 | connection_recycle_time = 10 20 | max_pool_size = 1 21 | max_retries = -1 22 | 23 | [keystone_authtoken] 24 | service_type = orchestration 25 | www_authenticate_uri = http://10.0.2.15:5000 26 | auth_url = http://10.0.2.15:35357 27 | auth_type = password 28 | project_domain_id = default 29 | user_domain_id = default 30 | project_name = service 31 | username = heat 32 | password = contrail123 33 | cafile = 34 | region_name = RegionOne 35 | memcache_security_strategy = ENCRYPT 36 | memcache_secret_key = contrail123 37 | memcached_servers = 10.0.2.15:11211 38 | 39 | [cache] 40 | backend = oslo_cache.memcache_pool 41 | enabled = True 42 | memcache_servers = 10.0.2.15:11211 43 | 44 | [trustee] 45 | auth_uri = http://10.0.2.15:5000 46 | auth_url = http://10.0.2.15:35357 47 | auth_type = password 48 | user_domain_id = default 49 | username = heat 50 | password = contrail123 51 | 52 | [ec2authtoken] 53 | auth_uri = http://10.0.2.15:5000/v3 54 | 55 | [oslo_messaging_notifications] 56 | transport_url = rabbit://openstack:contrail123@10.0.2.15:5672// 57 | driver = noop 58 | 59 | [oslo_messaging_rabbit] 60 | heartbeat_in_pthread = False 61 | 62 | [clients] 63 | endpoint_type = internalURL 64 | ca_file = 65 | 66 | [oslo_middleware] 67 | enable_proxy_headers_parsing = True 68 | 69 | -------------------------------------------------------------------------------- /examples/gce1.md: -------------------------------------------------------------------------------- 1 | # GCE k8s HA with separate control and data plane instaces 2 | This example creates, configures and installs 6 GCE instances. The first 3 instances 3 | are configured as control plane nodes and the remaining 3 as data plane nodes. 4 | The provider_config.gce parameters must be adjusted! 5 | ``` 6 | git clone http://github.com/opensdn-io/tf-ansible-deployer 7 | cd tf-ansible-deployer 8 | cat << EOF > config/instances.yaml 9 | provider_config: 10 | gce: 11 | service_account_email: YOU_SERVICE_ACCOUNT_EMAIL 12 | credentials_file: /path/to/creds.json 13 | project_id: YOUR_PROJECT_ID 14 | ssh_user: centos 15 | machine_type: n1-standard-4 16 | image: centos-7 17 | network: microservice-vn 18 | subnetwork: microservice-sn 19 | zone: us-west1-a 20 | disk_size: 50 21 | instances: 22 | master1: 23 | provider: gce 24 | roles: 25 | config_database: 26 | config: 27 | control: 28 | analytics_database: 29 | analytics: 30 | webui: 31 | k8s_master: 32 | master2: 33 | provider: gce 34 | roles: 35 | config_database: 36 | config: 37 | control: 38 | analytics_database: 39 | analytics: 40 | webui: 41 | k8s_master: 42 | master3: 43 | provider: gce 44 | roles: 45 | config_database: 46 | config: 47 | control: 48 | analytics_database: 49 | analytics: 50 | webui: 51 | k8s_master: 52 | node1: 53 | provider: gce 54 | roles: 55 | vrouter: 56 | k8s_node: 57 | node2: 58 | provider: gce 59 | roles: 60 | vrouter: 61 | k8s_node: 62 | node3: 63 | provider: gce 64 | roles: 65 | vrouter: 66 | k8s_node: 67 | EOF 68 | ansible-playbook -i inventory/ playbooks/provision_instances.yml 69 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/configure_instances.yml 70 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/install_contrail.yml 71 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/install_k8s.yml 72 | ``` 73 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_toragent/tasks/toragent.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "create /etc/contrail/{{ toragent_name }}" 3 | file: 4 | path: /etc/contrail/{{ toragent_name }} 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/{{ toragent_name }}.env stat" 9 | stat: 10 | path: "/etc/contrail/{{ toragent_name }}.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/{{ toragent_name }}.env if exists" 14 | file: 15 | path: "/etc/contrail/{{ toragent_name }}.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/{{ toragent_name }}.env" 20 | file: 21 | path: "/etc/contrail/{{ toragent_name }}.env" 22 | state: touch 23 | 24 | - name: "populate cluster wide {{ toragent_name }}.env" 25 | lineinfile: dest=/etc/contrail/{{ toragent_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 26 | with_dict: "{{ contrail_configuration }}" 27 | no_log: True 28 | 29 | - name: "populate instance specific {{ toragent_name }}.env" 30 | lineinfile: dest=/etc/contrail/{{ toragent_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 31 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 32 | when: instances[instance_name].contrail_configuration is defined 33 | ignore_errors: yes 34 | no_log: True 35 | 36 | - name: "populate pod specific {{ toragent_name }}.env" 37 | lineinfile: dest=/etc/contrail/{{ toragent_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 38 | with_dict: "{{ toragent_data }}" 39 | ignore_errors: yes 40 | no_log: True 41 | 42 | - name: create contrail {{ toragent_name }} compose file 43 | template: 44 | src: contrail-toragent.yaml.j2 45 | dest: "/etc/contrail/{{ toragent_name }}/docker-compose.yaml" 46 | 47 | - name: "start contrail {{ toragent_name }}" 48 | docker_compose: 49 | project_src: /etc/contrail/{{ toragent_name }} 50 | environment: 51 | DOCKER_CLIENT_TIMEOUT: '120' 52 | COMPOSE_HTTP_TIMEOUT: '120' 53 | -------------------------------------------------------------------------------- /playbooks/roles/docker/tasks/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: upgrade pyopenssl #otherwise next step fails 3 | pip: 4 | name: pyopenssl 5 | ignore_errors: true 6 | environment: 7 | PIP_BREAK_SYSTEM_PACKAGES: 1 8 | 9 | - name: Install pre-requisites 10 | apt: 11 | name: ['apt-transport-https', 'ca-certificates', 'curl', 'software-properties-common'] 12 | register: res 13 | retries: 5 14 | until: res is success 15 | 16 | - name: add docker repo key 17 | apt_key: 18 | url: https://download.docker.com/linux/ubuntu/gpg 19 | state: present 20 | 21 | - name: create docker repo 22 | apt_repository: 23 | repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" 24 | state: present 25 | 26 | - name: install docker for ubuntu18 27 | apt: 28 | name: 29 | - "docker-ce=18.06.3~ce~3-0~ubuntu" 30 | - docker-compose 31 | - docker-compose-plugin 32 | - python3-requests 33 | state: present 34 | update_cache: yes 35 | when: ansible_distribution_major_version|int == 18 36 | register: res 37 | retries: 5 38 | until: res is success 39 | 40 | - name: install docker for ubuntu20 41 | apt: 42 | name: 43 | - "docker-ce=5:24.0.7-1~ubuntu.20.04~focal" 44 | - docker-compose 45 | - docker-compose-plugin 46 | - python3-requests 47 | state: present 48 | update_cache: yes 49 | when: ansible_distribution_major_version|int == 20 50 | register: res 51 | retries: 5 52 | until: res is success 53 | 54 | - name: install docker for other ubuntu 55 | apt: 56 | name: 57 | - "docker-ce=5:28.5.2-1~ubuntu.{{ ansible_distribution_major_version }}.04~{{ ansible_distribution_release }}" 58 | - "docker-ce-cli=5:28.5.2-1~ubuntu.{{ ansible_distribution_major_version }}.04~{{ ansible_distribution_release }}" 59 | - docker-compose 60 | - docker-compose-plugin 61 | - python3-requests 62 | state: present 63 | update_cache: yes 64 | when: ansible_distribution_major_version|int != 20 and ansible_distribution_major_version|int != 18 65 | register: res 66 | retries: 5 67 | until: res is success 68 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_with_tor_tsn_ha: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: c0ntrail123 4 | ssh_user: root 5 | ntpserver: 192.168.1.10 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 192.168.1.1 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | webui: 18 | openstack: 19 | tsn_haproxy: 20 | bms2: 21 | provider: bms 22 | ip: 192.168.1.2 23 | roles: 24 | openstack_compute: 25 | vrouter: 26 | PHYSICAL_INTERFACE: enp2s0f1 27 | toragent_1: 28 | TOR_AGENT_ID: 1 29 | TOR_AGENT_NAME: noden5-1 30 | TOR_TSN_IP: 192.16.2.3 31 | TOR_TSN_NAME: noden5 32 | 33 | bms3: 34 | provider: bms 35 | ip: 192.168.1.3 36 | roles: 37 | vrouter: 38 | PHYSICAL_INTERFACE: enp2s0f1 39 | bms4: 40 | provider: bms 41 | ip: 192.168.1.4 42 | roles: 43 | vrouter: 44 | PHYSICAL_INTERFACE: enp2s0f1 45 | toragent_1: 46 | TOR_AGENT_ID: 10 47 | TOR_AGENT_NAME: noden6-1 48 | TOR_TSN_IP: 192.16.2.4 49 | TOR_TSN_NAME: noden6 50 | 51 | global_configuration: 52 | CONTAINER_REGISTRY: opensdn 53 | contrail_configuration: 54 | CONTRAIL_VERSION: queens-dev 55 | CLOUD_ORCHESTRATOR: openstack 56 | RABBITMQ_NODE_PORT: 5673 57 | AUTH_MODE: keystone 58 | KEYSTONE_AUTH_HOST: 192.168.1.1 59 | KEYSTONE_AUTH_URL_VERSION: /v3 60 | SSL_ENABLE: True 61 | VROUTER_GATEWAY: 192.16.2.254 62 | CONTROLLER_NODES: 192.168.1.1 63 | OPENSTACK_NODES: 192.168.1.1 64 | CONTROL_NODES: 192.168.1.1 65 | TOR_IP: 192.16.3.2 66 | TOR_OVS_PORT: 4321 67 | TOR_OVS_PROTOCOL: pssl 68 | TOR_TUNNEL_IP: 192.16.4.2 69 | TOR_NAME: bng-contrail-10 70 | TOR_HTTP_SERVER_PORT: 9090 71 | TOR_AGENT_OVS_KA: 10000 72 | TOR_VENDOR_NAME: Juniper 73 | TOR_PRODUCT_NAME: QFX5100 74 | TOR_NAME: bng-contrail-10 75 | kolla_config: 76 | kolla_globals: 77 | kolla_internal_vip_address: 192.168.1.1 78 | contrail_api_interface_address: 192.168.1.1 79 | kolla_passwords: 80 | keystone_admin_password: c0ntrail123 81 | -------------------------------------------------------------------------------- /config/instances.yaml.openstack_on_aws_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | aws: 3 | ec2_access_key: "ACCESS_KEY" 4 | ec2_secret_key: "SECRET_KEY" 5 | ssh_public_key: /root/.ssh/id_rsa.pub 6 | ssh_private_key: /root/.ssh/id_rsa 7 | ssh_user: centos 8 | instance_type: t2.xlarge 9 | # https://wiki.centos.org/Cloud/AWS#head-78d1e3a4e6ba5c5a3847750d88266916ffe69648 10 | image: ami-6e28b517 11 | # https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region 12 | region: eu-west-1 13 | security_group: default 14 | # console.aws.amazon.com/vpc/ 15 | vpc_subnet_id: subnet-ca9c4f82 16 | assign_public_ip: yes 17 | volume_size: 50 18 | key_pair: contrail 19 | instances: 20 | aws_control1: 21 | provider: aws 22 | instance_type: t2.xlarge 23 | roles: 24 | config_database: 25 | config: 26 | control: 27 | analytics_database: 28 | analytics: 29 | webui: 30 | aws_control2: 31 | provider: aws 32 | instance_type: t2.xlarge 33 | roles: 34 | config_database: 35 | config: 36 | control: 37 | analytics_database: 38 | analytics: 39 | webui: 40 | aws_control3: 41 | provider: aws 42 | instance_type: t2.xlarge 43 | roles: 44 | config_database: 45 | config: 46 | control: 47 | analytics_database: 48 | analytics: 49 | webui: 50 | aws_control_openstack: 51 | provider: aws 52 | instance_type: t2.xlarge 53 | roles: 54 | openstack: 55 | aws_compute1: 56 | provider: aws 57 | instance_type: t2.xlarge 58 | roles: 59 | vrouter: 60 | global_configuration: 61 | CONTAINER_REGISTRY: opensdn 62 | contrail_configuration: 63 | CONTRAIL_VERSION: latest 64 | CLOUD_ORCHESTRATOR: openstack 65 | RABBITMQ_NODE_PORT: 5673 66 | AUTH_MODE: keystone 67 | KEYSTONE_AUTH_URL_VERSION: /v3 68 | KEYSTONE_AUTH_ADMIN_PASSWORD: 69 | kolla_config: 70 | customize: 71 | nova.conf: | 72 | [libvirt] 73 | virt_type=qemu 74 | cpu_mode=none 75 | kolla_globals: 76 | network_interface: "eth0" 77 | kolla_external_vip_interface: "eth0" 78 | enable_haproxy: "no" 79 | enable_ironic: "no" 80 | -------------------------------------------------------------------------------- /playbooks/roles/instance/files/satellite.englab.juniper.net.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFwTCCA6mgAwIBAgIJAJMmm1mPgaaoMA0GCSqGSIb3DQEBCwUAMHcxCzAJBgNV 3 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQwwCgYDVQQHDANTVkwxETAPBgNV 4 | BAoMCENvbnRyYWlsMQswCQYDVQQLDAJCVTElMCMGA1UEAwwcc2F0ZWxsaXRlLmVu 5 | Z2xhYi5qdW5pcGVyLm5ldDAeFw0xNzEyMjAwNTU4MjFaFw0xODEyMjAwNTU4MjFa 6 | MHcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQwwCgYDVQQHDANT 7 | VkwxETAPBgNVBAoMCENvbnRyYWlsMQswCQYDVQQLDAJCVTElMCMGA1UEAwwcc2F0 8 | ZWxsaXRlLmVuZ2xhYi5qdW5pcGVyLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQADggIP 9 | ADCCAgoCggIBAL+U4AQmWKCjms/H//k/Fu+/FcWG//I5mdADX6l53DO3h/ILN6s9 10 | zUcd75j5uiqhd5GDFI899HLp6vCl2Xcwk/15bpjxDMtcuZ/wi1BjhV7KLBuoE+b2 11 | rtnH1L/4u/BDKCoz8qSgej4jBxJjtvptsO7KmReT+PWlzTA+Y5/INbu25kWU9Nhb 12 | rUBRaFYRQS365xFAH5toQCMMEsL/iTxPj2xEKsFfkNX5AdzuB+ibsShG390hX1bP 13 | qdUgZI2bn757CAdqz+aVVKpzJC7/3IKOks7NMnIDF6h5b4R2mdN3UuYpmGF5UdlL 14 | RpwibW8ecAwuURWzYnY7pBOR7BtP3OjDim8OP6XJcNHq12CWIprXhtQKo7Twhhfu 15 | Dr3RPOxc7H7OGtNhBBe3O3fVM1oTQYmbeDG3AQUTaMCeYTwaeNAdEoZBP0UocgSA 16 | gF0fMo6uac8xWBAZ8dHLzcxO4RXdkxYeV64X9cIuBpjU58zxj/cI/6ozMOV11ipO 17 | NtdAx4bdfLCfUZrW7scojSHsELgsEt42VyIBMVxCNx5VzfAtuXEsi9eu1Zx6hOYY 18 | cOvATdZRQnki5sloTVT7vrjb9XVmvJ+kb0uCYPyWyPPrkYm1SwhxUidPWu8jISGS 19 | M6dAT1ogqmqTWtySsGpJmz2F434Z/c2j9qCZ6ws9dHlOxLaRLfPh9iIvAgMBAAGj 20 | UDBOMB0GA1UdDgQWBBQAzj7Pg5KPON8eJ6ZXX7R3TCQ1hDAfBgNVHSMEGDAWgBQA 21 | zj7Pg5KPON8eJ6ZXX7R3TCQ1hDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA 22 | A4ICAQAgIOiiEWDaZLij/1xgZwro9z5CrDy2LKd+Be1cus9r19/Pg90v1vWPXRIu 23 | RhBjJ50bfLa8JTqobDZUkOs3g1Owqu/qUoU6XoqxHDDpt8emnnZpSt9PG+mT99VP 24 | Fkznc+Yc689tdN865mM3MkBeEyhwV5xVi8RD+nfBucBTXxT35PD5QUbMVv8FEsEn 25 | 7CIqMZABD+KO3cbAIw8M7BXvi66oMWnnq7xGyXnZHLPtbSF+IAwIMWZA+U44324P 26 | +sRdY8+0ae39S5ZjnCUTSZ3L6aRQE0aPWkruACFUYjVWHt0suPnm1EHKulspGpVh 27 | XkRnxVPAWWdAfrs8IuVKVcgEuQDRBUyoQxgY8lcZDQVEU4qy6bwRAR15hQWGlyLO 28 | AMHU6bBWPLaYaXMRZYvryP6qyfVgRTB+ocuWFixXlp1Z+iLcecRM0QfL6Ar4R3gL 29 | BajXtyo935H5wIEZVghTOwXb4DeNY/glTl6mx1FBY6gk5dC3ksEcm0D+BWMRBFRB 30 | iE152sUt8AjcSkMK03oBnvW2/ctoS5OrZTTy/9tnYAjs/skFUR5i00Kv9V/DwlfB 31 | CCJXRhG2NweRCxwZbIB698F6OdBAhlUwM8s0Kt9ZuRl7OdulF3Yy3tY+PCFWnSbc 32 | 1WWo8fWj3H53+S01wh/8m/ecbc0RtSl360yqnfBO1xKSxeSqiA== 33 | -----END CERTIFICATE----- 34 | -------------------------------------------------------------------------------- /playbooks/roles/k8s_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: init master_ip list 3 | set_fact: 4 | k8s_master_ip_list: [] 5 | - name: init master_name list 6 | set_fact: 7 | k8s_master_name_list: [] 8 | - name: fill master lists 9 | set_fact: 10 | k8s_master_ip_list: "{{ k8s_master_ip_list + [ hostvars[item]['private_ip'] ] }}" 11 | k8s_master_name_list: "{{ k8s_master_name_list + [ item ] }}" 12 | when: 13 | - roles[hostvars[item]['instance_name']].k8s_master is defined 14 | with_items: 15 | - "{{ groups['container_hosts'] }}" 16 | 17 | - name: show master_ip list 18 | debug: 19 | msg: "{{ k8s_master_ip_list }}" 20 | 21 | - name: show master_name list 22 | debug: 23 | msg: "{{ k8s_master_name_list }}" 24 | 25 | - name: set master_ip as first item of master_ip list 26 | set_fact: 27 | k8s_master_ip: "{{ k8s_master_ip_list[0] }}" 28 | when: k8s_master_ip_list | length > 0 29 | 30 | - name: set master_name as first item of master_name list 31 | set_fact: 32 | k8s_master_name: "{{ k8s_master_name_list[0] }}" 33 | when: k8s_master_name_list | length > 0 34 | 35 | - name: "create contrail_configuration.KUBERNETES_API_SERVER for nodes" 36 | set_fact: 37 | contrail_configuration: "{{ contrail_configuration | combine({'KUBERNETES_API_SERVER': k8s_master_ip}) }}" 38 | when: 39 | - contrail_configuration.KUBERNETES_API_SERVER is undefined 40 | - k8s_master_ip is defined 41 | 42 | # TODO: there are no private_ip/ansible_user/ansible_ssh_pass/ansible_ssh_private_key_file 43 | - name: create k8s_master_host host group 44 | add_host: 45 | hostname: "{{ item.value.ip }}" 46 | groupname: k8s_master_host 47 | instance_name: "{{ item.key }}" 48 | when: 49 | - k8s_master_ip is defined 50 | - item.value.ip == k8s_master_ip 51 | with_dict: "{{ instances }}" 52 | 53 | # TODO: there are no private_ip/ansible_user/ansible_ssh_pass/ansible_ssh_private_key_file 54 | - name: create k8s_hosts host group 55 | add_host: 56 | hostname: "{{ item.value.ip }}" 57 | groupname: k8s_hosts 58 | instance_name: "{{ item.key }}" 59 | when: 60 | - item.value.roles is defined 61 | - item.value.roles.k8s_master is defined or item.value.roles.k8s_node is defined 62 | with_dict: "{{ instances }}" 63 | -------------------------------------------------------------------------------- /config/instances.yaml.gce_example: -------------------------------------------------------------------------------- 1 | provider_config: 2 | gce: 3 | service_account_email: # Mandatory. GCE service account email address. 4 | credentials_file: # Mandatory. Path to GCE account json file. 5 | project_id: # Mandatory. GCE project name. 6 | ssh_user: # Mandatory. Ssh user for GCE instances. 7 | #ssh_pwd: # Optional. Ssh password used by ssh user, not needed when public is used 8 | ssh_private_key: # Optional. Path to private SSH key, used by by ssh user, not needed when ssh-agent loaded private key 9 | machine_type: n1-standard-4 # Mandatory. Default is too small 10 | image: centos-7 # Mandatory. For provisioning and configuration only centos-7 is currently supported. 11 | network: microservice-vn # Optional. Defaults to default 12 | subnetwork: microservice-sn # Optional. Defaults to default 13 | zone: us-west1-aA # Optional. Defaults to ? 14 | disk_size: 50 # Mandatory. Default is too small 15 | aws: 16 | ec2_access_key: 17 | ec2_secret_key: 18 | ssh_public_key: 19 | ssh_private_key: 20 | ssh_user: centos 21 | instance_type: t2.xlarge 22 | image: 23 | region: 24 | security_group: 25 | vpc_subnet_id: 26 | assign_public_ip: yes 27 | volume_size: 50 28 | key_pair: 29 | instances: 30 | gce1: # Mandatory. Instance name 31 | provider: gce # Mandatory. Instance runs on GCE 32 | roles: # Optional. If roles is not defined, all below roles will be created 33 | config_database: # Optional. 34 | config: # Optional. 35 | control: # Optional. 36 | analytics_database: # Optional. 37 | analytics: # Optional. 38 | webui: # Optional. 39 | k8s_master: # Optional. 40 | k8s_node: # Optional. 41 | vrouter: # Optional. 42 | gce2: 43 | provider: gce 44 | gce3: 45 | provider: gce 46 | global_configuration: 47 | CONTAINER_REGISTRY: michaelhenkel 48 | contrail_configuration: 49 | CONTRAIL_VERSION: queens-5.0.0-134 50 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/set_global_variables.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set contrail configuration param 3 | set_fact: 4 | contrail_configuration: {} 5 | when: contrail_configuration is undefined 6 | tags: 7 | - always 8 | 9 | - name: set global configuration param 10 | set_fact: 11 | global_configuration: {} 12 | when: global_configuration is undefined 13 | tags: 14 | - always 15 | 16 | - name: set ENABLE_DESTROY flag if absent 17 | set_fact: 18 | global_configuration: "{{ global_configuration | ternary(global_configuration, {}) | combine({'ENABLE_DESTROY': true}) }}" 19 | when: 20 | - global_configuration.ENABLE_DESTROY is not defined 21 | tags: 22 | - always 23 | 24 | - name: set container tag contrail version if defined 25 | set_fact: 26 | contrail_version_tag: "{{ contrail_configuration.CONTRAIL_VERSION | default('latest') }}" 27 | tags: 28 | - always 29 | 30 | - name: add specific contrail version tag if defined 31 | set_fact: 32 | contrail_version_tag: "{{ contrail_configuration.CONTRAIL_CONTAINER_TAG }}" 33 | when: 34 | - contrail_configuration.CONTRAIL_CONTAINER_TAG is defined 35 | tags: 36 | - always 37 | 38 | - name: set registry if defined 39 | set_fact: 40 | container_registry: "{{ global_configuration.CONTAINER_REGISTRY }}" 41 | when: 42 | - global_configuration is defined 43 | - global_configuration.CONTAINER_REGISTRY is defined 44 | tags: 45 | - always 46 | - name: set registry to opensdn if undefined 47 | set_fact: 48 | container_registry: opensdn 49 | when: 50 | container_registry is not defined 51 | tags: 52 | - always 53 | 54 | - set_fact: 55 | roles: {} 56 | - name: add roles if defined 57 | set_fact: 58 | roles: "{{ roles | extract_roles(item) }}" 59 | when: item.value.roles is defined 60 | with_dict: "{{ instances }}" 61 | 62 | - name: set vars for vanilla openstack deploy 63 | set_fact: 64 | config_api_port: "{{ CONFIG_API_PORT }}" 65 | analytics_api_port: "{{ ANALYTICS_API_PORT }}" 66 | keystone_auth_public_port: "{{ KEYSTONE_AUTH_PUBLIC_PORT }}" 67 | keystone_auth_proto: "{{ KEYSTONE_AUTH_PROTO }}" 68 | opencontrail_api_server_ip: "{{ opencontrail_api_server_ip }}" 69 | opencontrail_collector_ip: "{{ opencontrail_collector_ip }}" 70 | -------------------------------------------------------------------------------- /playbooks/roles/instance/tasks/copy_root_ca.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set default ca & ca_key paths 3 | set_fact: 4 | server_root_ca: "/etc/contrail/ssl/certs/ca-cert.pem" 5 | server_root_ca_key: "/etc/contrail/ssl/private/ca-key.pem" 6 | 7 | - name: set ca path if set 8 | set_fact: 9 | server_root_ca: "{{ contrail_configuration.SERVER_CA_CERTFILE }}" 10 | when: contrail_configuration.SERVER_CA_CERTFILE is defined 11 | 12 | - name: set ca key path if set 13 | set_fact: 14 | server_root_ca_key: "{{ contrail_configuration.SERVER_CA_KEYFILE }}" 15 | when: contrail_configuration.SERVER_CA_KEYFILE is defined 16 | 17 | - name: set default ssl dir path 18 | set_fact: 19 | ssl_dir: "/etc/contrail/ssl" 20 | 21 | - name: set ssl dir path if defined 22 | set_fact: 23 | ssl_dir: "{{ hostvars['localhost'].ssl_dir }}" 24 | when: hostvars['localhost'].ssl_dir is undefined 25 | 26 | - name: set certs & key dir paths 27 | set_fact: 28 | certs_dir: "{{ ssl_dir }}/certs" 29 | 30 | - name: set certs & key dir paths 31 | set_fact: 32 | private_keys_dir: "{{ ssl_dir }}/private" 33 | 34 | - name: default root CA & Key paths 35 | set_fact: 36 | root_ca: "{{ certs_dir }}/ca-cert.pem" 37 | root_ca_csr: "{{ certs_dir }}/ca-cert.csr" 38 | root_ca_key: "{{ private_keys_dir }}/ca-key.pem" 39 | 40 | - name: root CA path if defined 41 | set_fact: 42 | root_ca: "{{ hostvars['localhost'].root_ca }}" 43 | when: hostvars['localhost'].root_ca is defined 44 | 45 | - name: root CA Key path if defined 46 | set_fact: 47 | root_ca_key: "{{ hostvars['localhost'].root_ca_key }}" 48 | when: hostvars['localhost'].root_ca_key is defined 49 | 50 | - name: create certs directories on host 51 | become: yes 52 | file: 53 | state: directory 54 | path: "{{ item.dir.split('/')[0:-1]|join('/') }}" 55 | mode: "{{ item.mode }}" 56 | with_items: 57 | - dir: "{{ server_root_ca }}" 58 | mode: "0755" 59 | - dir: "{{ server_root_ca_key }}" 60 | mode: "0700" 61 | 62 | - name: copy root ca to host 63 | copy: src={{ item.src}} dest={{ item.dest }} mode={{ item.mode }} 64 | with_items: 65 | - src: "{{ root_ca_key }}" 66 | dest: "{{ server_root_ca_key }}" 67 | mode: "0600" 68 | - src: "{{ root_ca }}" 69 | dest: "{{ server_root_ca }}" 70 | mode: "0644" 71 | when: 72 | - root_ca_key is defined and root_ca is defined 73 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_deployer/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: create container host group 2 | include_tasks: create_container_host_group.yml 3 | tags: 4 | - install_contrail 5 | 6 | - name: build node lists 7 | include_tasks: build_node_lists.yml 8 | tags: 9 | - always 10 | 11 | - name: set global variables 12 | include_tasks: set_global_variables.yml 13 | tags: 14 | - always 15 | 16 | - name: set default variables 17 | include_tasks: set_default_variables.yml 18 | tags: 19 | - always 20 | 21 | - name: set contrail variables 22 | include_tasks: set_contrail_variables.yml 23 | tags: 24 | - always 25 | 26 | - name: add gce container hosts 27 | include_tasks: add_gce_container_hosts.yml 28 | when: item.value.provider=='gce' 29 | with_dict: "{{ instances }}" 30 | tags: 31 | - configure_gce_instances 32 | - install_contrail 33 | 34 | - name: add aws container hosts 35 | include_tasks: add_aws_container_hosts.yml 36 | when: item.value.provider=='aws' 37 | with_dict: "{{ instances }}" 38 | tags: 39 | - configure_aws_instances 40 | - install_contrail 41 | 42 | - name: build cluster node role lists 43 | include_tasks: cluster_node_role_lists.yml 44 | tags: 45 | - always 46 | 47 | - name: Configure certs 48 | include_tasks: configure_certs.yml 49 | when: 50 | - contrail_configuration is defined 51 | - (( contrail_configuration.SSL_ENABLE is defined ) and 52 | ( contrail_configuration.SSL_ENABLE|bool )) or 53 | (( contrail_configuration.CONFIG_API_SSL_ENABLE is defined ) and 54 | ( contrail_configuration.CONFIG_API_SSL_ENABLE|bool )) or 55 | (( contrail_configuration.ANALYTICS_API_SSL_ENABLE is defined ) and 56 | ( contrail_configuration.ANALYTICS_API_SSL_ENABLE|bool )) or 57 | (( contrail_configuration.XMPP_SSL_ENABLE is defined ) and 58 | ( contrail_configuration.XMPP_SSL_ENABLE|bool )) or 59 | (( contrail_configuration.INTROSPECT_SSL_ENABLE is defined ) and 60 | ( contrail_configuration.INTROSPECT_SSL_ENABLE|bool )) or 61 | (( contrail_configuration.SANDESH_SSL_ENABLE is defined ) and 62 | ( contrail_configuration.SANDESH_SSL_ENABLE|bool )) or 63 | (( contrail_configuration.TSN_SSL_ENABLE is defined ) and 64 | ( contrail_configuration.TSN_SSL_ENABLE|bool )) or 65 | (( contrail_configuration.REDIS_SSL_ENABLE is defined ) and 66 | ( contrail_configuration.REDIS_SSL_ENABLE|bool )) 67 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_cni/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/cni 3 | file: 4 | path: /etc/contrail/cni 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/common_cni.env stat" 9 | stat: 10 | path: "/etc/contrail/common_cni.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/common_cni.env if exists" 14 | file: 15 | path: "/etc/contrail/common_cni.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/common_cni.env" 20 | file: 21 | path: "/etc/contrail/common_cni.env" 22 | mode: "0640" 23 | state: touch 24 | 25 | - name: "populate cluster wide common_cni.env" 26 | lineinfile: dest=/etc/contrail/common_cni.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 27 | with_dict: "{{ contrail_configuration }}" 28 | no_log: True 29 | 30 | - name: "populate instance specific common_cni.env" 31 | lineinfile: dest=/etc/contrail/common_cni.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 32 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 33 | when: instances[instance_name].contrail_configuration is defined 34 | ignore_errors: yes 35 | no_log: True 36 | 37 | - name: "populate pod specific common_cni.env" 38 | lineinfile: dest=/etc/contrail/common_cni.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 39 | with_dict: "{{ roles[instance_name].k8s_master }}" 40 | ignore_errors: yes 41 | no_log: True 42 | 43 | - name: create /var/lib/contrail 44 | file: 45 | path: /var/lib/contrail 46 | state: directory 47 | recurse: yes 48 | 49 | - name: create /etc/cni 50 | file: 51 | path: /etc/cni 52 | state: directory 53 | recurse: yes 54 | 55 | - name: create /opt/cni/bin 56 | file: 57 | path: /opt/cni/bin 58 | state: directory 59 | recurse: yes 60 | 61 | - name: create /var/log/contrail/cni 62 | file: 63 | path: /var/log/contrail/cni 64 | state: directory 65 | recurse: yes 66 | 67 | - name: "create contrail cni compose file" 68 | template: 69 | src: contrail-cni.yaml.j2 70 | dest: "/etc/contrail/cni/docker-compose.yaml" 71 | 72 | - name: "start contrail cni" 73 | docker_compose: 74 | project_src: /etc/contrail/cni 75 | environment: 76 | DOCKER_CLIENT_TIMEOUT: '120' 77 | COMPOSE_HTTP_TIMEOUT: '120' 78 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_config/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/config 3 | file: 4 | path: /etc/contrail/config 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/common_config.env stat" 9 | stat: 10 | path: "/etc/contrail/common_config.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/common_config.env if exists" 14 | file: 15 | path: "/etc/contrail/common_config.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/common_config.env" 20 | file: 21 | path: "/etc/contrail/common_config.env" 22 | mode: "0640" 23 | state: touch 24 | 25 | - name: "populate global common_config.env" 26 | lineinfile: dest=/etc/contrail/common_config.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 27 | with_dict: "{{ contrail_configuration }}" 28 | no_log: True 29 | 30 | - name: "populate instance specific common_config.env" 31 | lineinfile: dest=/etc/contrail/common_config.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 32 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 33 | when: instances[instance_name].contrail_configuration is defined 34 | ignore_errors: yes 35 | no_log: True 36 | 37 | - name: "populate pod specific common_config.env" 38 | lineinfile: dest=/etc/contrail/common_config.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 39 | with_dict: "{{ roles[instance_name].config | default ({}) }}" 40 | when: roles[instance_name].config is defined 41 | ignore_errors: yes 42 | no_log: True 43 | 44 | - name: initialize use_external_tftp variable 45 | set_fact: 46 | use_external_tftp: false 47 | 48 | - name: check if ironic_pxe is deployed on node 49 | shell: "docker inspect ironic_pxe" 50 | register: ironic_pxe_container 51 | ignore_errors: yes 52 | 53 | - name: set use_external_tftp if ironic_pxe is present 54 | set_fact: 55 | use_external_tftp: true 56 | when: 57 | - contrail_configuration.CLOUD_ORCHESTRATOR == 'openstack' 58 | - ironic_pxe_container.rc == 0 59 | 60 | - name: create contrail config compose file 61 | template: 62 | src: contrail-config.yaml.j2 63 | dest: /etc/contrail/config/docker-compose.yaml 64 | 65 | - name: start contrail config 66 | docker_compose: 67 | project_src: /etc/contrail/config 68 | environment: 69 | DOCKER_CLIENT_TIMEOUT: '120' 70 | COMPOSE_HTTP_TIMEOUT: '120' 71 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_control_only/templates/contrail-control-only.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common_control_only_{{ location.key }}.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | nodemgr: 14 | image: "{{ container_registry }}/opensdn-nodemgr:{{ contrail_version_tag }}" 15 | env_file: /etc/contrail/common_control_only_{{ location.key }}.env 16 | environment: 17 | - NODE_TYPE=control 18 | network_mode: "host" 19 | volumes: 20 | - /var/run/docker.sock:/var/run/docker.sock 21 | volumes_from: 22 | - node-init 23 | depends_on: 24 | - node-init 25 | restart: always 26 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 27 | tty: {{ contrail_configuration.TTY }} 28 | logging: 29 | driver: "{{ control_log_driver }}" 30 | options: 31 | max-size: "{{ control_log_max_size }}" 32 | max-file: "{{ control_log_max_file }}" 33 | provisioner: 34 | image: "{{ container_registry }}/opensdn-provisioner:{{ contrail_version_tag }}" 35 | env_file: 36 | - /etc/contrail/common_control_only_{{ location.key }}.env 37 | - /etc/contrail/defaults.env 38 | environment: 39 | - NODE_TYPE=control 40 | network_mode: "host" 41 | volumes_from: 42 | - node-init 43 | depends_on: 44 | - node-init 45 | restart: always 46 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 47 | tty: {{ contrail_configuration.TTY }} 48 | logging: 49 | driver: "{{ control_log_driver }}" 50 | options: 51 | max-size: "{{ control_log_max_size }}" 52 | max-file: "{{ control_log_max_file }}" 53 | control: 54 | image: "{{ container_registry }}/opensdn-controller-control-control:{{ contrail_version_tag }}" 55 | network_mode: "host" 56 | env_file: /etc/contrail/common_control_only_{{ location.key }}.env 57 | volumes_from: 58 | - node-init 59 | depends_on: 60 | - node-init 61 | restart: always 62 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 63 | tty: {{ contrail_configuration.TTY }} 64 | logging: 65 | driver: "{{ control_log_driver }}" 66 | options: 67 | max-size: "{{ control_log_max_size }}" 68 | max-file: "{{ control_log_max_file }}" 69 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_k8s_kubemanager/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set kube_cluster_name 3 | set_fact: 4 | kube_cluster_name: "{{ contrail_configuration.get('KUBERNETES_CLUSTER_NAME', 'k8s') }}" 5 | 6 | - name: "create /etc/contrail/kubemanager_{{ kube_cluster_name }}" 7 | file: 8 | path: "/etc/contrail/kubemanager_{{ kube_cluster_name }}" 9 | state: directory 10 | recurse: yes 11 | 12 | - name: "get /etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env stat" 13 | stat: 14 | path: "/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env" 15 | register: st 16 | 17 | - name: "delete /etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env if exists" 18 | file: 19 | path: "/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env" 20 | state: absent 21 | when: st.stat.exists is defined and st.stat.exists 22 | 23 | - name: "create /etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env" 24 | file: 25 | path: "/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env" 26 | mode: "0640" 27 | state: touch 28 | 29 | - name: "populate global common_kubemanager.env" 30 | lineinfile: dest=/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 31 | with_dict: "{{ contrail_configuration }}" 32 | no_log: True 33 | 34 | - name: "populate instance specific common_kubemanager.env" 35 | lineinfile: dest=/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 36 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 37 | when: instances[instance_name].contrail_configuration is defined 38 | ignore_errors: yes 39 | no_log: True 40 | 41 | - name: "populate pod specific common_kubemanager.env" 42 | lineinfile: dest=/etc/contrail/common_kubemanager_{{ kube_cluster_name }}.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 43 | with_dict: "{{ roles[instance_name].kubemanager | default ({}) }}" 44 | when: roles[instance_name].kubemanager is defined 45 | ignore_errors: yes 46 | no_log: True 47 | 48 | - name: create contrail kubemanager compose file 49 | template: 50 | src: contrail-kubemanager.yaml.j2 51 | dest: /etc/contrail/kubemanager_{{ kube_cluster_name }}/docker-compose.yaml 52 | 53 | - name: start contrail kubemanager 54 | docker_compose: 55 | project_src: /etc/contrail/kubemanager_{{ kube_cluster_name }} 56 | environment: 57 | DOCKER_CLIENT_TIMEOUT: '120' 58 | COMPOSE_HTTP_TIMEOUT: '120' 59 | -------------------------------------------------------------------------------- /playbooks/roles/openstack/tasks/manage_etc_hosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # evaluate mgmt IP for all hosts in deployment to be able to create /etc/hosts 3 | - name: Build host_intf_dict 4 | set_fact: 5 | host_intf_dict: "{{ host_intf_dict | combine({item.value['ip'] : hostvars[item.value['ip']]['network_interface_detected']}) }}" 6 | with_dict: "{{ instances }}" 7 | when: 8 | - item.value.get('ip') in groups['rabbitmq'] 9 | - inventory_hostname in groups['rabbitmq'] 10 | 11 | - name: "Build hosts file with ctrl-data and domain suffix when provided" 12 | lineinfile: dest=/etc/hosts regexp='^{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }}.*' line="{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }} {{ hostvars[item]['ansible_hostname'] }}.{{ provider_data.domainsuffix }} {{ hostvars[item]['ansible_hostname'] }}" state=present insertafter='127.0.0.1' 13 | with_items: "{{ hostvars[inventory_hostname].groups.container_hosts }}" 14 | when: 15 | - inventory_hostname in groups['rabbitmq'] 16 | - provider_data is defined 17 | - provider_data.domainsuffix is defined 18 | - host_intf_dict is defined 19 | - host_intf_dict.get(item) 20 | 21 | - name: Build hosts file with ctrl-data using ansible_fqdn 22 | lineinfile: dest=/etc/hosts regexp='^{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }}.*' line="{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }} {{ hostvars[item]['ansible_fqdn'] }} {{ hostvars[item]['ansible_hostname'] }}" state=present insertafter='127.0.0.1' 23 | with_items: "{{ hostvars[inventory_hostname].groups.container_hosts }}" 24 | when: 25 | - inventory_hostname in groups['rabbitmq'] 26 | - provider_data is defined 27 | - provider_data.domainsuffix is not defined 28 | - hostvars[item].ansible_fqdn is defined 29 | - host_intf_dict is defined 30 | - host_intf_dict.get(item) 31 | 32 | - name: Build hosts file with ctrl-data without domain suffix 33 | lineinfile: dest=/etc/hosts regexp='^{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }}.*' line="{{ hostvars[item]['ansible_' + host_intf_dict.get(item)]['ipv4']['address'] }} {{ hostvars[item]['ansible_hostname'] }}" state=present insertafter='127.0.0.1' 34 | with_items: "{{ hostvars[inventory_hostname].groups.container_hosts }}" 35 | when: 36 | - inventory_hostname in groups['rabbitmq'] 37 | - provider_data is defined 38 | - provider_data.domainsuffix is not defined 39 | - hostvars[item].ansible_fqdn is not defined 40 | - host_intf_dict is defined 41 | - host_intf_dict.get(item) 42 | 43 | -------------------------------------------------------------------------------- /examples/kvm1.md: -------------------------------------------------------------------------------- 1 | # KVM based k8s HA with separate control and data plane instaces 2 | This example creates, configures and installs 5 KVM instances. The first 3 instances 3 | are configured as control plane nodes and the remaining 2 as data plane nodes. 4 | The provider_config.kvm parameters must be adjusted! 5 | ``` 6 | git clone http://github.com/opensdn-io/tf-ansible-deployer 7 | cd tf-ansible-deployer 8 | cat << EOF > config/instances.yaml 9 | provider_config: 10 | kvm: 11 | image: CentOS-7-x86_64-GenericCloud-1802.qcow2.xz 12 | image_url: https://cloud.centos.org/centos/7/images/ 13 | ssh_pwd: 14 | ssh_user: root 15 | vcpu: 8 16 | vram: 24000 17 | vdisk: 100G 18 | subnet_prefix: 192.168.1.0 19 | subnet_netmask: 255.255.255.0 20 | gateway: 192.168.1.1 21 | nameserver: 10.84.5.100 22 | ntpserver: 192.168.1.1 23 | domainsuffix: local 24 | instances: 25 | kvm1: 26 | provider: kvm 27 | host: 10.87.64.31 28 | bridge: br1 29 | ip: 192.168.1.100 30 | roles: 31 | config_database: 32 | config: 33 | control: 34 | analytics_database: 35 | analytics: 36 | webui: 37 | k8s_master: 38 | kubemanager: 39 | kvm2: 40 | provider: kvm 41 | host: 10.87.64.32 42 | bridge: br1 43 | ip: 192.168.1.101 44 | roles: 45 | config_database: 46 | config: 47 | control: 48 | analytics_database: 49 | analytics: 50 | webui: 51 | kubemanager: 52 | kvm3: 53 | provider: kvm 54 | host: 10.87.64.33 55 | bridge: br1 56 | ip: 192.168.1.102 57 | roles: 58 | config_database: 59 | config: 60 | control: 61 | analytics_database: 62 | analytics: 63 | webui: 64 | kubemanager: 65 | kvm4: 66 | provider: kvm 67 | host: 10.87.64.33 68 | bridge: br1 69 | ip: 192.168.1.104 70 | UPGRADE_KERNEL: true 71 | roles: 72 | vrouter: 73 | k8s_node: 74 | kvm5: 75 | provider: kvm 76 | host: 10.87.64.32 77 | bridge: br1 78 | ip: 192.168.1.105 79 | UPGRADE_KERNEL: true 80 | roles: 81 | vrouter: 82 | k8s_node: 83 | contrail_configuration: 84 | CONTRAIL_VERSION: latest 85 | global_configuration: 86 | CONTAINER_REGISTRY: opensdn 87 | EOF 88 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/provision_instances.yml 89 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/configure_instances.yml 90 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/install_contrail.yml 91 | ansible-playbook -e orchestrator=kubernetes -i inventory/ playbooks/install_k8s.yml 92 | ``` 93 | -------------------------------------------------------------------------------- /playbooks/roles/kvm/tasks/build_kvm_instances.yml: -------------------------------------------------------------------------------- 1 | - name: set provider data 2 | set_fact: 3 | provider_data: "{{ provider_config.kvm }}" 4 | 5 | - name: set image to default if not provided 6 | set_fact: 7 | image: CentOS-7-x86_64-GenericCloud-1802.qcow2.xz 8 | 9 | - name: set image to provider default if not provided 10 | set_fact: 11 | image: "{{ provider_data.image }}" 12 | when: provider_data.image is defined 13 | 14 | - name: set image url to default if not provided 15 | set_fact: 16 | image_url: https://cloud.centos.org/centos/7/images/ 17 | 18 | - name: set image_url to provider default if not provided 19 | set_fact: 20 | image_url: "{{ provider_data.image_url }}" 21 | when: provider_data.image_url is defined 22 | 23 | - name: register uncompressed image 24 | find: 25 | paths: /tmp/centos_image/ 26 | patterns: '*.qcow2' 27 | file_type: file 28 | register: qcow_exists 29 | 30 | - name: get image 31 | stat: 32 | path: "/tmp/centos_image/{{ image }}" 33 | register: st 34 | 35 | - name: Clean image directory path 36 | file: 37 | state: absent 38 | path: /tmp/centos_image/ 39 | when: qcow_exists.matched == 0 and st.stat.exists == False 40 | 41 | - name: create image directory 42 | file: 43 | path: /tmp/centos_image 44 | state: directory 45 | mode: 0770 46 | when: qcow_exists.matched == 0 and st.stat.exists == False 47 | 48 | - name: Get {{ image }} 49 | get_url: 50 | url: "{{ image_url }}/{{ image }}" 51 | dest: "/tmp/centos_image/{{ image }}" 52 | when: qcow_exists.matched == 0 and st.stat.exists == False 53 | 54 | - name: Figure out file type 55 | stat: 56 | path: /tmp/centos_image/{{ image }} 57 | get_mime: true 58 | register: image_file_type 59 | when: st is defined 60 | 61 | - name: xz -d {{ image }} 62 | shell: /usr/bin/xz -f -d /tmp/centos_image/{{ image }} 63 | when: qcow_exists.matched == 0 and image_file_type.stat.mimetype == "application/x-xz" 64 | 65 | - name: ungzip {{ image }} 66 | unarchive: 67 | src: /tmp/centos_image/{{ image }} 68 | dest: /tmp/centos_image 69 | remote_src: yes 70 | register: extract_return 71 | when: qcow_exists.matched == 0 and image_file_type.stat.mimetype == "application/gzip" 72 | 73 | - name: register uncompressed image 74 | find: 75 | paths: /tmp/centos_image/ 76 | patterns: '*.qcow2' 77 | file_type: file 78 | register: uncompressed_image_file 79 | 80 | - name: set uncompressed image name 81 | set_fact: 82 | uncompressed_image_name: "{{ uncompressed_image_file.files[0].path.split('/')[3] }}" 83 | 84 | - name: build vms 85 | include_tasks: build_and_start_container_hosts.yml 86 | with_dict: "{{ hostvars['localhost'].kvm_host_dict[inventory_hostname] }}" 87 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_database/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: create /etc/contrail/analytics_database 3 | file: 4 | path: /etc/contrail/analytics_database 5 | state: directory 6 | recurse: yes 7 | 8 | - name: set cassandra seeds to ANALYTICSDB_NODES if defined 9 | set_fact: 10 | cassandra_seeds: "{{ contrail_configuration.ANALYTICSDB_NODES }}" 11 | when: contrail_configuration.ANALYTICSDB_NODES is defined 12 | 13 | - name: set cassandra seeds to CONTROLLER_NODES if ANALYTICSDB_NODES not defined 14 | set_fact: 15 | cassandra_seeds: "{{ contrail_configuration.CONTROLLER_NODES }}" 16 | when: contrail_configuration.CONTROLLER_NODES is defined and contrail_configuration.ANALYTICSDB_NODES is undefined 17 | 18 | - name: "get /etc/contrail/common_analytics_database.env stat" 19 | stat: 20 | path: "/etc/contrail/common_analytics_database.env" 21 | register: st 22 | 23 | - name: "delete /etc/contrail/common_analytics_database.env if exists" 24 | file: 25 | path: "/etc/contrail/common_analytics_database.env" 26 | state: absent 27 | when: st.stat.exists is defined and st.stat.exists 28 | 29 | - name: "create /etc/contrail/common_analytics_database.env" 30 | file: 31 | path: "/etc/contrail/common_analytics_database.env" 32 | mode: "0640" 33 | state: touch 34 | 35 | - name: "populate global common_analytics_database.env" 36 | lineinfile: dest=/etc/contrail/common_analytics_database.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 37 | with_dict: "{{ contrail_configuration }}" 38 | no_log: True 39 | 40 | - name: "populate instance specific common_analytics_database.env" 41 | lineinfile: dest=/etc/contrail/common_analytics_database.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 42 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 43 | when: instances[instance_name].contrail_configuration is defined 44 | ignore_errors: yes 45 | no_log: True 46 | 47 | - name: "populate pod specific common_analytics_database.env" 48 | lineinfile: dest=/etc/contrail/common_analytics_database.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 49 | with_dict: "{{ roles[instance_name].analytics_database | default ({}) }}" 50 | when: roles[instance_name].analytics_database is defined 51 | ignore_errors: yes 52 | no_log: True 53 | 54 | - name: create contrail analytics database compose file 55 | template: 56 | src: contrail-analytics-database.yaml.j2 57 | dest: /etc/contrail/analytics_database/docker-compose.yaml 58 | 59 | - name: start contrail analyticsdb 60 | docker_compose: 61 | project_src: /etc/contrail/analytics_database 62 | environment: 63 | DOCKER_CLIENT_TIMEOUT: '120' 64 | COMPOSE_HTTP_TIMEOUT: '120' 65 | -------------------------------------------------------------------------------- /examples/aws2.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | This document contains instructions to deploy a Contrail cluster with OpenStack on AWS using CloudFormation. 4 | 5 | ## Requirements 6 | 7 | To start working on AWS You will need AWS account with API key/secret access. 8 | If You are using IAM AWS account, account should have this inline policy attached: 9 | 10 | ``` 11 | { 12 | "Version": "2012-10-17", 13 | "Statement": [ 14 | { 15 | "Effect": "Allow", 16 | "Action": [ 17 | "cloudformation:*", 18 | "aws-marketplace:*", 19 | "sns:*", 20 | "s3:*", 21 | "ec2:*", 22 | "elasticloadbalancing:*", 23 | "cloudwatch:*", 24 | "autoscaling:*", 25 | "iam:*" 26 | ], 27 | "Resource": "*" 28 | } 29 | ] 30 | } 31 | ``` 32 | 33 | Go to AWS console: 34 | 35 | - Click services 36 | - Find IAM service 37 | - Click Users 38 | - Find Yours user, and click on it 39 | - Click "Add inline policy" 40 | - Use JSON editor, and paste above policy 41 | - Review policy 42 | - Add policy name 43 | - Click "Create policy" 44 | 45 | ## Deploying the Cluster 46 | 47 | 1. Select the AWS Region: 48 | 49 | 2. Execute the CloudFormation Template: 50 | - In the AWS services search, look for CloudFormation and select it. 51 | - Click on Create new stack. 52 | - Click on Specify an Amazon S3 template URL, and specify this URL: 53 | 54 | https://s3-eu-west-1.amazonaws.com/contrail-ansible-deployer/cloudformation_template.yaml 55 | 56 | - Next. 57 | - Give a name to the stack. 58 | - Choose HTTP url for tf-ansible-deployer config template. 59 | - Optinal: change other values. Next. Next. Next. Create. 60 | - Refresh the page until the stack is in CREATE_COMPLETE status. 61 | 62 | When stack will be deployed, please see `output` tab in cloudformation. It will contain 63 | ssh command to log to tf-ansible-deployer `base` host. You should use password to log there. 64 | 65 | From this node You can access all other nodes (user `centos`). IP addressess can be obtain from AWS console 66 | (EC2 service). 67 | 68 | If You set `InstallContrail: Yes`, logs from deployment can be found in `/var/log/messages` 69 | 70 | ## tf-ansible-deployer templates 71 | 72 | By default contrail ansible deployer will deploy env from: 73 | 74 | https://raw.githubusercontent.com/opensdn-io/tf-ansible-deployer/master/examples/aws/contrail_with_k8s.yaml 75 | 76 | Other templates are available in 77 | 78 | https://github.com/opensdn-io/tf-ansible-deployer/tree/master/examples/aws/ 79 | 80 | You can always prepare own template and serve it to cloudformation from any http url (gist, nopaste, s3, own http server, ...) 81 | 82 | ## Cleanup 83 | 84 | When You finish, You should cleanup yours AWS resources. 85 | 86 | 1) Remove all EC2 instances created by tf-ansible-deployer 87 | 2) Remove ssh key-pair created by tf-ansible-deployer 88 | 3) Remove Cloudformation stack 89 | -------------------------------------------------------------------------------- /config/instances.yaml.bms_tor_agent: -------------------------------------------------------------------------------- 1 | provider_config: 2 | bms: 3 | ssh_pwd: pass123 4 | ssh_user: root 5 | ntpserver: 192.168.1.10 6 | domainsuffix: local 7 | instances: 8 | bms1: 9 | provider: bms 10 | ip: 192.168.1.1 11 | roles: 12 | config_database: 13 | config: 14 | control: 15 | analytics_database: 16 | analytics: 17 | webui: 18 | openstack: 19 | bms2: 20 | provider: bms 21 | ip: 192.168.1.2 22 | contrail_configuration: 23 | TOR_TSN_IP: 192.16.2.3 24 | TOR_TSN_NAME: a1s16 25 | TSN_AGENT_MODE: 'tsn' 26 | roles: 27 | openstack_compute: 28 | vrouter: 29 | PHYSICAL_INTERFACE: enp2s0f1 30 | toragent_1: 31 | TOR_IP: 192.16.3.1 32 | TOR_AGENT_ID: 11 33 | TOR_AGENT_NAME: a1s16-11 34 | TOR_OVS_PORT: 4321 35 | TOR_OVS_PROTOCOL: pssl 36 | TOR_NAME: a2-qfx1 37 | TOR_TUNNEL_IP: 192.16.4.1 38 | TOR_HTTP_SERVER_PORT: 8090 39 | toragent_2: 40 | TOR_IP: 192.16.3.2 41 | TOR_AGENT_ID: 23 42 | TOR_AGENT_NAME: a1s16-23 43 | TOR_OVS_PORT: 5321 44 | TOR_OVS_PROTOCOL: tcp 45 | TOR_NAME: a2-qfx2 46 | TOR_TUNNEL_IP: 192.16.4.2 47 | TOR_HTTP_SERVER_PORT: 8091 48 | bms3: 49 | provider: bms 50 | ip: 192.168.1.3 51 | roles: 52 | vrouter: 53 | PHYSICAL_INTERFACE: enp2s0f1 54 | bms4: 55 | provider: bms 56 | ip: 192.168.1.4 57 | contrail_configuration: 58 | TOR_TSN_IP: 192.16.2.4 59 | TOR_TSN_NAME: noden7 60 | TOR_OVS_PROTOCOL: pssl 61 | TSN_AGENT_MODE: 'tsn' 62 | roles: 63 | vrouter: 64 | PHYSICAL_INTERFACE: enp2s0f1 65 | toragent_1: 66 | TOR_IP: 192.16.3.3 67 | TOR_AGENT_ID: 1 68 | TOR_AGENT_NAME: noden7-1 69 | TOR_OVS_PORT: 6321 70 | TOR_NAME: a1-qfx1 71 | TOR_TUNNEL_IP: 192.16.4.3 72 | TOR_HTTP_SERVER_PORT: 8092 73 | toragent_2: 74 | TOR_IP: 192.16.3.4 75 | TOR_AGENT_ID: 2 76 | TOR_AGENT_NAME: noden7-2 77 | TOR_OVS_PORT: 9321 78 | TOR_NAME: a1-qfx2 79 | TOR_TUNNEL_IP: 192.16.4.4 80 | TOR_HTTP_SERVER_PORT: 8093 81 | global_configuration: 82 | CONTAINER_REGISTRY: opensdn 83 | contrail_configuration: 84 | CONTRAIL_VERSION: queens-dev 85 | CLOUD_ORCHESTRATOR: openstack 86 | RABBITMQ_NODE_PORT: 5673 87 | AUTH_MODE: keystone 88 | KEYSTONE_AUTH_HOST: 192.168.1.1 89 | KEYSTONE_AUTH_URL_VERSION: /v3 90 | SSL_ENABLE: True 91 | VROUTER_GATEWAY: 192.16.2.254 92 | CONTROLLER_NODES: 192.168.1.1 93 | OPENSTACK_NODES: 192.168.1.1 94 | CONTROL_NODES: 192.168.1.1 95 | TOR_VENDOR_NAME: Juniper 96 | TOR_PRODUCT_NAME: QFX5100 97 | TOR_AGENT_OVS_KA: 10000 98 | TSN_SSL_ENABLE: True 99 | kolla_config: 100 | kolla_globals: 101 | kolla_internal_vip_address: 192.168.1.1 102 | contrail_api_interface_address: 192.168.1.1 103 | kolla_passwords: 104 | keystone_admin_password: pass123 105 | -------------------------------------------------------------------------------- /playbooks/roles/haproxy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "create /etc/contrail/tsn_haproxy" 3 | file: 4 | path: /etc/contrail/tsn_haproxy 5 | state: directory 6 | recurse: yes 7 | 8 | - name: "get /etc/contrail/tsn_haproxy.env stat" 9 | stat: 10 | path: "/etc/contrail/tsn_haproxy.env" 11 | register: st 12 | 13 | - name: "delete /etc/contrail/tsn_haproxy.env if exists" 14 | file: 15 | path: "/etc/contrail/tsn_haproxy.env" 16 | state: absent 17 | when: st.stat.exists is defined and st.stat.exists 18 | 19 | - name: "create /etc/contrail/tsn_haproxy.env" 20 | file: 21 | path: "/etc/contrail/tsn_haproxy.env" 22 | state: touch 23 | 24 | - set_fact: 25 | toragent_hosts_list: [] 26 | - name: add toragent hosts to the list 27 | set_fact: 28 | toragent_hosts_list: "{{ toragent_hosts_list + [ item.key ] }}" 29 | when: 30 | - item.value.roles is defined 31 | - ( item.value.roles.keys() | select('search','toragent') | list | count > 0 ) 32 | with_dict: "{{ instances }}" 33 | 34 | - set_fact: 35 | tsn_haproxy_config: {} 36 | - name: construct tsn ip and ovs port list for redundat toragent pairs in tsn_haproxy_config dict 37 | set_fact: 38 | tsn_haproxy_config: "{{ tsn_haproxy_config | calculate_tsn_haproxy_config(toragent_hosts_list, instances, contrail_configuration) }}" 39 | when: 40 | - toragent_hosts_list | length > 0 41 | 42 | - name: "populate pod specific tsn_haproxy.env with IP_LIST and PORT_LIST calculated by haproxy filter" 43 | lineinfile: dest=/etc/contrail/tsn_haproxy.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value | join(',') }}" state=present 44 | when: 45 | - tsn_haproxy_config.keys() | length > 0 46 | with_dict: "{{ tsn_haproxy_config }}" 47 | 48 | - name: "populate global tsn_haproxy.env" 49 | lineinfile: dest=/etc/contrail/tsn_haproxy.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 50 | with_dict: "{{ contrail_configuration }}" 51 | no_log: True 52 | 53 | - name: "populate instance specific tsn_haproxy.env" 54 | lineinfile: dest=/etc/contrail/common_config.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value }}" state=present 55 | with_dict: "{{ instances[instance_name].contrail_configuration }}" 56 | when: instances[instance_name].contrail_configuration is defined 57 | ignore_errors: yes 58 | no_log: True 59 | 60 | - name: "populate pod specific tsn_haproxy.env" 61 | lineinfile: dest=/etc/contrail/tsn_haproxy.env regexp='^{{ item.key }}=.*' line="{{ item.key }}={{ item.value | string }}" state=present 62 | with_dict: 63 | "{{ roles[instance_name].tsn_haproxy | default({}) }}" 64 | when: roles[instance_name].tsn_haproxy is defined 65 | ignore_errors: yes 66 | no_log: True 67 | 68 | - name: "create tsn_haproxy compose file" 69 | template: 70 | src: haproxy.yaml.j2 71 | dest: "/etc/contrail/tsn_haproxy/docker-compose.yaml" 72 | 73 | - name: "start tsn_haproxy container" 74 | docker_compose: 75 | project_src: /etc/contrail/tsn_haproxy 76 | environment: 77 | DOCKER_CLIENT_TIMEOUT: '120' 78 | COMPOSE_HTTP_TIMEOUT: '120' 79 | -------------------------------------------------------------------------------- /playbooks/roles/k8s/tasks/configure_k8s_master_node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: check if master is already running 3 | shell: kubectl cluster-info 4 | register: master_state 5 | ignore_errors: true 6 | 7 | - name: set master_running state to true if master is running 8 | set_fact: 9 | master_running: true 10 | when: master_state is defined and master_state.rc == 0 11 | 12 | - name: set master_running state to false if master is not running 13 | set_fact: 14 | master_running: false 15 | when: (master_state is undefined) or 16 | (master_state is defined and master_state.rc == 1) 17 | 18 | - name: get controller ip from all ips 19 | set_fact: 20 | listen_ip: "{{ item[0] }}" 21 | when: item[0] == item[1] 22 | with_nested: 23 | - "{{ hostvars[inventory_hostname].ansible_all_ipv4_addresses }}" 24 | - "{{ contrail_configuration.KUBERNETES_API_NODES }}" 25 | 26 | - name: Configure kubelet 27 | include_tasks: configure_kubelet.yml 28 | 29 | - name: enable kubelet service 30 | systemd: 31 | name: kubelet 32 | state: restarted 33 | daemon_reload: yes 34 | enabled: True 35 | when: master_running == false 36 | 37 | - name: initialize k8s master with listen ip 38 | shell: | 39 | kubeadm init --token-ttl 0 --kubernetes-version v{{ k8s_version }} --apiserver-advertise-address {{ listen_ip }} --pod-network-cidr {{ kube_pod_subnet }} --service-cidr {{ kube_service_subnet }} && 40 | mkdir -p $HOME/.kube && 41 | cp -u /etc/kubernetes/admin.conf $HOME/.kube/config && 42 | chown -R $(id -u):$(id -g) $HOME/.kube 43 | when: listen_ip is defined and master_running == false 44 | register: res 45 | retries: 5 46 | until: res is success 47 | 48 | - name: initialize k8s master without listen ip 49 | shell: | 50 | kubeadm init --token-ttl 0 --kubernetes-version v{{ k8s_version }} --pod-network-cidr {{ kube_pod_subnet }} --service-cidr {{ kube_service_subnet }} && 51 | mkdir -p $HOME/.kube && 52 | cp -u /etc/kubernetes/admin.conf $HOME/.kube/config && 53 | chown -R $(id -u):$(id -g) $HOME/.kube 54 | when: listen_ip is undefined and master_running == false 55 | 56 | - name: get master token 57 | shell: kubeadm token list |grep "system:bootstrappers:kubeadm:default-node-token" |grep "forever" |awk '{print $1}' 58 | register: output 59 | 60 | - name: set master token 61 | set_fact: 62 | mastertoken: "{{ output.stdout }}" 63 | 64 | - name: get nodes 65 | shell: kubectl get nodes -o yaml |grep "\- address:" |awk '{print $3}' 66 | register: nodes_list_output 67 | 68 | - name: set node list 69 | set_fact: 70 | node_list: "{{ nodes_list_output.stdout }}" 71 | 72 | #Need to upgrade CoreDNS to 1.2.6 for fix of Loop crash issue 73 | #Remove once k8s_version version bumped up to 1.13.1 or higher 74 | - name: upgrade CoreDNS to 1.2.6 75 | shell: "kubectl patch deployment -n=kube-system coredns -p '{\"spec\": {\"template\": {\"spec\":{\"containers\":[{\"image\":\"k8s.gcr.io/coredns:1.2.6\", \"name\":\"coredns\",\"resources\":{\"limits\":{\"memory\":\"1Gi\"},\"requests\":{\"cpu\":\"100m\",\"memory\":\"70Mi\"}}}]}}}}'" 76 | when: k8s_version == "1.12.9" 77 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics/templates/contrail-analytics.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common_analytics.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | nodemgr: 14 | image: "{{ container_registry }}/opensdn-nodemgr:{{ contrail_version_tag }}" 15 | env_file: /etc/contrail/common_analytics.env 16 | environment: 17 | - NODE_TYPE=analytics 18 | network_mode: "host" 19 | volumes: 20 | - /var/run/docker.sock:/var/run/docker.sock 21 | volumes_from: 22 | - node-init 23 | depends_on: 24 | - node-init 25 | restart: always 26 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 27 | tty: {{ contrail_configuration.TTY }} 28 | logging: 29 | driver: "{{ analytics_log_driver }}" 30 | options: 31 | max-size: "{{ analytics_log_max_size }}" 32 | max-file: "{{ analytics_log_max_file }}" 33 | provisioner: 34 | image: "{{ container_registry }}/opensdn-provisioner:{{ contrail_version_tag }}" 35 | env_file: 36 | - /etc/contrail/common_analytics.env 37 | - /etc/contrail/defaults.env 38 | environment: 39 | - NODE_TYPE=analytics 40 | network_mode: "host" 41 | volumes_from: 42 | - node-init 43 | depends_on: 44 | - node-init 45 | restart: always 46 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 47 | tty: {{ contrail_configuration.TTY }} 48 | logging: 49 | driver: "{{ analytics_log_driver }}" 50 | options: 51 | max-size: "{{ analytics_log_max_size }}" 52 | max-file: "{{ analytics_log_max_file }}" 53 | api: 54 | image: "{{ container_registry }}/opensdn-analytics-api:{{ contrail_version_tag }}" 55 | network_mode: "host" 56 | env_file: /etc/contrail/common_analytics.env 57 | volumes_from: 58 | - node-init 59 | depends_on: 60 | - node-init 61 | restart: always 62 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 63 | tty: {{ contrail_configuration.TTY }} 64 | logging: 65 | driver: "{{ analytics_log_driver }}" 66 | options: 67 | max-size: "{{ analytics_log_max_size }}" 68 | max-file: "{{ analytics_log_max_file }}" 69 | collector: 70 | image: "{{ container_registry }}/opensdn-analytics-collector:{{ contrail_version_tag }}" 71 | network_mode: "host" 72 | cap_add: 73 | - SYS_PTRACE 74 | env_file: /etc/contrail/common_analytics.env 75 | volumes_from: 76 | - node-init 77 | depends_on: 78 | - node-init 79 | restart: always 80 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 81 | tty: {{ contrail_configuration.TTY }} 82 | logging: 83 | driver: "{{ analytics_log_driver }}" 84 | options: 85 | max-size: "{{ analytics_log_max_size }}" 86 | max-file: "{{ analytics_log_max_file }}" 87 | -------------------------------------------------------------------------------- /playbooks/roles/opensdn_analytics_snmp/templates/contrail-analytics-snmp.yaml.j2: -------------------------------------------------------------------------------- 1 | version: '2.4' 2 | services: 3 | node-init: 4 | image: "{{ container_registry }}/opensdn-node-init:{{ contrail_version_tag }}" 5 | env_file: /etc/contrail/common.env 6 | environment: 7 | - CONTRAIL_STATUS_IMAGE="{{ container_registry }}/opensdn-status:{{ contrail_version_tag }}" 8 | privileged: true 9 | pid: host 10 | network_mode: "host" 11 | volumes: 12 | {{ common_volumes | to_yaml | indent(width=6) }} 13 | nodemgr: 14 | image: "{{ container_registry }}/opensdn-nodemgr:{{ contrail_version_tag }}" 15 | env_file: /etc/contrail/common.env 16 | environment: 17 | - NODE_TYPE=analytics-snmp 18 | network_mode: "host" 19 | volumes: 20 | - /var/run/docker.sock:/var/run/docker.sock 21 | volumes_from: 22 | - node-init 23 | restart: always 24 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 25 | tty: {{ contrail_configuration.TTY }} 26 | logging: 27 | driver: "{{ analytics_snmp_log_driver }}" 28 | options: 29 | max-size: "{{ analytics_snmp_log_max_size }}" 30 | max-file: "{{ analytics_snmp_log_max_file }}" 31 | depends_on: 32 | - node-init 33 | provisioner: 34 | image: "{{ container_registry }}/opensdn-provisioner:{{ contrail_version_tag }}" 35 | env_file: 36 | - /etc/contrail/common.env 37 | - /etc/contrail/defaults.env 38 | environment: 39 | - NODE_TYPE=analytics-snmp 40 | network_mode: "host" 41 | volumes_from: 42 | - node-init 43 | depends_on: 44 | - node-init 45 | restart: always 46 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 47 | tty: {{ contrail_configuration.TTY }} 48 | logging: 49 | driver: "{{ analytics_snmp_log_driver }}" 50 | options: 51 | max-size: "{{ analytics_snmp_log_max_size }}" 52 | max-file: "{{ analytics_snmp_log_max_file }}" 53 | snmp-collector: 54 | image: "{{ container_registry }}/opensdn-analytics-snmp-collector:{{ contrail_version_tag }}" 55 | network_mode: "host" 56 | env_file: /etc/contrail/common.env 57 | volumes_from: 58 | - node-init 59 | depends_on: 60 | - node-init 61 | restart: always 62 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 63 | tty: {{ contrail_configuration.TTY }} 64 | logging: 65 | driver: "{{ analytics_snmp_log_driver }}" 66 | options: 67 | max-size: "{{ analytics_snmp_log_max_size }}" 68 | max-file: "{{ analytics_snmp_log_max_file }}" 69 | topology: 70 | image: "{{ container_registry }}/opensdn-analytics-snmp-topology:{{ contrail_version_tag }}" 71 | network_mode: "host" 72 | env_file: /etc/contrail/common.env 73 | volumes_from: 74 | - node-init 75 | depends_on: 76 | - node-init 77 | restart: always 78 | stdin_open: {{ contrail_configuration.STDIN_OPEN }} 79 | tty: {{ contrail_configuration.TTY }} 80 | logging: 81 | driver: "{{ analytics_snmp_log_driver }}" 82 | options: 83 | max-size: "{{ analytics_snmp_log_max_size }}" 84 | max-file: "{{ analytics_snmp_log_max_file }}" 85 | --------------------------------------------------------------------------------