diff --git a/.gitignore b/.gitignore index d341973ed44..97a7125a360 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ Ansible/group_vars/all +*.pyc +.vscode/* diff --git a/Ansible/deployvms.yml b/Ansible/deployvms.yml index 8bc043f5ee8..842825d29ef 100644 --- a/Ansible/deployvms.yml +++ b/Ansible/deployvms.yml @@ -26,6 +26,9 @@ connection: local gather_facts: no tasks: + - name: Ensure cmk is pointing to the right env + shell: cmk set profile cloudstack + - name: Capture build date set_fact: env_builddate="{{lookup('pipe','date +%d/%m/%y_%H:%M')}}" @@ -62,17 +65,17 @@ # Create build project if it doesn't exist. - name: Create project include: tasks/updateproject.yml project_tag=Deploying_VMs - + - name: Capture all accounts in domain - shell: cs listAccounts listall=true | jq -c -r '.account[] | select(.domain == "ROOT")' | jq -c -r '.name' | sed -e ':a;N;$!ba;s/\n/,/g' + shell: cmk listAccounts listall=true | jq -c -r '.account[] | select(.domain == "ROOT")' | jq -c -r '.name' | sed -e ':a;N;$!ba;s/\n/,/g' register: allaccts_retval - name: get projectid - shell: cs listProjects | jq -c '.project[] | select(.name | contains("{{ build_project }}"))' | jq '.id' + shell: cmk listProjects | jq -c '.project[] | select(.name | contains("{{ build_project }}"))' | jq '.id' register: projectid - name: Add accounts to project - shell: "cs addAccountToProject account={{ item }} projectid={{ projectid.stdout }}" + shell: "cmk addAccountToProject account={{ item }} projectid={{ projectid.stdout }}" with_items: - "{{ allaccts_retval.stdout.split(',') }}" @@ -237,6 +240,13 @@ roles: - cloudstack-config +- hosts: localhost + connection: local + gather_facts: no + tasks: + - name: create mavin cfg file + template: src=advanced-cfg.j2 dest="./{{ env_name_clean }}-advanced-cfg" + ## update status - hosts: localhost diff --git a/Ansible/destroyvms.yml b/Ansible/destroyvms.yml index b5cb41878be..941d36f86ad 100644 --- a/Ansible/destroyvms.yml +++ b/Ansible/destroyvms.yml @@ -6,13 +6,16 @@ # gather_facts: no # tasks: # - name: Deregister Licensed XenServers -# shell: xe host-license-remove host-uuid=`xe host-list --minimal hostname=$HOSTNAME` +# shell: xe host-license-remove host-uuid=`xe host-list --minimal hostname=$HOSTNAME` # ignore_errors: true - hosts: localhost connection: local gather_facts: no tasks: + - name: Ensure cmk is pointing to the right env + shell: cmk set profile cloudstack + - include: ./tasks/removeproject.yml - hosts: primary_storage_hosts @@ -40,6 +43,7 @@ env_db_manage: DBHOST={{ env_db_ip }} DBUSER={{ env_db_user }} DBPASS={{ env_db_password }} DBNAME={{ env_db_name }} ENV_UUID={{ env_uuid }} ENV_NAME={{ env_name_clean }} ENV_COMMENT='{{ env_comment }}' ENV_ACTION=rel register: db_manage_output when: not destroy_forced + # ignore_errors: true - debug: msg: "{{ db_manage_output }}" @@ -47,6 +51,7 @@ - name: Check for environments db failure fail: msg="Environment not successfully released - {{ env_return }} {{ env_retmsg }}." when: env_return != "success" + # ignore_errors: true - name: Update inventory file - remove server IP addresses replace: diff --git a/Ansible/generate-cloudconfig.yml b/Ansible/generate-cloudconfig.yml index 92e4db70cc8..2c83fa8a750 100644 --- a/Ansible/generate-cloudconfig.yml +++ b/Ansible/generate-cloudconfig.yml @@ -174,7 +174,7 @@ versionstring: "{{ env_dotted_version }}" register: cs_version_data when: env_dotted_version is defined - + - debug: msg="{{ cs_version_data }}" - name: Check returned environment name @@ -207,12 +207,12 @@ - name: set value for additional zone if not defined set_fact: - additional_zone: no + additional_zone: no when: additional_zone is not defined - name: set value for additional pod if not defined set_fact: - additional_pod: no + additional_pod: no when: additional_pod is not defined - name: ensure existing_zone is given when env is an additional pod @@ -252,15 +252,15 @@ # messy but necessary check. - debug: - msg: "{{ env_version }}" + msg: "{{ env_cs_minor_version_string }}" - name: set mgmt java version set_fact: - java_ver: "{{ java_vers[env_version] }}" + java_ver: "{{ java_vers[env_cs_minor_version_string] }}" - debug: msg: "{{ java_ver }}" - + - name: Set mgmt os fact set_fact: mgmt_os_name: "{{ linux_os[mgmt_os].os }}" @@ -315,8 +315,11 @@ - debug: msg="{{ dbcheck }}" # now do stuff + - name: Ensure cmk is pointing to the right env + shell: cmk set profile cloudstack + - name: Capture account name - shell: cs listAccounts + shell: cmk listAccounts register: acct_retval - name: Register authenticating account @@ -361,14 +364,14 @@ - name: Build group_vars file template: src=templates/nestedgroupvars.j2 dest="{{ inventory_dir }}/group_vars/{{ env_name_clean }}" - + - name: check group_vars are OK (read in the file) shell: "cat {{ inventory_dir }}/group_vars/{{ env_name_clean }}" register: group_vars_file - + - name: check group_vars are OK (look for curly braces) fail: msg: "Curly braces found in group_vars, some var could not be evaluated. Stopping" when: group_vars_file.stdout.find("templating_succeeded") == -1 - + - debug: msg="You can now run{{":"}} ansible-playbook deployvms.yml -i ./hosts_{{ env_name_clean }} " diff --git a/Ansible/group_vars/all.sample b/Ansible/group_vars/all.sample index cff9b33db8e..3165020ab88 100644 --- a/Ansible/group_vars/all.sample +++ b/Ansible/group_vars/all.sample @@ -74,7 +74,9 @@ def_management_vm_hypervisor: "VMware" def_build_zone: "" def_build_keyboard: "uk" parent_vcenter_dc: "" -repohost: "http://" +os_repo: "http://" +sb_repo: "http://" +custom_repo: "http://" def_env_timezone: "UTC" def_use_external_hv_hosts: no def_use_phys_hosts: no @@ -147,6 +149,7 @@ def_local_storage_disk_offering: "Custom" def_local_storage_disk_size: "80" def_use_s3: no def_setshortname: no +hypervisors_on_same_host: no base_version_of_master: cs413 @@ -710,7 +713,7 @@ def_vmware_templates: vc_template: "vCenter 5.1u2d" 55u3: esxi_template: "ESXi 5.5u3" - vc_template: "vCenter 55u3" + vc_template: "vCenter 5.5u3" 60u2: esxi_template: "ESXi 6.0u2" vc_template: "vCenter 60u2" @@ -722,7 +725,7 @@ def_vmware_templates: vc_template: "vCenter 65u1" "65u2": esxi_template: "ESXi 6.5u1" - vc_template: "vCenter-65u2" + vc_template: "vCenter 65u2" "67u0": esxi_template: "ESXi 6.7.0" vc_template: "vCenter 67u0" @@ -784,6 +787,7 @@ def_marvin_tests_source: "github" def_marvin_tests_github_source: "https://github.com/apache/cloudstack" def_marvin_images_location: "http:///marvin" def_openvm_images_location: "http:///openvm" +def_cks_images_location: "http:///cks" def_fallback_marvin_test_repo: "http:///shapeblue/cloudstack/upstream/centos7/4.13/" # Webhooks for integration @@ -879,7 +883,7 @@ global_settings: - {name: "vm.destroy.forcestop", value: "true", condition: "marvin"} - {name: "vpc.max.networks", value: "5", condition: "marvin"} - {name: "router.redundant.vrrp.interval", value: "1", condition: "marvin"} - - {name: "router.aggregation.command.each.timeout", value: "10", condition: "marvin"} + - {name: "router.aggregation.command.each.timeout", value: "120", condition: "marvin"} dvswitch: - {name: "vmware.use.dvswitch", value: "true", condition: "dvswitch"} systemvmlocalstorage: diff --git a/Ansible/library/custom_allocator b/Ansible/library/custom_allocator index ea8775eb184..01032f99eb5 100644 --- a/Ansible/library/custom_allocator +++ b/Ansible/library/custom_allocator @@ -27,19 +27,28 @@ function least_cluster_mem() LOWESTCLUSTERNAME=`cmk list clusters id=$LOWESTCLUSTERID | jq -r '.cluster[] | .name'` } -function least_host() +function least_host_cpu() { - HOSTUSE=`cmk list hosts type=routing | jq '.host[]' | sed 's/\%//'` + HOSTUSE=`cmk list hosts type=routing state=Up resourcestate=Enabled | jq '.host[]' | sed 's/\%//'` LOWESTHOSTID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.cpuused|tonumber) | .[0] | .id'` LOWESTCLUSTERID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.cpuused|tonumber) | .[0] | .clusterid'` LOWESTHOSTNAME=`cmk list hosts id=$LOWESTHOSTID | jq -r '.host[] | .name'` LOWESTCLUSTERNAME=`cmk list clusters id=$LOWESTCLUSTERID | jq -r '.cluster[] | .name'` } +function least_host_mem() +{ + HOSTUSE=`cmk list hosts type=routing state=Up resourcestate=Enabled | jq '.host[]' | sed 's/\%//'` + LOWESTHOSTID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.memoryused) | .[0] | .id'` + LOWESTCLUSTERID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.memoryused) | .[0] | .clusterid'` + LOWESTHOSTNAME=`cmk list hosts id=$LOWESTHOSTID | jq -r '.host[] | .name'` + LOWESTCLUSTERNAME=`cmk list clusters id=$LOWESTCLUSTERID | jq -r '.cluster[] | .name'` +} + function least_host_in_cluster() { - HOSTUSE=`cmk list hosts type=routing clusterid=$CLUSTERID| jq '.host[]' | sed 's/\%//'` - LOWESTHOSTID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.cpuused|tonumber) | .[0] | .id'` + HOSTUSE=`cmk list hosts type=routing state=Up resourcestate=Enabled | jq '.host[]' | sed 's/\%//'` + LOWESTHOSTID=`echo $HOSTUSE | jq -r -s -c 'sort_by(.memoryused) | .[0] | .id'` LOWESTHOSTNAME=`cmk list hosts id=$LOWESTHOSTID | jq -r '.host[] | .name'` } @@ -77,13 +86,18 @@ LOWESTPODID="" ## DO STUFF case "$ALGORITHM" in - least_host) - least_host; + least_host_cpu) + least_host_cpu; + MSG="Returning lowest used host in zone" + ReturnFact; + ;; + least_host_mem) + least_host_mem; MSG="Returning lowest used host in zone" ReturnFact; ;; least_host_least_cluster) - least_cluster; + least_cluster_mem; CLUSTERID=${LOWESTCLUSTERID} least_host_in_cluster; MSG="Returning lowest used host in lowest used cluster in zone" diff --git a/Ansible/library/env_db_manage b/Ansible/library/env_db_manage index 1a2c643769c..903649427fd 100644 --- a/Ansible/library/env_db_manage +++ b/Ansible/library/env_db_manage @@ -96,9 +96,9 @@ WriteOutput "Name check - found ${env_name_count} with name ${ENV_NAME}"; # function countEnvAvailable() { - COUNTPODENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${PODTBL} WHERE inuse='FALSE' and removed IS NOT NULL"` - COUNTPUBLICENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${PUBTBL} WHERE inuse='FALSE' and removed IS NOT NULL"` - COUNTGUESTENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${GUESTTBL} WHERE inuse='FALSE' and removed IS NOT NULL"` + COUNTPODENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${PODTBL} WHERE inuse='FALSE'"` + COUNTPUBLICENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${PUBTBL} WHERE inuse='FALSE'"` + COUNTGUESTENVS=`${MYSQLCOMMAND} "SELECT COUNT(*) FROM ${DBNAME}.${GUESTTBL} WHERE inuse='FALSE'"` WriteOutput "Environments count: ${COUNTPODENVS} podnets, ${COUNTPUBLICENVS} pubnets, ${COUNTGUESTENVS} guestnets"; } diff --git a/Ansible/library/os_facts b/Ansible/library/os_facts index 2b0080eca85..da700587243 100644 --- a/Ansible/library/os_facts +++ b/Ansible/library/os_facts @@ -2,9 +2,9 @@ OS_DIST="NotFound" OS_VER="NotFound" -if [ -h "/etc/redhat-release" ]; then +if [ -e "/etc/redhat-release" ]; then OS_DIST="CentOS" - if [ "`cat cat /etc/*-release | grep 'VERSION_ID='`" == "" ]; then + if [ "`cat /etc/*-release | grep 'VERSION_ID='`" == "" ]; then OS_VER=`cat /etc/*-release | grep -i 'centos' | awk -F ' ' '{print $3}' | sed 's/\"//g' | head -1` OS_VER_MAJOR=`echo $OS_VER | awk -F '.' '{print $1}'` else @@ -31,4 +31,4 @@ cat << EOF } EOF -exit \ No newline at end of file +exit diff --git a/Ansible/roles/cloudmonkey/tasks/centos.yml b/Ansible/roles/cloudmonkey/tasks/centos.yml index b58a93e9712..b41f108f0f7 100644 --- a/Ansible/roles/cloudmonkey/tasks/centos.yml +++ b/Ansible/roles/cloudmonkey/tasks/centos.yml @@ -29,6 +29,7 @@ url: "{{ def_linux_cm_url }}" dest: /usr/bin/cmk mode: 0755 + timeout: 30 - name: link cmk to cloudmonkey file: diff --git a/Ansible/roles/cloudmonkey/tasks/centos8.yml b/Ansible/roles/cloudmonkey/tasks/centos8.yml index 05c74bf6f7b..2f5cb68ae1f 100644 --- a/Ansible/roles/cloudmonkey/tasks/centos8.yml +++ b/Ansible/roles/cloudmonkey/tasks/centos8.yml @@ -34,6 +34,7 @@ url: "{{ def_linux_cm_url }}" dest: /usr/bin/cmk mode: 0755 + timeout: 30 - name: link cmk to cloudmonkey file: diff --git a/Ansible/roles/cloudmonkey/tasks/main.yml b/Ansible/roles/cloudmonkey/tasks/main.yml index 34e54410fb8..2ee12ae2e43 100644 --- a/Ansible/roles/cloudmonkey/tasks/main.yml +++ b/Ansible/roles/cloudmonkey/tasks/main.yml @@ -23,3 +23,6 @@ - include: ./ubuntu.yml when: ansible_distribution == 'Ubuntu' + +- include: ./suse.yml + when: ansible_distribution == 'SUSE' diff --git a/Ansible/roles/cloudmonkey/tasks/suse.yml b/Ansible/roles/cloudmonkey/tasks/suse.yml new file mode 100644 index 00000000000..a02fbcd2fda --- /dev/null +++ b/Ansible/roles/cloudmonkey/tasks/suse.yml @@ -0,0 +1,46 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- name: install jq + zypper: + name: jq + state: latest + +- name: ensure cm config is removed + file: path=/root/.cloudmonkey/config state=absent + +- name: copy CloudMonkey to host + get_url: + url: "{{ def_linux_cm_url }}" + dest: /usr/bin/cmk + mode: 0755 + timeout: 30 + +- name: link cmk to cloudmonkey + file: + src: /usr/bin/cmk + dest: /usr/bin/cloudmonkey + state: link + +- name: create .cmk directory + file: + path: /root/.cmk + state: directory + mode: 0755 + +- name: base configuration + shell: "cmk set prompt 'cmk-SB>' ; cmk set log_file /var/log/cloud-cli.log ; cmk set apikey {{ cm_apikey }} ; cmk set secretkey {{ cm_secretkey }} ; cmk set url http://{{ hostvars[groups['primary_cs_manager'][0]]['ansible_ssh_host'] }}:8080/client/api" + ignore_errors: true diff --git a/Ansible/roles/cloudmonkey/tasks/ubuntu.yml b/Ansible/roles/cloudmonkey/tasks/ubuntu.yml index b4dca377f3d..bf7c0b0c2ef 100644 --- a/Ansible/roles/cloudmonkey/tasks/ubuntu.yml +++ b/Ansible/roles/cloudmonkey/tasks/ubuntu.yml @@ -15,7 +15,7 @@ #limitations under the License. - name: update apt-get - command: apt-get update + command: apt-get update - name: install setup tools and jq apt: pkg={{ item }} state=present @@ -30,6 +30,7 @@ url: "{{ def_linux_cm_url }}" dest: /usr/bin/cmk mode: 0755 + timeout: 30 - name: link cmk to cloudmonkey file: diff --git a/Ansible/roles/cloudstack-config/templates/deployzone.sh.j2 b/Ansible/roles/cloudstack-config/templates/deployzone.sh.j2 index 3390dede5d2..867221d75f6 100644 --- a/Ansible/roles/cloudstack-config/templates/deployzone.sh.j2 +++ b/Ansible/roles/cloudstack-config/templates/deployzone.sh.j2 @@ -193,7 +193,7 @@ then then WriteOutput "Adding VMware cluster." {% if env_numversion | version_compare('4.2','>') %} - cloudmonkey add cluster zoneid=${ZoneID} hypervisor='VMware' clustertype='ExternalManaged' podid=${PodID} url="http://{% if groups['vc_hosts'] | length | int > 0 %}{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}{% else %}UNDEFINED{% endif %}/{{ vmware_datacenter_name }}/{{ env_zone_clustername }}" clustername="{{ env_zone_clustername }}" vsmipaddress="{% if groups['vc_hosts'] | length | int > 0 %}{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}{% else %}UNDEFINED{% endif %}" vsmpassword='{{ vmware_vcsa_pass }}' vsmusername='{{ vmware_vcsa_user }}' | tee -i -a ${DEPLOYLOG}; + cloudmonkey add cluster zoneid=${ZoneID} hypervisor='VMware' clustertype='ExternalManaged' podid=${PodID} url="http://{% if groups['vc_hosts'] | length | int > 0 %}{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}{% else %}UNDEFINED{% endif %}/{{ vmware_datacenter_name }}/{{ env_zone_clustername }}" clustername="{{ env_zone_clustername }}" vsmipaddress="{% if groups['vc_hosts'] | length | int > 0 %}{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}{% else %}UNDEFINED{% endif %}" password='{{ vmware_vcsa_pass }}' username='{{ vmware_vcsa_user }}' vsmpassword='{{ vmware_vcsa_pass }}' vsmusername='{{ vmware_vcsa_user }}' | tee -i -a ${DEPLOYLOG}; {% else %} cloudmonkey add cluster zoneid=${ZoneID} hypervisor='VMware' clustertype='ExternalManaged' podid=${PodID} url="http://{% if groups['vc_hosts'] | length | int > 0 %}{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}{% else %}UNDEFINED{% endif %}/{{ vmware_datacenter_name }}/{{ env_zone_clustername }}" clustername="{{ env_zone_clustername }}" password='{{ vmware_vcsa_pass }}' username='{{ vmware_vcsa_user }}' | tee -i -a ${DEPLOYLOG}; {% endif %} diff --git a/Ansible/roles/cloudstack-manager/tasks/centos-ccp.yml b/Ansible/roles/cloudstack-manager/tasks/centos-ccp.yml index 28feb874b0a..e35ccba5555 100644 --- a/Ansible/roles/cloudstack-manager/tasks/centos-ccp.yml +++ b/Ansible/roles/cloudstack-manager/tasks/centos-ccp.yml @@ -27,7 +27,7 @@ when: ansible_distribution_major_version == "6" - name: download installer - get_url: url="{{ repohost }}/ccp/{{ccp_install_tarball}}.tar.gz" dest="/tmp/{{ ccp_install_tarball }}.tar.gz" + get_url: url="{{ sb_repo }}/ccp/{{ccp_install_tarball}}.tar.gz" dest="/tmp/{{ ccp_install_tarball }}.tar.gz" - name: extract tarball unarchive: src="/tmp/{{ ccp_install_tarball }}.tar.gz" dest=/tmp copy=no diff --git a/Ansible/roles/cloudstack-manager/tasks/centos.yml b/Ansible/roles/cloudstack-manager/tasks/centos.yml index 6f29018da15..258cdc53ad0 100644 --- a/Ansible/roles/cloudstack-manager/tasks/centos.yml +++ b/Ansible/roles/cloudstack-manager/tasks/centos.yml @@ -7,8 +7,8 @@ file: path=/etc/hostname state=absent when: ansible_distribution_major_version == "7" -- name: ensure yum cache is cleared - shell: command="yum clean all" +- name: Clear all yum cache + command: yum clean all - name: Set selinux to permissive command: setenforce permissive @@ -42,7 +42,7 @@ when: force_java -- debug: +- debug: msg: "env_cs_distribution - {{ env_cs_distribution }}" - include: ./centos-acs.yml when: env_cs_distribution == "cs" diff --git a/Ansible/roles/cloudstack-manager/tasks/centos8.yml b/Ansible/roles/cloudstack-manager/tasks/centos8.yml index cf4d6aab50c..71221e7a294 100644 --- a/Ansible/roles/cloudstack-manager/tasks/centos8.yml +++ b/Ansible/roles/cloudstack-manager/tasks/centos8.yml @@ -20,8 +20,12 @@ - name: Ensure selinux is set permanently selinux: policy=targeted state=permissive +- name: get name of eth0 connection + shell: nmcli device show eth0 | grep 'GENERAL.CONNECTION' | awk -F ':' '{print $2}' | sed 's/^ *//' + register: eth0_name + - name: disable ipv6 - command: nmcli connection modify eth0 ipv6.method ignore + command: nmcli connection modify '{{ eth0_name.stdout }}' ipv6.method ignore - name: change cockpit port lineinfile: @@ -47,12 +51,20 @@ - "8443" - "9090" +- name: Stop firewalld CentOS8 + service: + name=firewalld + state=stopped + enabled=no + when: ( ansible_distribution_major_version|int == 8 ) and (use_firewalld|bool == False) + - name: set dnf repo to local template: src="{{ inventory_dir }}/templates/{{ item }}.j2" dest="/etc/yum.repos.d/{{item}}" with_items: - "epel.repo" - - "CentOS8-Base.repo" - - "CentOS-AppStream.repo" + +- name: Clear all dnf cache + command: dnf clean all - name: Ensure CA Certs are latest dnf: name=ca-certificates state=latest enablerepo=base @@ -119,5 +131,8 @@ # when: (num_marv_hosts > 0) and (ansible_distribution_major_version == "7") # Workaround for https://github.com/apache/cloudstack/issues/4204 -- name: Patch ipmitool yo ipmitool-1.8.18-12.el8_1.x86_64.rpm - shell: "rpm -i https://rpmfind.net/linux/centos/8.1.1911/AppStream/x86_64/os/Packages/ipmitool-1.8.18-12.el8_1.x86_64.rpm --force" +- name: Patch ipmitool to ipmitool-1.8.18-12.el8_1.x86_64.rpm + shell: "dnf install -y {{ sb_repo }}/ipmi/{{ ipmitool_binary }}" + +- name: Upgrade gcrypt library on CentOS 8 MS + dnf: name=libgcrypt state=present \ No newline at end of file diff --git a/Ansible/roles/cloudstack-manager/tasks/main.yml b/Ansible/roles/cloudstack-manager/tasks/main.yml index 68e3fb8f241..b1debd44b6d 100644 --- a/Ansible/roles/cloudstack-manager/tasks/main.yml +++ b/Ansible/roles/cloudstack-manager/tasks/main.yml @@ -32,19 +32,32 @@ - name: now i'm connected, get facts os_facts: +# For some weird reason, it thinks SUSE is Ubuntu +- name: Check if SUSE + shell: cat /etc/os-release | grep -i suse + register: result + when: ansible_distribution == 'Ubuntu' + ignore_errors: yes + +- name: Set distro as SUSE + set_fact: + ansible_distribution: "SUSE" + when: ansible_distribution == 'Ubuntu' and result is succeeded + - include: ./centos.yml when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int < 8 ) - include: ./centos8.yml when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int == 8 ) +- include: ./suse.yml + when: ansible_distribution == 'SUSE' - include: ./ubuntu.yml when: ansible_distribution == 'Ubuntu' tags: - "global_settings" - - name: copy cloudutil script to /usr/bin copy: src: cloudutil diff --git a/Ansible/roles/cloudstack-manager/tasks/preconfig_globalsettings.yml b/Ansible/roles/cloudstack-manager/tasks/preconfig_globalsettings.yml index 6872d70b113..a5dfb0ac102 100644 --- a/Ansible/roles/cloudstack-manager/tasks/preconfig_globalsettings.yml +++ b/Ansible/roles/cloudstack-manager/tasks/preconfig_globalsettings.yml @@ -43,7 +43,7 @@ when: xs_ver not in xs_dyn_scaling_ok_vers and ("primary_cs_manager" in group_names) tags: - "global_settings" - + - name: Boost SSVM offering when using VMWare acs_mysql_update: DBHOST="{{ mysql_master_ip }}" DBUSER="cloud" DBPASS={{ mysql_cloud_password }} MYSQL_STATEMENT="UPDATE cloud.service_offering SET {{ item.field}}='{{ item.value }}' WHERE vm_type='secondarystoragevm';" @@ -57,7 +57,7 @@ - name: Set SSVM to use jumbo frames when using vmware acs_mysql_update: DBHOST="{{ mysql_master_ip }}" DBUSER="cloud" DBPASS={{ mysql_cloud_password }} MYSQL_STATEMENT="UPDATE cloud.configuration SET value='{{ item.value }}' WHERE name='{{ item.name }}';" with_items: - - {name: "secstorage.vm.mtu.size", value: "4500"} + - {name: "secstorage.vm.mtu.size", value: "1500"} when: ( env_hv == "vmware" ) tags: - "global_settings" diff --git a/Ansible/roles/cloudstack-manager/tasks/setup-mgmt.yml b/Ansible/roles/cloudstack-manager/tasks/setup-mgmt.yml index 5b6a4aaec31..b5eef32de45 100644 --- a/Ansible/roles/cloudstack-manager/tasks/setup-mgmt.yml +++ b/Ansible/roles/cloudstack-manager/tasks/setup-mgmt.yml @@ -8,9 +8,6 @@ tags: - setup_mgmt -- name: now i'm connected, get facts - os_facts: - - debug: msg: "cloudstack not cloud is {{ path_is_cloudstack.stat.exists }} and the OS version is {{ ansible_distribution_major_version }}" @@ -50,7 +47,11 @@ tags: - setup_mgmt - +- name: Setup CloudStack Manager (SUSE) + shell: sleep {{ play_hosts.index(inventory_hostname) | int * 15 }} && /usr/bin/cloudstack-setup-management + when: ansible_distribution == "SUSE" + tags: + - setup_mgmt - name: Setup CloudStack Manager (Ubuntu) shell: sleep {{ play_hosts.index(inventory_hostname) | int * 15 }} && /usr/bin/cloudstack-setup-management diff --git a/Ansible/roles/cloudstack-manager/tasks/suse-acs.yml b/Ansible/roles/cloudstack-manager/tasks/suse-acs.yml new file mode 100644 index 00000000000..aaf7d118906 --- /dev/null +++ b/Ansible/roles/cloudstack-manager/tasks/suse-acs.yml @@ -0,0 +1,54 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- name: "Setup Apache Cloudstack Repo file. baseurl={{ baseurl_cloudstack }} " + template: src=cloudstack.repo.j2 dest=/etc/zypp/repos.d/cloudstack.repo + +- name: Ensure CloudStack packages are installed + zypper: + name: + - "{{ cloudstack_management_package }}*" + - "{{ cloudstack_common_package }}*" + state: present + +- name: Ensure MySQL Client is present + zypper: + name: mysql + state: present + +- name: Fix messed up python mysql ssl libs + copy: + src: /usr/lib64/libssl.so.1.1 + dest: /usr/lib64/python3.6/site-packages/mysql-vendor/libssl.so.1.1 + remote_src: yes + +- name: Fix messed up python mysql crypto libs + copy: + src: /usr/lib64/libcrypto.so.1.1 + dest: /usr/lib64/python3.6/site-packages/mysql-vendor/libcrypto.so.1.1 + remote_src: yes + +- name: Ensure vhd-util is present + get_url: url="{{ vhdutil_url }}" dest=/usr/share/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util mode=0755 + +- name: Ensure CloudStack Usage Service is installed + zypper: name="{{ cloudstack_usage_package }}*" state=present + +- include: ./setupdb.yml + +- name: Start cloudstack-usage service + service: name=cloudstack-usage state=started enabled=yes + diff --git a/Ansible/roles/cloudstack-manager/tasks/suse.yml b/Ansible/roles/cloudstack-manager/tasks/suse.yml new file mode 100644 index 00000000000..3b793a0de3d --- /dev/null +++ b/Ansible/roles/cloudstack-manager/tasks/suse.yml @@ -0,0 +1,101 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- debug: + msg: "SUSE Specific Management Server Build" + +- name: Ensure selinux python bindings are installed (Ansible requirement) + zypper: + name: python3-selinux + state: present + ignore_errors: yes + +- name: Set selinux to permissive + command: setenforce permissive + changed_when: false + ignore_errors: yes + +- name: Ensure selinux is set permanently + selinux: policy=targeted state=permissive + ignore_errors: yes + +- name: Allow connections on management server required ports with firewall + shell: "firewall-cmd --zone=public --add-port={{ item }}/tcp --permanent" + with_items: + - "3306" + - "8080" + - "8096" + - "8250" + - "8443" + - "9090" + ignore_errors: yes + +- name: Stop firewalld SUSE + service: + name: firewalld + state: stopped + enabled: no + when: use_firewalld|bool == False + +- name: Ensure CA Certs are latest + zypper: name=ca-certificates state=latest + +- name: install rng-tools to get entropy + zypper: name=haveged state=present + +- name: determine number of db hosts + set_fact: num_xen_hosts="{{ groups['xenserver_hosts'] | length }}" + +- name: update lvm2 as fix for bugzilla.redhat.com/show_bug.cgi?id=1294128 + zypper: name=lvm2 state=latest + +- name: install qemu-tools + zypper: name=qemu-tools state=present + +- debug: msg="Set Java on VM" +- set_fact: java_ver="{{ mgmt_java_ver }}" +- set_fact: java_path="{{ mgmt_java_path }}" +- include: ../../../tasks/set_java.yml + when: force_java + +- debug: + msg: "env_cs_distribution - {{ env_cs_distribution }}" +- include: ./suse-acs.yml + when: env_cs_distribution == "cs" + +# Don't really need suse support for ccp + +- name: ensure rpcbind in installed + zypper: + name: rpcbind + state: present + +- name: ensure rpcbind in started + service: + name: rpcbind + state: started + enabled: yes + +- debug: msg="Some Marvin Stuff" + when: (num_marv_hosts > 0) + +- name: Ensure sshpass is installed + zypper: name=sshpass state=present + when: (num_marv_hosts > 0) + +- name: Open 8096 when Marvin is required + shell: "iptables -I INPUT -p tcp -m tcp --dport 8096 -j ACCEPT && iptables-save > /etc/sysconfig/iptables" + when: (num_marv_hosts > 0) diff --git a/Ansible/roles/cloudstack-manager/tasks/ubuntu.yml b/Ansible/roles/cloudstack-manager/tasks/ubuntu.yml index 010e29d2d2a..50e4242f17d 100644 --- a/Ansible/roles/cloudstack-manager/tasks/ubuntu.yml +++ b/Ansible/roles/cloudstack-manager/tasks/ubuntu.yml @@ -65,12 +65,21 @@ - name: Add CloudStack repository into sources list. shell: echo "deb {{ baseurl_cloudstack }} /" > /etc/apt/sources.list.d/cloudstack.list - when: ansible_distribution_major_version|int == 20 + when: ansible_distribution_major_version|int >= 20 - name: Run the equivalent of "apt-get update" as a separate step apt: update_cache: yes +- name: Remove package unattended-upgrades + apt: + pkg: "{{ item }}" + state: absent + force: true + with_items: + - unattended-upgrades + ignore_errors: yes + - name: Ensure CloudStack management-server only is installed (we install usage server later) apt: pkg: "{{ item }}" diff --git a/Ansible/roles/cloudstack-manager/templates/CentOS-AppStream.repo.j2 b/Ansible/roles/cloudstack-manager/templates/CentOS-AppStream.repo.j2 index 39fcdfeec9a..abaeb607f4c 100644 --- a/Ansible/roles/cloudstack-manager/templates/CentOS-AppStream.repo.j2 +++ b/Ansible/roles/cloudstack-manager/templates/CentOS-AppStream.repo.j2 @@ -13,7 +13,7 @@ [AppStream] name=CentOS-$releasever - AppStream #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra -baseurl=http://{{ repohost }}/centos/$releasever/AppStream/$basearch/os/ +baseurl=http://{{ os_repo }}/centos/$releasever/AppStream/$basearch/os/ gpgcheck=0 enabled=1 diff --git a/Ansible/roles/cloudstack-manager/templates/CentOS-Base.repo.j2 b/Ansible/roles/cloudstack-manager/templates/CentOS-Base.repo.j2 index 63744ff28c5..6ffbc93b88b 100644 --- a/Ansible/roles/cloudstack-manager/templates/CentOS-Base.repo.j2 +++ b/Ansible/roles/cloudstack-manager/templates/CentOS-Base.repo.j2 @@ -13,7 +13,7 @@ [base] name=CentOS-$releasever - Base #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os -baseurl=http://{{ repohost }}/centos/$releasever/os/$basearch/ +baseurl=http://{{ os_repo }}/centos/$releasever/os/$basearch/ gpgcheck=0 enabled = {{ base_repo_enabled }} @@ -21,7 +21,7 @@ enabled = {{ base_repo_enabled }} [updates] name=CentOS-$releasever - Updates #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates -baseurl=http://{{ repohost }}/centos/$releasever/updates/$basearch/ +baseurl=http://{{ os_repo }}/centos/$releasever/updates/$basearch/ gpgcheck=0 enabled = {{ update_repo_enabled }} diff --git a/Ansible/roles/kvm/tasks/centos-ccp.yml b/Ansible/roles/kvm/tasks/centos-ccp.yml index f2ea8e9319c..d1ec740f63d 100644 --- a/Ansible/roles/kvm/tasks/centos-ccp.yml +++ b/Ansible/roles/kvm/tasks/centos-ccp.yml @@ -20,7 +20,7 @@ - name: download installer - get_url: url="{{ repohost }}/ccp/{{ccp_install_tarball}}.tar.gz" dest="/tmp/{{ ccp_install_tarball }}.tar.gz" + get_url: url="{{ sb_repo }}/ccp/{{ccp_install_tarball}}.tar.gz" dest="/tmp/{{ ccp_install_tarball }}.tar.gz" - name: extract tarball unarchive: src="/tmp/{{ ccp_install_tarball }}.tar.gz" dest=/tmp copy=no diff --git a/Ansible/roles/kvm/tasks/centos.yml b/Ansible/roles/kvm/tasks/centos.yml index 569d82749b3..46fd2aa317b 100644 --- a/Ansible/roles/kvm/tasks/centos.yml +++ b/Ansible/roles/kvm/tasks/centos.yml @@ -55,6 +55,11 @@ tags: - kvm +- name: ensure yum cache is cleared + command: yum clean all + tags: + - kvm + - name: Install basic utilities and tools - all versions yum: name={{ item }} state=present enablerepo=base with_items: @@ -199,6 +204,6 @@ shell: "echo {{ kvm_password }} | passwd {{ kvm_username }} --stdin" - include: ./centos_elrepokernel.yml - when: kvm_install_elrepo_kernel + when: kvm_install_elrepo_kernel tags: - kvm \ No newline at end of file diff --git a/Ansible/roles/kvm/tasks/centos8.yml b/Ansible/roles/kvm/tasks/centos8.yml index 1f69cf85a19..efba23765c6 100644 --- a/Ansible/roles/kvm/tasks/centos8.yml +++ b/Ansible/roles/kvm/tasks/centos8.yml @@ -21,6 +21,11 @@ tags: - kvm +- name: Clear all dnf cache + command: dnf clean all + tags: + - kvm + - name: change cockpit port lineinfile: path: /usr/lib/systemd/system/cockpit.socket @@ -45,10 +50,6 @@ local_action: wait_for port=22 host="{{ ansible_ssh_host }}" timeout={{ ssh_retries }} connect_timeout=5 when: (not use_phys_hosts) -- name: Now Im connected, get facts - setup: - when: (not use_phys_hosts) - - include: ./kvm_networking_phys_host.yml when: use_phys_hosts @@ -56,8 +57,6 @@ template: src="{{ inventory_dir }}/templates/{{ item }}.j2" dest="/etc/yum.repos.d/{{item}}" with_items: - "epel.repo" - - "CentOS8-Base.repo" - - "CentOS-AppStream.repo" tags: - kvm @@ -122,6 +121,9 @@ - include: ../../../tasks/set_java.yml when: force_java +- name: Upgrade gcrypt library on CentOS 8 KVM hosts + shell: "dnf install -y libgcrypt" + - include: ./centos-acs.yml when: env_cs_distribution == "cs" @@ -146,6 +148,9 @@ - kvm - kvm-agent +- name: Mask libvirtd sockets + shell: systemctl mask libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket libvirtd-tls.socket libvirtd-tcp.socket + - name: Update /etc/libvirt/qemu.conf lineinfile: dest=/etc/libvirt/qemu.conf regexp='vnc_listen' line='vnc_listen = "0.0.0.0"' state=present tags: diff --git a/Ansible/roles/kvm/tasks/centos_elrepokernel.yml b/Ansible/roles/kvm/tasks/centos_elrepokernel.yml index 4466d761058..020d31e3805 100644 --- a/Ansible/roles/kvm/tasks/centos_elrepokernel.yml +++ b/Ansible/roles/kvm/tasks/centos_elrepokernel.yml @@ -18,9 +18,6 @@ # Proprietary and confidential # Released by ShapeBlue , April 2014 -- name: Now I'm connected, get facts - setup: - - name: Setup ELrepo-kernel yum repository template: src=elrepo.repo.j2 dest=/etc/yum.repos.d/elrepo.repo diff --git a/Ansible/roles/kvm/tasks/kvm_networking_bridge8.yml b/Ansible/roles/kvm/tasks/kvm_networking_bridge8.yml index c700c10c02e..0cb6041a5c5 100644 --- a/Ansible/roles/kvm/tasks/kvm_networking_bridge8.yml +++ b/Ansible/roles/kvm/tasks/kvm_networking_bridge8.yml @@ -31,9 +31,6 @@ fi become: true -- name: Now Im connected, get facts - os_facts: - - name: Create {{ kvm_mgmt_network_label }} bridge interface command: nmcli con add ifname {{ kvm_mgmt_network_label }} type bridge con-name {{ kvm_mgmt_network_label }} autoconnect yes @@ -76,19 +73,33 @@ - name: delete old eth1 command: nmcli connection delete '{{ eth1_name.stdout }}' + when: eth1_name.stdout != "--" - pause: seconds: 2 -- name: Add interfaces to bridge +- name: Configure eth1 (Advanced Networking) command: nmcli con add type bridge-slave ifname eth1 master {{ kvm_guest_network_label }} autoconnect yes con-name br-eth1 + when: ("{{ env_zonetype | lower }}" == "advanced") + +- name: Configure eth1 (Basic Networking) + command: nmcli con add type ethernet ifname eth1 autoconnect yes con-name br-eth1 ipv4.method disabled ipv6.method ignore + when: ("{{ env_zonetype | lower }}" == "basic") + +- name: Configure eth1.vlan (Basic Networking) + command: nmcli con add type vlan ifname eth1.{{ hostvars['localhost']['env_guestnetvlan'] }} dev eth1 autoconnect yes id {{ hostvars['localhost']['env_guestnetvlan'] }} master {{ kvm_guest_network_label }} con-name br-eth1.{{ hostvars['localhost']['env_guestnetvlan'] }} + when: ("{{ env_zonetype | lower }}" == "basic") - pause: seconds: 2 - -- name: Bring up interface + +- name: Bring up eth1 command: nmcli connection up br-eth1 +- name: Bring up eth1.vlan + command: nmcli connection up br-eth1.{{ hostvars['localhost']['env_guestnetvlan'] }} + when: ("{{ env_zonetype | lower }}" == "basic") + - pause: seconds: 2 diff --git a/Ansible/roles/kvm/tasks/kvm_networking_bridge_suse.yml b/Ansible/roles/kvm/tasks/kvm_networking_bridge_suse.yml new file mode 100644 index 00000000000..ce558966d32 --- /dev/null +++ b/Ansible/roles/kvm/tasks/kvm_networking_bridge_suse.yml @@ -0,0 +1,35 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- name: Configure eth0 + template: src=kvm-suse-eth0.j2 dest=/etc/sysconfig/network/ifcfg-eth0 + +- name: Configure bridge 1 + template: src=kvm-suse-cloudbr0.j2 dest="/etc/sysconfig/network/ifcfg-{{ kvm_mgmt_network_label }}" + +- name: Configure eth1 + template: src=kvm-suse-eth1.j2 dest=/etc/sysconfig/network/ifcfg-eth1 + +- name: Configure eth1.vlan (Basic Networking) + template: src=kvm-suse-eth1-basic-vlan.j2 dest=/etc/sysconfig/network/ifcfg-eth1.{{ hostvars['localhost']['env_guestnetvlan'] }} + when: ("{{ env_zonetype | lower }}" == "basic") + +- name: Configure bridge 2 + template: src=kvm-suse-cloudbr1.j2 dest="/etc/sysconfig/network/ifcfg-{{ kvm_guest_network_label }}" + +- name: restart networking + service: name=network state=restarted + ignore_errors: true diff --git a/Ansible/roles/kvm/tasks/kvm_networking_ovs_suse.yml b/Ansible/roles/kvm/tasks/kvm_networking_ovs_suse.yml new file mode 100644 index 00000000000..6b278132402 --- /dev/null +++ b/Ansible/roles/kvm/tasks/kvm_networking_ovs_suse.yml @@ -0,0 +1,99 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- name: get OS facts + setup: + +- name: Blacklist bridge module + template: src=bridge-blacklist.j2 dest="/etc/modprobe.d/bridge-blacklist.conf" + +- name: Install OVS + zypper: name={{ item }} state=present + with_items: + - openvswitch + - openvswitch-switch + +- name: Start OVS + systemd: + name: openvswitch + state: started + enabled: yes + +- name: Configure eth0 + template: src=kvm-suse-eth0.j2 dest=/etc/sysconfig/network/ifcfg-eth0 + +- name: Configure eth1 + template: src=kvm-suse-eth1.j2 dest=/etc/sysconfig/network/ifcfg-eth1 + +- name: Configure bridges - advanced networking + template: src=kvm-suse-ovs-bridges.j2 dest=/etc/sysconfig/network/ifcfg-{{ item.bridge }} + with_items: + - { bridge: "{{ kvm_mgmt_network_label }}", bootproto: static, port: eth0 } + - { bridge: "{{ kvm_guest_network_label }}", bootproto: none, port: eth1 } + - { bridge: "cloud0", bootproto: static } + +- name: Set default gateway for {{ kvm_mgmt_network_label }} + lineinfile: + path: /etc/sysconfig/network/routes + create: yes + regexp: default + line: default {{ ansible_default_ipv4.gateway }} - {{ kvm_mgmt_network_label }} + +- name: Get the dns servers + shell: grep 'nameserver' /etc/resolv.conf | sed 's/nameserver //g' | tr '\n' ' ' + register: dns_servers + +- name: Get the dns search list + shell: grep 'search' /etc/resolv.conf | sed 's/search //g' + register: dns_search_list + +- name: Set the dns server + lineinfile: + path: /etc/sysconfig/network/config + regexp: NETCONFIG_DNS_STATIC_SERVERS= + line: NETCONFIG_DNS_STATIC_SERVERS='{{ dns_servers.stdout }}' + +- name: Set the dns search list + lineinfile: + path: /etc/sysconfig/network/config + regexp: NETCONFIG_DNS_STATIC_SEARCHLIST= + line: NETCONFIG_DNS_STATIC_SEARCHLIST='{{ dns_search_list.stdout }}' + +- name: Set static hostname + shell: /usr/bin/hostnamectl set-hostname --static --transient --pretty {{ inventory_hostname }} + +- name: Configure sysctl.conf for OVS + lineinfile: + path: /etc/sysctl.conf + line: "{{ item }}" + with_items: + - "net.ipv4.ip_forward=1" + - "net.ipv4.conf.default.rp_filter=0" + - "net.ipv4.conf.all.rp_filter=0" + - "net.ipv6.conf.all.disable_ipv6=1" + - "net.ipv6.conf.default.disable_ipv6=1" + +- name: Reboot KVM host to implement new networking (reboot scheduled in 1min) + command: /sbin/shutdown -r +1 "Ansible-triggered Reboot" + async: 0 + poll: 0 + +- name: Reboot KVM host to implement new networking (wait for server to restart) + wait_for_connection: + delay: 120 + sleep: 5 + timeout: 900 + connect_timeout: 2 diff --git a/Ansible/roles/kvm/tasks/main.yml b/Ansible/roles/kvm/tasks/main.yml index fbf0ec6c3de..c8ce9278ec6 100644 --- a/Ansible/roles/kvm/tasks/main.yml +++ b/Ansible/roles/kvm/tasks/main.yml @@ -39,6 +39,18 @@ tags: - kvm +# For some weird reason, it thinks SUSE is Ubuntu +- name: Check if SUSE + shell: cat /etc/os-release | grep -i suse + register: result + when: ansible_distribution == 'Ubuntu' + ignore_errors: yes + +- name: Set distro as SUSE + set_fact: + ansible_distribution: "SUSE" + when: ansible_distribution == 'Ubuntu' and result is succeeded + #- name: retrieve environment data # env_db_manage: DBHOST={{ env_db_ip }} DBUSER={{ env_db_user }} DBPASS={{ env_db_password }} DBNAME={{ env_db_name }} ENV_NAME={{ env_name_clean }} ENV_ZONETYPE={{ env_zonetype }} ENV_SECGROUPS={{ env_zone_secgroups }} ENV_ACTION=retrieve # tags: @@ -61,7 +73,11 @@ tags: - kvm - +- name: Configure SUSE VMs for KVM + include: ./suse.yml + when: ansible_distribution == 'SUSE' + tags: + - kvm - name: Configure Ubuntu VMs for KVM include: ./ubuntu.yml diff --git a/Ansible/roles/kvm/tasks/suse-acs.yml b/Ansible/roles/kvm/tasks/suse-acs.yml new file mode 100644 index 00000000000..b8f1c8a043a --- /dev/null +++ b/Ansible/roles/kvm/tasks/suse-acs.yml @@ -0,0 +1,45 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. +# Copyright (C) ShapeBlue Ltd - All Rights Reserved +# Unauthorized copying of this file, via any medium is strictly prohibited +# Proprietary and confidential +# Released by ShapeBlue , April 2014 + +- name: Ensure the Apache Cloudstack Repo file is configured + template: src=cloudstack.repo.j2 dest=/etc/zypp/repos.d/cloudstack.repo + tags: + - kvm + - kvm-agent + +- name: Ensure CloudStack packages are installed + zypper: + name: + - "{{ cloudstack_agent_package }}*" + - "{{ cloudstack_common_package }}*" + state: present + update_cache: yes + tags: + - kvm + - kvm-agent + +- name: Configure agent.properties for OVS + lineinfile: + path: /etc/cloudstack/agent/agent.properties + line: "{{ item }}" + with_items: + - "network.bridge.type=openvswitch" + - "libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.OvsVifDriver" + when: kvm_network_mode == "ovs" diff --git a/Ansible/roles/kvm/tasks/suse.yml b/Ansible/roles/kvm/tasks/suse.yml new file mode 100644 index 00000000000..e359096c6d6 --- /dev/null +++ b/Ansible/roles/kvm/tasks/suse.yml @@ -0,0 +1,194 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- debug: + msg: "SUSE Specific KVM host Build" + +- name: Ensure selinux python bindings are installed (Ansible requirement) + zypper: + name: python3-selinux + state: present + tags: + - kvm + ignore_errors: yes + +- name: Set selinux to permissive + command: setenforce permissive + changed_when: false + tags: + - kvm + ignore_errors: yes + +- name: Ensure selinux is set permanently + selinux: policy=targeted state=permissive + tags: + - kvm + ignore_errors: yes + +- include: ./kvm_networking_bridge_suse.yml + when: (not use_phys_hosts) and (kvm_network_mode == "bridge") + +- include: ./kvm_networking_ovs_suse.yml + when: (not use_phys_hosts) and (kvm_network_mode == "ovs") + +- name: wait for ssh + local_action: wait_for port=22 host="{{ ansible_ssh_host }}" timeout={{ ssh_retries }} connect_timeout=5 + when: (not use_phys_hosts) + +- name: Now Im connected, get facts + setup: + when: (not use_phys_hosts) + +# Don't really need suse for phy hosts + +- name: Install basic utilities and tools - all versions + zypper: name={{ item }} state=present update_cache=yes + with_items: + - bind-utils + - openssh + - pciutils + - telnet + - tcpdump + - traceroute + - nano + - iftop + - rpcbind + - parted + - vim + tags: + - kvm + +- name: install python-argparse + pip: + name: argparse + state: present + tags: + - kvm + +- name: Disable firewalld + service: + name=firewalld + state=stopped + enabled=no + +- name: Check if AMD processors + shell: "sed -ne '/^flags/s/^.*: //p' /proc/cpuinfo | egrep -q '(vmx)'" + register: amd_virt + ignore_errors: true + +- name: Ignore msrs if amd processors present on host + shell: echo 1 > /sys/module/kvm/parameters/ignore_msrs + when: amd_virt.rc == 1 + +- include: ./add_local_storage.yml + when: use_local_storage + tags: + - kvm + +- name: ensure rpcbind in started + service: name=rpcbind state=started enabled=yes + +- debug: msg="Set Java on VM" +- set_fact: java_ver="{{ kvm_java_ver }}" +- set_fact: java_path="{{ kvm_java_path }}" +- include: ../../../tasks/set_java.yml + when: force_java + +- include: ./suse-acs.yml + when: env_cs_distribution == "cs" + +# Don't really need suse support for ccp + +- name: Update libvirtd.conf - listen_tls + lineinfile: dest=/etc/libvirt/libvirtd.conf regexp={{ item.regexp }} line={{ item.line }} state=present + with_items: + - { regexp: "listen_tls", line: "listen_tls = 0" } + - { regexp: "listen_tcp", line: "listen_tcp = 1" } + - { regexp: "tcp_port", line: "tcp_port = \"16509\"" } + - { regexp: "auth_tcp", line: "auth_tcp = \"none\"" } + - { regexp: "mdns_adv", line: "mdns_adv = 0" } + tags: + - kvm + - kvm-agent + +- name: Update /etc/sysconfig/libvirtd - LIBVIRTD_ARGS + lineinfile: dest=/etc/sysconfig/libvirtd regexp='LIBVIRTD_ARGS' line='LIBVIRTD_ARGS="--listen"' state=present + tags: + - kvm + - kvm-agent + +- name: Mask libvirtd sockets + shell: systemctl mask libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket libvirtd-tls.socket libvirtd-tcp.socket + +- name: Update /etc/libvirt/qemu.conf + lineinfile: dest=/etc/libvirt/qemu.conf regexp='vnc_listen' line='vnc_listen = "0.0.0.0"' state=present + tags: + - kvm + - kvm-agent + +- name: Add iptables rules + shell: "iptables -I INPUT -p tcp -m tcp --dport {{ item }} -j ACCEPT" + with_items: + - "22" + - "1798" + - "16509" + - "5900:6100" + - "49152:49216" + when: not use_firewalld + tags: + - kvm + - kvm-agent + +- name: Add iptables rules + shell: "firewall-cmd --zone=public --add-port={{ item }}/tcp --permanent" + with_items: + - "22" + - "1798" + - "16509" + - "5900-6100" + - "49152-49216" + when: use_firewalld + tags: + - kvm + - kvm-agent + +- name: IPtables save config + shell: "iptables-save > /etc/sysconfig/iptables" + when: not use_firewalld + tags: + - kvm + - kvm-agent + +- name: load updated config + shell: "firewall-cmd --reload" + when: use_firewalld + tags: + - kvm + - kvm-agent + +- name: KVM libvirtd restarted + service: name=libvirtd state=restarted + tags: + - kvm + - kvm-agent + +- name: Check for authorized_keys presence + stat: path=/root/.ssh/authorized_keys + register: authkeys_present + +- name: Enable the root user because Cloudstack uses root account to add host + shell: "sed -i 's/^.*\\(ssh-rsa .*$\\)/\\1/' /root/.ssh/authorized_keys" + when: authkeys_present.stat.exists == True diff --git a/Ansible/roles/kvm/tasks/ubuntu.yml b/Ansible/roles/kvm/tasks/ubuntu.yml index f98e0e3a9ea..f354f860a50 100644 --- a/Ansible/roles/kvm/tasks/ubuntu.yml +++ b/Ansible/roles/kvm/tasks/ubuntu.yml @@ -34,7 +34,7 @@ when: ansible_distribution_version|version_compare('18.04','==') - apt_key: - url: "{{ repohost }}/release.asc" + url: "{{ os_repo }}/release.asc" state: present - apt_key: @@ -57,6 +57,16 @@ apt: update_cache: yes +- name: Remove package unattended-upgrades + apt: + pkg: "{{ item }}" + state: absent + force: true + with_items: + - unattended-upgrades + ignore_errors: yes + + - name: Install basic utilities and tools - all OS versions apt: pkg: "{{ item }}" @@ -131,7 +141,7 @@ - name: netplan on Ubuntu 18 onwards block: - + - name: write netplan shell: rm -rf /etc/netplan/* @@ -221,7 +231,7 @@ - name: add CloudStack ubuntu repo keys apt_key: - url: "{{ baseurl_cloudstack }}Release.gpg" + url: "{{ baseurl_kvm }}Release.gpg" state: present ignore_errors: yes @@ -236,15 +246,15 @@ - name: Add CloudStack repository into sources list. apt_repository: - repo: 'deb "{{ baseurl_cloudstack }}" /' + repo: 'deb "{{ baseurl_kvm }}" /' state: present validate_certs: no ignore_errors: yes when: ansible_distribution_version|version_compare('20.04','<') - name: Add CloudStack repository into sources list. - shell: echo "deb {{ baseurl_cloudstack }} /" > /etc/apt/sources.list.d/cloudstack.list - when: ansible_distribution_version|version_compare('20.04','==') + shell: echo "deb {{ baseurl_kvm }} /" > /etc/apt/sources.list.d/cloudstack.list + when: ansible_distribution_version|version_compare('20.04','>=') - name: Run the equivalent of "apt-get update" as a separate step apt: @@ -316,7 +326,14 @@ dest: "/etc/default/libvirtd" regexp: '.*libvirtd_opts=*' line: 'libvirtd_opts="-l"' - when: ansible_distribution_version|version_compare('16.04','>=') + when: ansible_distribution_version|version_compare('16.04','>=') and ansible_distribution_version|version_compare('22.04','<') + +- name: Update /etc/default/libvirtd in Ubuntu 22.04 + lineinfile: + dest: "/etc/default/libvirtd" + regexp: '^LIBVIRTD_ARGS=*' + line: 'LIBVIRTD_ARGS="-l"' + when: ansible_distribution_version|version_compare('22.04','>=') #- name: Updated /etc/init/libvirt-bin.conf # lineinfile: dest=/etc/init/libvirt-bin.conf regexp='env libvirtd_opts="-d"' line='env libvirtd_opts="-d -l"' @@ -369,9 +386,9 @@ - name: wait for ssh local_action: wait_for port=22 host="{{ ansible_ssh_host }}" timeout={{ ssh_retries }} connect_timeout=5 when: (not use_phys_hosts) - + # Kernel 5.8+, because the stock kernel + EPYC CPU = can't start any VM on the host - include: ./ubuntu_custom_kernel.yml - when: ansible_distribution_version|version_compare('20.04','>=') + when: ansible_distribution_version|version_compare('20.04','==') tags: - kvm diff --git a/Ansible/roles/kvm/tasks/ubuntu_custom_kernel.yml b/Ansible/roles/kvm/tasks/ubuntu_custom_kernel.yml index 9475fbbca63..8bb6074f681 100644 --- a/Ansible/roles/kvm/tasks/ubuntu_custom_kernel.yml +++ b/Ansible/roles/kvm/tasks/ubuntu_custom_kernel.yml @@ -1,16 +1,16 @@ --- - name: Download kernel DEB packages - shell: /usr/bin/wget http://10.2.0.4/custom-kernels/{{ item }} -P /tmp + shell: /usr/bin/wget http://10.0.3.122/custom-kernels/{{ item }} -P /tmp with_items: - linux-headers-5.9.0-050900_5.9.0-050900.202010112230_all.deb - linux-headers-5.9.0-050900-generic_5.9.0-050900.202010112230_amd64.deb - linux-image-unsigned-5.9.0-050900-generic_5.9.0-050900.202010112230_amd64.deb - linux-modules-5.9.0-050900-generic_5.9.0-050900.202010112230_amd64.deb - + - name: Install kernel DEB packages shell: /usr/bin/dpkg -i /tmp/linux-*.deb - + - name: Reboot KVM host to load new kernel shell: /sbin/reboot async: 0 diff --git a/Ansible/roles/kvm/templates/interfaces.j2 b/Ansible/roles/kvm/templates/interfaces.j2 index 5adf4637b04..6777952a8b8 100644 --- a/Ansible/roles/kvm/templates/interfaces.j2 +++ b/Ansible/roles/kvm/templates/interfaces.j2 @@ -19,7 +19,7 @@ iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet manual - mtu 4500 + mtu 1500 auto eth1 {% if env_zonetype | lower == "advanced" %} iface eth1 inet manual @@ -34,7 +34,7 @@ iface cloudbr0 inet dhcp bridge_fd 5 bridge_stp off bridge_maxwait 1 - mtu 4500 + mtu 1500 # Public network auto cloudbr1 @@ -47,4 +47,4 @@ iface cloudbr1 inet manual bridge_fd 5 bridge_stp off bridge_maxwait 1 - + diff --git a/Ansible/roles/kvm/templates/kvm-cloudbr0.j2 b/Ansible/roles/kvm/templates/kvm-cloudbr0.j2 index f98611095f7..21c0bc8eb04 100644 --- a/Ansible/roles/kvm/templates/kvm-cloudbr0.j2 +++ b/Ansible/roles/kvm/templates/kvm-cloudbr0.j2 @@ -24,4 +24,4 @@ STP=off PEERDNS=yes PEERROUTES=yes DEFROUTE=yes -MTU=4500 +MTU=1500 diff --git a/Ansible/roles/kvm/templates/kvm-cloudbr0_phys_host.j2 b/Ansible/roles/kvm/templates/kvm-cloudbr0_phys_host.j2 index 4c0cd316c19..80a282f1bb4 100644 --- a/Ansible/roles/kvm/templates/kvm-cloudbr0_phys_host.j2 +++ b/Ansible/roles/kvm/templates/kvm-cloudbr0_phys_host.j2 @@ -27,4 +27,4 @@ PREFIX=16 GATEWAY=10.2.254.254 DNS1={{ env_zone_intdns1 }} DEFROUTE=yes -MTU=4500 \ No newline at end of file +MTU=1500 \ No newline at end of file diff --git a/Ansible/roles/kvm/templates/kvm-eth0.j2 b/Ansible/roles/kvm/templates/kvm-eth0.j2 index 01c790a0af7..353d94cdc9e 100644 --- a/Ansible/roles/kvm/templates/kvm-eth0.j2 +++ b/Ansible/roles/kvm/templates/kvm-eth0.j2 @@ -21,4 +21,4 @@ BOOTPROTO=none TYPE=Ethernet BRIDGE={{ kvm_mgmt_network_label }} NM_CONTROLLED=no -MTU=4500 \ No newline at end of file +MTU=1500 \ No newline at end of file diff --git a/Ansible/roles/kvm/templates/kvm-eth_mgmt_phys_host.j2 b/Ansible/roles/kvm/templates/kvm-eth_mgmt_phys_host.j2 index b35fd466df3..836412eb267 100644 --- a/Ansible/roles/kvm/templates/kvm-eth_mgmt_phys_host.j2 +++ b/Ansible/roles/kvm/templates/kvm-eth_mgmt_phys_host.j2 @@ -22,4 +22,4 @@ BOOTPROTO=none TYPE=Ethernet BRIDGE={{ kvm_mgmt_network_label }} NM_CONTROLLED=no -MTU=4500 \ No newline at end of file +MTU=1500 \ No newline at end of file diff --git a/Ansible/roles/kvm/templates/kvm-ovs-eth.j2 b/Ansible/roles/kvm/templates/kvm-ovs-eth.j2 index b4103df9dd9..2c90f4a3a36 100644 --- a/Ansible/roles/kvm/templates/kvm-ovs-eth.j2 +++ b/Ansible/roles/kvm/templates/kvm-ovs-eth.j2 @@ -22,5 +22,5 @@ ONBOOT=yes NM_CONTROLLED=no HOTPLUG=no {% if item.interface == "eth0" %} -MTU=4500 +MTU=1500 {% endif %} diff --git a/Ansible/roles/kvm/templates/kvm-suse-cloudbr0.j2 b/Ansible/roles/kvm/templates/kvm-suse-cloudbr0.j2 new file mode 100644 index 00000000000..59aaaff30ed --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-cloudbr0.j2 @@ -0,0 +1,22 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +BOOTPROTO='dhcp' +STARTMODE='auto' +BRIDGE='yes' +BRIDGE_PORTS='eth0' +BRIDGE_STP='off' +BRIDGE_FORWARDDELAY='15' +MTU='1500' diff --git a/Ansible/roles/kvm/templates/kvm-suse-cloudbr1.j2 b/Ansible/roles/kvm/templates/kvm-suse-cloudbr1.j2 new file mode 100644 index 00000000000..60f8a06a961 --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-cloudbr1.j2 @@ -0,0 +1,25 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +BOOTPROTO='none' +STARTMODE='auto' +BRIDGE='yes' +{% if env_zonetype | lower == "advanced" %} +BRIDGE_PORTS='eth1' +{% else %} +BRIDGE_PORTS='eth1.{{ hostvars['localhost']['env_guestnetvlan'] }}' +{% endif %} +BRIDGE_STP='off' +BRIDGE_FORWARDDELAY='15' diff --git a/Ansible/roles/kvm/templates/kvm-suse-eth0.j2 b/Ansible/roles/kvm/templates/kvm-suse-eth0.j2 new file mode 100644 index 00000000000..859189b09b8 --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-eth0.j2 @@ -0,0 +1,19 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + + +BOOTPROTO='none' +STARTMODE='auto' +MTU='1500' diff --git a/Ansible/roles/kvm/templates/kvm-suse-eth1-basic-vlan.j2 b/Ansible/roles/kvm/templates/kvm-suse-eth1-basic-vlan.j2 new file mode 100644 index 00000000000..4acfd285281 --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-eth1-basic-vlan.j2 @@ -0,0 +1,19 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +BOOTPROTO='none' +STARTMODE='auto' +VLAN_ID='{{ hostvars['localhost']['env_guestnetvlan'] }}' +ETHERDEVICE='eth1' diff --git a/Ansible/roles/kvm/templates/kvm-suse-eth1.j2 b/Ansible/roles/kvm/templates/kvm-suse-eth1.j2 new file mode 100644 index 00000000000..416c41ab4c5 --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-eth1.j2 @@ -0,0 +1,18 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + + +BOOTPROTO='none' +STARTMODE='auto' diff --git a/Ansible/roles/kvm/templates/kvm-suse-ovs-bridges.j2 b/Ansible/roles/kvm/templates/kvm-suse-ovs-bridges.j2 new file mode 100644 index 00000000000..3bd7df9ca99 --- /dev/null +++ b/Ansible/roles/kvm/templates/kvm-suse-ovs-bridges.j2 @@ -0,0 +1,38 @@ +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. +# +# Note: during testing of OVS version 2.9.2 on CentOS7 it was found that bridges +# can not simply request DHCP address based on the uplink NIC MAC address. +# Forcing the bridge to use the MAC of uplink NIC caused DHCP leases on both +# interfaces - bridge and uplink. As a result the correct OVS configuration +# is included but commented out below for future use, whilst the configuration +# used uses static IP address based on the DHCP lease at Trillian build time. +# +# + +BOOTPROTO='{{ item.bootproto }}' +STARTMODE='auto' +OVS_BRIDGE='yes' +{% if item.port is defined %} +OVS_BRIDGE_PORT_DEVICE='{{ item.port }}' +{% endif %} +{% if item.bootproto == "static" %} +{% if item.bridge == "cloud0" %} +IPADDR=169.254.0.1 +NETMASK=255.255.0.0 +{% else %} +IPADDR={{ ansible_eth0.ipv4.address }} +NETMASK={{ ansible_eth0.ipv4.netmask }} +{% endif %} +{% endif %} diff --git a/Ansible/roles/marvin/files/smoke/README b/Ansible/roles/marvin/files/smoke/README new file mode 100644 index 00000000000..3765a564e2c --- /dev/null +++ b/Ansible/roles/marvin/files/smoke/README @@ -0,0 +1 @@ +drop any tests here in case you want to override behaviour of the ACS smoke tests diff --git a/Ansible/roles/marvin/files/smoke/test_hostha_kvm.py b/Ansible/roles/marvin/files/smoke/test_hostha_kvm.py deleted file mode 100644 index cd4a2d412a4..00000000000 --- a/Ansible/roles/marvin/files/smoke/test_hostha_kvm.py +++ /dev/null @@ -1,632 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.lib.utils import * -from marvin.lib.base import * -from marvin.lib.common import * -from nose.plugins.attrib import attr - -import random - -from ipmisim.ipmisim import IpmiServerContext, IpmiServer, ThreadedIpmiServer - -import random -import socket -import sys -import thread -import time - - -class TestHAKVM(cloudstackTestCase): - """ Test cases for host HA using KVM host(s) - """ - - def setUp(self): - self.testClient = super(TestHAKVM, self).getClsTestClient() - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.services = self.testClient.getParsedTestDataConfig() - self.logger = logging.getLogger('TestHAKVM') - - #Get Zone specifics - self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) - self.hypervisor = self.testClient.getHypervisorInfo() - self.host = self.getHost() - self.hostConfig = self.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ - self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__ - self.cluster_id = self.host.clusterid - - # Cleanup any existing configs - self.dbclient.execute("delete from ha_config where resource_type='Host'") - - # use random port for ipmisim - self.fakeMsId = random.randint(10000, 99999) * random.randint(10, 20) - s = socket.socket() - s.bind(('', 0)) - self.serverPort = s.getsockname()[1] - s.close() - - # Set Cluster-level setting in order to run tests faster - self.updateConfiguration("kvm.ha.activity.check.failure.ratio", "0.6") - self.updateConfiguration("kvm.ha.activity.check.interval", "8") - self.updateConfiguration("kvm.ha.activity.check.max.attempts", "5") - self.updateConfiguration("kvm.ha.activity.check.timeout", "30") - self.updateConfiguration("kvm.ha.degraded.max.period", "30") - self.updateConfiguration("kvm.ha.fence.timeout", "30") - self.updateConfiguration("kvm.ha.health.check.timeout", "30") - self.updateConfiguration("kvm.ha.recover.failure.threshold", "2") - self.updateConfiguration("kvm.ha.recover.timeout", "30") - self.updateConfiguration("kvm.ha.recover.wait.period", "30") - - self.service_offering = ServiceOffering.create( - self.apiclient, - self.services["service_offerings"]["hasmall"] - ) - - self.template = get_test_template( - self.apiclient, - self.zone.id, - self.hypervisor - ) - - self.configureAndDisableHostHa() - self.cleanup = [self.service_offering] - - def updateConfiguration(self, name, value): - cmd = updateConfiguration.updateConfigurationCmd() - cmd.name = name - cmd.value = value - cmd.clusterid = self.cluster_id - self.apiclient.updateConfiguration(cmd) - - def getFakeMsId(self): - return self.fakeMsId - - def getFakeMsRunId(self): - return self.fakeMsId * 1000 - - def tearDown(self): - self.configureAndDisableHostHa() - self.host = None - try: - self.dbclient.execute("delete from mshost_peer where peer_runid=%s" % self.getFakeMsRunId()) - self.dbclient.execute("delete from mshost where runid=%s" % self.getFakeMsRunId()) - self.dbclient.execute("delete from cluster_details where name='resourceHAEnabled'") - self.dbclient.execute("delete from data_center_details where name='resourceHAEnabled'") - self.dbclient.execute("delete from ha_config where resource_type='Host'") - self.dbclient.execute("delete from oobm where port=%d" % self.getIpmiServerPort()) - self.dbclient.execute("delete from mshost_peer where peer_runid=%s" % self.getFakeMsRunId()) - self.dbclient.execute("delete from mshost where runid=%s" % self.getFakeMsRunId()) - self.dbclient.execute("delete from cluster_details where name='outOfBandManagementEnabled'") - self.dbclient.execute("delete from data_center_details where name='outOfBandManagementEnabled'") - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def getHostHaEnableCmd(self): - cmd = enableHAForHost.enableHAForHostCmd() - cmd.hostid = self.host.id - return cmd - - def getHost(self, hostId=None): - response = list_hosts( - self.apiclient, - type='Routing', - hypervisor='kvm', - id=hostId - ) - # Check if more than one kvm hosts are available in order to successfully configure host-ha - if response and len(response) > 0: - self.host = response[0] - return self.host - raise self.skipTest("Not enough KVM hosts found, skipping host-ha test") - - def getHostHaConfigCmd(self, provider='kvmhaprovider'): - cmd = configureHAForHost.configureHAForHostCmd() - cmd.provider = provider - cmd.hostid = self.host.id - return cmd - - def getHostHaDisableCmd(self): - cmd = disableHAForHost.disableHAForHostCmd() - cmd.hostid = self.host.id - return cmd - - def configureAndEnableHostHa(self): - #Adding sleep between configuring and enabling - self.apiclient.configureHAForHost(self.getHostHaConfigCmd()) - response = self.apiclient.enableHAForHost(self.getHostHaEnableCmd()) - self.assertEqual(response.haenable, True) - - def configureAndDisableHostHa(self): - self.apiclient.configureHAForHost(self.getHostHaConfigCmd()) - cmd = self.getHostHaDisableCmd() - cmd.hostid = self.host.id - response = self.apiclient.disableHAForHost(cmd) - self.assertEqual(response.hostid, cmd.hostid) - self.assertEqual(response.haenable, False) - - def enableHostHa(self, hostId): - cmd = self.getHostHaEnableCmd() - cmd.hostid = hostId - response = self.apiclient.enableHAForHost(cmd) - self.assertEqual(response.hostid, cmd.hostid) - self.assertEqual(response.haenable, True) - return response - - def disableAgent(self): - SshClient(self.host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]).execute\ - ("systemctl disable cloudstack-agent || chkconfig cloudstack-agent off") - - def resetHost(self): - SshClient(self.host.ipaddress, port=22, user=self.hostConfig["username"], - passwd=self.hostConfig["password"]).execute \ - ("reboot") - - def enableAgent(self): - SshClient(self.host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]).execute\ - ("systemctl enable cloudstack-agent || chkconfig cloudstack-agent on") - - def waitUntilHostInState(self, state="Available", interval=3): - def checkForState(expectedState): - response = self.getHost(self.host.id) - print("checkForState:: expected=%s, actual=%s" % (state, response.hostha)) - return response.hostha.hastate == expectedState, None - - res, _ = wait_until(interval, 200, checkForState, state) - if not res: - self.fail("Failed to see host ha state in :" + state) - - def deployVM(self): - try: - vm = VirtualMachine.create( - self.apiclient, - services=self.services["virtual_machine"], - serviceofferingid=self.service_offering.id, - templateid=self.template.id, - zoneid=self.zone.id, - hostid = self.host.id, - method="POST" - ) - self.cleanup.append(vm) - except Exception as e: - raise self.skipTest("Failed to deploy VM, skipping kvm host-ha test case") - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_disable_oobm_ha_state_ineligible(self): - """ - Tests that when HA is enabled for a host, if oobm is disabled HA State should turn into Ineligible - """ - self.logger.debug("Starting test_disable_oobm_ha_state_ineligible") - - # Enable ha for host - self.configureAndEnableHostHa() - - # Disable OOBM - self.apiclient.configureOutOfBandManagement(self.getOobmConfigCmd()) - oobm_cmd = self.getOobmDisableCmd() - oobm_cmd.hostid = self.host.id - response = self.apiclient.disableOutOfBandManagementForHost(oobm_cmd) - self.assertEqual(response.hostid, oobm_cmd.hostid) - self.assertEqual(response.enabled, False) - - response = self.getHost(hostId=self.host.id).outofbandmanagement - self.assertEqual(response.powerstate, 'Disabled') - - # Verify HA State is Ineligeble - self.waitUntilHostInState("Ineligible") - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_configure_default_driver(self): - """ - Tests host-ha configuration with valid data - """ - self.logger.debug("Starting test_hostha_configure_default_driver") - - cmd = self.getHostHaConfigCmd() - response = self.apiclient.configureHAForHost(cmd) - self.assertEqual(response.hostid, cmd.hostid) - self.assertEqual(response.haprovider, cmd.provider.lower()) - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_enable_ha_when_host_disabled(self): - """ - Tests Enable HA when host is disconnected, should be Ineligible - """ - self.logger.debug("Starting test_hostha_enable_ha_when_host_disabled") - - # Enable HA - self.configureAndEnableHostHa() - - # Disable Host - self.disableHost(self.host.id) - - # Check HA State - try: - self.waitUntilHostInState("Ineligible") - except Exception as e: - self.enableHost(self.host.id) - self.fail(e) - - # Enable Host - self.enableHost(self.host.id) - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_enable_ha_when_host_in_maintenance(self): - """ - Tests Enable HA when host is in Maintenance mode, should be Ineligible - """ - self.logger.debug("Starting test_hostha_enable_ha_when_host_in_maintenance") - self.logger.debug("Pausing to wait for VMs to have finished starting") - time.sleep(300) - - # Enable HA - self.configureAndEnableHostHa() - - - # Prepare for maintenance Host - self.setHostToMaintanance(self.host.id) - - # Check HA State - try: - self.waitUntilHostInState("Ineligible") - except Exception as e: - self.cancelMaintenance() - self.fail(e) - - # Enable Host - self.cancelMaintenance() - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_enable_ha_when_host_disconected(self): - """ - Tests Enable HA when host is disconnected, should be Ineligible - """ - self.logger.debug("Starting test_hostha_enable_ha_when_host_disconected") - - # Enable HA - self.apiclient.configureHAForHost(self.getHostHaConfigCmd()) - cmd = self.getHostHaEnableCmd() - cmd.hostid = self.host.id - enable = self.apiclient.enableHAForHost(cmd) - self.assertEqual(enable.hostid, cmd.hostid) - self.assertEqual(enable.haenable, True) - - # Make Host Disconnected - self.killAgent() - - # Check HA State - try: - self.waitUntilHostInState("Ineligible") - except Exception as e: - self.startAgent() - self.fail(e) - - # Enable Host - self.startAgent() - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_remove_ha_provider_not_possible(self): - """ - Tests HA Provider should be possible to be removed when HA is enabled - """ - self.logger.debug("Starting test_remove_ha_provider_not_possible") - - - # Enable HA - self.apiclient.configureHAForHost(self.getHostHaConfigCmd()) - cmd = self.getHostHaEnableCmd() - cmd.hostid = self.host.id - enable = self.apiclient.enableHAForHost(cmd) - self.assertEqual(enable.hostid, cmd.hostid) - self.assertEqual(enable.haenable, True) - - try: - self.apiclient.configureHAForHost(self.getHostHaConfigCmd('')) - except Exception: - pass - else: - self.fail("Expected an exception to be thrown, failing") - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_kvm_host_degraded(self): - """ - Tests degraded HA state when agent is stopped/killed - """ - - self.configureAndStartIpmiServer() - self.assertIssueCommandState('ON', 'On') - self.configureAndEnableHostHa() - - self.deployVM() - - # Start with the available state - self.waitUntilHostInState("Available") - - # SSH into the KVM Host and executes kill -9 of the agent - self.stopAgent() - - # Check if host would go into Suspect state - try: - self.waitUntilHostInState("Suspect") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - # Checks if the host would turn into Degraded - try: - self.waitUntilHostInState("Degraded") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - self.startAgent() - self.waitUntilHostInState("Available") - - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_kvm_host_recovering(self): - """ - Tests recovery and fencing HA state transitions - """ - - self.configureAndStartIpmiServer() - self.assertIssueCommandState('ON', 'On') - self.configureAndEnableHostHa() - - self.deployVM() - - # Start with the available state - self.waitUntilHostInState("Available") - - # Kill host by triggering a fault - self.killAgent() - self.disableAgent() - self.resetHost() - - # Check if host would go into Suspect state - try: - self.waitUntilHostInState("Suspect") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - # Checks if the host would turn into Recovered - try: - self.waitUntilHostInState("Recovered") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - self.enableAgent() - self.startAgent() - self.waitUntilHostInState("Available") - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_hostha_kvm_host_fencing(self): - """ - Tests fencing/fenced HA state when host crashes - """ - self.logger.debug("Starting test_ha_kvm_host_fencing") - - - self.configureAndStartIpmiServer() - self.assertIssueCommandState('ON', 'On') - self.configureAndEnableHostHa() - - self.deployVM() - - # Start with the available state - self.waitUntilHostInState("Available") - - # Fail oobm commands - cmd = self.getOobmConfigCmd() - cmd.address = "1.1.1.1" - self.apiclient.configureOutOfBandManagement(cmd) - - # Kill host by triggering a fault - self.killAgent() - self.disableAgent() - self.resetHost() - - # Check if host would go into Suspect state - try: - self.waitUntilHostInState("Suspect") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - # Checks if the host would turn into Fencing - try: - self.waitUntilHostInState("Fencing") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - # Allow oobm commands to work now - self.configureAndEnableOobm() - - # Checks if the host would turn into Fenced - try: - self.waitUntilHostInState("Fenced") - except Exception as e: - self.startAgent() - raise Exception("Warning: Exception during test execution : %s" % e) - - self.enableAgent() - self.startAgent() - self.cancelMaintenance() - self.waitUntilHostInState("Available") - - def configureAndStartIpmiServer(self, power_state=None): - """ - Setup ipmisim and enable out-of-band management for host - """ - self.configureAndEnableOobm() - self.startIpmiServer() - if power_state: - bmc = IpmiServerContext().bmc - bmc.powerstate = power_state - - def assertIssueCommandState(self, command, expected): - """ - Asserts power action result for a given power command - """ - if command != 'STATUS': - self.issuePowerActionCmd(command) - try: - response = self.issuePowerActionCmd('STATUS') - self.assertEqual(response.powerstate, expected) - except: - pass # in case of ipmisim errors ignore - - def configureAndEnableOobm(self): - self.apiclient.configureOutOfBandManagement(self.getOobmConfigCmd()) - response = self.apiclient.enableOutOfBandManagementForHost(self.getOobmEnableCmd()) - self.assertEqual(response.enabled, True) - - def startIpmiServer(self): - def startIpmiServer(tname, server): - self.debug("Starting ipmisim server") - try: - server.serve_forever() - except Exception: pass - IpmiServerContext('reset') - ThreadedIpmiServer.allow_reuse_address = False - server = ThreadedIpmiServer(('0.0.0.0', self.getIpmiServerPort()), IpmiServer) - thread.start_new_thread(startIpmiServer, ("ipmi-server", server,)) - self.server = server - - def stopIpmiServer(self): - if self.server: - self.server.shutdown() - self.server.server_close() - - def getOobmIssueActionCmd(self): - cmd = issueOutOfBandManagementPowerAction.issueOutOfBandManagementPowerActionCmd() - cmd.hostid = self.host.id - cmd.action = 'STATUS' - return cmd - - def issuePowerActionCmd(self, action, timeout=None): - cmd = self.getOobmIssueActionCmd() - cmd.action = action - if timeout: - cmd.timeout = timeout - - try: - return self.apiclient.issueOutOfBandManagementPowerAction(cmd) - except Exception as e: - if "packet session id 0x0 does not match active session" in str(e): - raise self.skipTest("Known ipmitool issue hit, skipping test") - raise e - - def getOobmEnableCmd(self): - cmd = enableOutOfBandManagementForHost.enableOutOfBandManagementForHostCmd() - cmd.hostid = self.host.id - return cmd - - def getOobmDisableCmd(self): - cmd = disableOutOfBandManagementForHost.disableOutOfBandManagementForHostCmd() - cmd.hostid = self.host.id - return cmd - - def getIpmiServerPort(self): - return self.serverPort - - def getOobmConfigCmd(self): - cmd = configureOutOfBandManagement.configureOutOfBandManagementCmd() - cmd.driver = 'ipmitool' # The default available driver - cmd.address = self.getIpmiServerIp() - cmd.port = self.getIpmiServerPort() - cmd.username = 'admin' - cmd.password = 'password' - cmd.hostid = self.host.id - return cmd - - def getIpmiServerIp(self): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.connect((self.mgtSvrDetails["mgtSvrIp"], self.mgtSvrDetails["port"])) - return s.getsockname()[0] - - def get_non_configured_ha_host(self): - - response = list_hosts( - self.apiclient, - type='Routing' - ) - - for host in response: - if host.haprovider is None: - return host - else: - cloudstackTestCase.skipTest(self, "There is no non configured hosts. Skipping test.") - - raise self.skipTest("No KVM hosts found, skipping host-ha test") - - def getHAState(self, id): - cmd = listHostHAResources.listHostHAResourcesCmd() - cmd.hostid = id - response = self.apiclient.listHostHAResources(cmd) - - return response[0] - - def startAgent(self): - SshClient(host=self.host.ipaddress, port=22, user=self.hostConfig["username"], - passwd=self.hostConfig["password"]).execute \ - ("systemctl start cloudstack-agent || service cloudstack-agent start") - - def stopAgent(self): - SshClient(host=self.host.ipaddress, port=22, user=self.hostConfig["username"], - passwd=self.hostConfig["password"]).execute \ - ("systemctl stop cloudstack-agent || service cloudstack-agent stop") - - def killAgent(self): - SshClient(host=self.host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"]).execute\ - ("kill -9 $(ps aux | grep 'cloudstack-agent' | awk '{print $2}')") - - def disableHost(self, id): - cmd = updateHost.updateHostCmd() - cmd.id = id - cmd.allocationstate = "Disable" - response = self.apiclient.updateHost(cmd) - self.assertEqual(response.resourcestate, "Disabled") - - def enableHost(self, id): - cmd = updateHost.updateHostCmd() - cmd.id = id - cmd.allocationstate = "Enable" - response = self.apiclient.updateHost(cmd) - self.assertEqual(response.resourcestate, "Enabled") - - def setHostToMaintanance(self, id): - cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd() - cmd.id = id - - response = self.apiclient.prepareHostForMaintenance(cmd) - - self.assertEqual(response.resourcestate, "PrepareForMaintenance") - - def cancelMaintenance(self): - cmd = cancelHostMaintenance.cancelHostMaintenanceCmd() - cmd.id = self.host.id - response = self.apiclient.cancelHostMaintenance(cmd) - - self.assertEqual(response.resourcestate, "Enabled") diff --git a/Ansible/roles/marvin/files/smoke/test_ssvm.py b/Ansible/roles/marvin/files/smoke/test_ssvm.py deleted file mode 100644 index 52f525c7ec3..00000000000 --- a/Ansible/roles/marvin/files/smoke/test_ssvm.py +++ /dev/null @@ -1,1256 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -""" BVT tests for SSVM -""" -# Import Local Modules -from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (stopSystemVm, - rebootSystemVm, - destroySystemVm, updateConfiguration) -from marvin.lib.utils import (cleanup_resources, - get_process_status, - get_host_credentials, - wait_until) -from marvin.lib.base import (PhysicalNetwork, - NetScaler, ImageStore) -from marvin.lib.common import (get_zone, - list_hosts, - list_ssvms, - list_zones, - list_vlan_ipranges) -from nose.plugins.attrib import attr -import telnetlib -import logging - -# Import System modules -import time -_multiprocess_shared_ = True - - -class TestSSVMs(cloudstackTestCase): - - def setUp(self): - test_case = super(TestSSVMs, self) - self.apiclient = self.testClient.getApiClient() - self.hypervisor = self.testClient.getHypervisorInfo() - self.cleanup = [] - self.config = test_case.getClsConfig() - self.services = self.testClient.getParsedTestDataConfig() - self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) - - self.logger = logging.getLogger('TestSSVMs') - self.stream_handler = logging.StreamHandler() - self.logger.setLevel(logging.DEBUG) - self.logger.addHandler(self.stream_handler) - - def tearDown(self): - try: - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def waitForSystemVMAgent(self, vmname): - def checkRunningAgent(): - list_host_response = list_hosts( - self.apiclient, - name=vmname - ) - if isinstance(list_host_response, list): - return list_host_response[0].state == 'Up', None - return False, None - - res, _ = wait_until(3, 300, checkRunningAgent) - if not res: - raise Exception("Failed to wait for SSVM agent to be Up") - - def checkForRunningSystemVM(self, ssvm, ssvm_type=None): - if not ssvm: - return None - - def checkRunningState(): - if not ssvm_type: - response = list_ssvms( - self.apiclient, - id=ssvm.id - ) - else: - response = list_ssvms( - self.apiclient, - zoneid=self.zone.id, - systemvmtype=ssvm_type - ) - - if isinstance(response, list): - ssvm_response = response[0] - return ssvm_response.state == 'Running', ssvm_response - return False, None - - res, ssvm_response = wait_until(3, 300, checkRunningState) - if not res: - self.fail("Failed to reach systemvm state to Running") - return ssvm_response - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="false") - def test_01_list_sec_storage_vm(self): - """Test List secondary storage VMs - """ - - # Validate the following: - # 1. listSystemVM (systemvmtype=secondarystoragevm) - # should return only ONE SSVM per zone - # 2. The returned SSVM should be in Running state - # 3. listSystemVM for secondarystoragevm should list publicip, - # privateip and link-localip - # 4. The gateway programmed on the ssvm by listSystemVm should be - # the same as the gateway returned by listVlanIpRanges - # 5. DNS entries must match those given for the zone - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - # Verify SSVM response - self.assertNotEqual( - len(list_ssvm_response), - 0, - "Check list System VMs response" - ) - - list_zones_response = list_zones(self.apiclient) - - self.assertEqual( - isinstance(list_zones_response, list), - True, - "Check list response returns a valid list" - ) - - self.debug("Number of zones: %s" % len(list_zones_response)) - self.debug("Number of SSVMs: %s" % len(list_ssvm_response)) - # Number of Sec storage VMs = No of Zones - self.assertEqual( - len(list_ssvm_response), - len(list_zones_response), - "Check number of SSVMs with number of zones" - ) - # For each secondary storage VM check private IP, - # public IP, link local IP and DNS - for ssvm in list_ssvm_response: - - self.debug("SSVM state: %s" % ssvm.state) - self.assertEqual( - ssvm.state, - 'Running', - "Check whether state of SSVM is running" - ) - - self.assertEqual( - hasattr(ssvm, 'privateip'), - True, - "Check whether SSVM has private IP field" - ) - - self.assertEqual( - hasattr(ssvm, 'linklocalip'), - True, - "Check whether SSVM has link local IP field" - ) - - self.assertEqual( - hasattr(ssvm, 'publicip'), - True, - "Check whether SSVM has public IP field" - ) - - # Fetch corresponding ip ranges information from listVlanIpRanges - ipranges_response = list_vlan_ipranges( - self.apiclient, - zoneid=ssvm.zoneid - ) - self.assertEqual( - isinstance(ipranges_response, list), - True, - "Check list response returns a valid list" - ) - - # Fetch corresponding Physical Network of SSVM's Zone - listphyntwk = PhysicalNetwork.list( - self.apiclient, - zoneid=ssvm.zoneid - ) - - # Execute the following assertion in all zones except EIP-ELB Zones - if not ( - self.zone.networktype.lower() == 'basic' and isinstance( - NetScaler.list( - self.apiclient, - physicalnetworkid=listphyntwk[0].id), - list) is True): - gatewayFound = False - for iprange in ipranges_response: - if ssvm.gateway == iprange.gateway: - gatewayFound = True - break - - self.assertTrue( - gatewayFound, - "Check gateway with that of corresponding ip range" - ) - - # Fetch corresponding zone information from listZones - zone_response = list_zones( - self.apiclient, - id=ssvm.zoneid - ) - self.assertEqual( - isinstance(zone_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - ssvm.dns1, - zone_response[0].dns1, - "Check DNS1 with that of corresponding zone" - ) - - self.assertEqual( - ssvm.dns2, - zone_response[0].dns2, - "Check DNS2 with that of corresponding zone" - ) - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="false") - def test_02_list_cpvm_vm(self): - """Test List console proxy VMs - """ - - # Validate the following: - # 1. listSystemVM (systemvmtype=consoleproxy) should return - # at least ONE CPVM per zone - # 2. The returned ConsoleProxyVM should be in Running state - # 3. listSystemVM for console proxy should list publicip, privateip - # and link-localip - # 4. The gateway programmed on the console proxy should be the same - # as the gateway returned by listZones - # 5. DNS entries must match those given for the zone - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - state='Running', - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - # Verify CPVM response - self.assertNotEqual( - len(list_cpvm_response), - 0, - "Check list System VMs response" - ) - list_zones_response = list_zones(self.apiclient) - # Number of Console Proxy VMs = No of Zones - - self.assertEqual( - isinstance(list_zones_response, list), - True, - "Check list response returns a valid list" - ) - - self.debug("Number of zones: %s" % len(list_zones_response)) - self.debug("Number of CPVMs: %s" % len(list_cpvm_response)) - - self.assertEqual( - len(list_cpvm_response), - len(list_zones_response), - "Check number of CPVMs with number of zones" - ) - # For each CPVM check private IP, public IP, link local IP and DNS - for cpvm in list_cpvm_response: - - self.debug("CPVM state: %s" % cpvm.state) - self.assertEqual( - cpvm.state, - 'Running', - "Check whether state of CPVM is running" - ) - - self.assertEqual( - hasattr(cpvm, 'privateip'), - True, - "Check whether CPVM has private IP field" - ) - - self.assertEqual( - hasattr(cpvm, 'linklocalip'), - True, - "Check whether CPVM has link local IP field" - ) - - self.assertEqual( - hasattr(cpvm, 'publicip'), - True, - "Check whether CPVM has public IP field" - ) - # Fetch corresponding ip ranges information from listVlanIpRanges - ipranges_response = list_vlan_ipranges( - self.apiclient, - zoneid=cpvm.zoneid - ) - self.assertEqual( - isinstance(ipranges_response, list), - True, - "Check list response returns a valid list" - ) - - # Fetch corresponding Physical Network of SSVM's Zone - listphyntwk = PhysicalNetwork.list( - self.apiclient, - zoneid=cpvm.zoneid - ) - - # Execute the following assertion in all zones except EIP-ELB Zones - if not ( - self.zone.networktype.lower() == 'basic' and isinstance( - NetScaler.list( - self.apiclient, - physicalnetworkid=listphyntwk[0].id), - list) is True): - gatewayFound = False - for iprange in ipranges_response: - if iprange.gateway == cpvm.gateway: - gatewayFound = True - break - self.assertTrue( - gatewayFound, - "Check gateway with that of corresponding ip range" - ) - - # Fetch corresponding zone information from listZones - zone_response = list_zones( - self.apiclient, - id=cpvm.zoneid - ) - - self.assertEqual( - cpvm.dns1, - zone_response[0].dns1, - "Check DNS1 with that of corresponding zone" - ) - - self.assertEqual( - cpvm.dns2, - zone_response[0].dns2, - "Check DNS2 with that of corresponding zone" - ) - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_03_ssvm_internals(self): - """Test SSVM Internals""" - - # Validate the following - # 1. The SSVM check script should not return any - # WARN|ERROR|FAIL messages - # 2. If you are unable to login to the SSVM with the signed key - # then test is deemed a failure - # 3. There should be only one ""cloud"" process running within the SSVM - # 4. If no process is running/multiple process are running - # then the test is a failure - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - ssvm = list_ssvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=ssvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - host = hosts[0] - - self.debug("Running SSVM check script") - - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and - # Hyper-V - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - ssvm.privateip, - "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL", - hypervisor=self.hypervisor) - else: - try: - host.user, host.passwd = get_host_credentials( - self.config, host.ipaddress) - result = get_process_status( - host.ipaddress, - 22, - host.user, - host.passwd, - ssvm.linklocalip, - "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL") - except KeyError: - self.skipTest( - "Marvin configuration has no host\ - credentials to check router services") - res = str(result) - self.debug("SSVM script output: %s" % res) - - self.assertEqual( - res.count("ERROR"), - 1, - "Check for Errors in tests" - ) - - self.assertEqual( - res.count("WARNING"), - 1, - "Check for warnings in tests" - ) - - # Check status of cloud service - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and - # Hyper-V - retries = 3 - while retries > -1: - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - ssvm.privateip, - "systemctl is-active cloud", - hypervisor=self.hypervisor - ) - if ("deactivating" in result) or ("activating" in result): - if retries >= 0: - retries = retries - 1 - time.sleep(10) - continue - else: - return result - else: - try: - host.user, host.passwd = get_host_credentials( - self.config, host.ipaddress) - retries = 3 - while retries > -1: - result = get_process_status( - host.ipaddress, - 22, - host.user, - host.passwd, - ssvm.linklocalip, - "systemctl is-active cloud" - ) - print("result is %s" % result) - if ("deactivating" in result) or ("activating" in result): - if retries >= 0: - retries = retries - 1 - time.sleep(10) - continue - else: - return result - except KeyError: - self.skipTest( - "Marvin configuration has no host\ - credentials to check router services") - res = str(result) - self.debug("Cloud Process status: %s" % res) - # Apache CloudStack service (type=secstorage) is running: process id: 2346 - self.assertEqual( - res.count("active"), - 1, - "Check cloud service is running or not" - ) - - linklocal_ip = None - # Check status of cloud service - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and - # Hyper-V - linklocal_ip = ssvm.privateip - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - ssvm.privateip, - "cat /var/cache/cloud/cmdline | xargs | sed \"s/ /\\n/g\" | grep eth1ip= | sed \"s/\=/ /g\" | awk '{print $2}'", - hypervisor=self.hypervisor - ) - else: - try: - linklocal_ip = ssvm.linklocalip - host.user, host.passwd = get_host_credentials( - self.config, host.ipaddress) - result = get_process_status( - host.ipaddress, - 22, - host.user, - host.passwd, - ssvm.linklocalip, - "cat /var/cache/cloud/cmdline | xargs | sed \"s/ /\\n/g\" | grep eth0ip= | sed \"s/\=/ /g\" | awk '{print $2}'" - ) - except KeyError: - self.skipTest( - "Marvin configuration has no host\ - credentials to check router services") - res = result[0] - self.debug("Cached Link Local IP: %s" % res) - self.assertEqual( - linklocal_ip, - res, - "The cached Link Local should be the same as the current Link Local IP, but they are different! Current ==> %s; Cached ==> %s " % (linklocal_ip, res) - ) - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_04_cpvm_internals(self): - """Test CPVM Internals""" - - # Validate the following - # 1. test that telnet access on 8250 is available to - # the management server for the CPVM - # 2. No telnet access, test FAIL - # 3. Service cloud status should report cloud agent status to be - # running - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - cpvm = list_cpvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=cpvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - host = hosts[0] - - try: - telnetlib.Telnet( - str(self.apiclient.connection.mgtSvr), - '8250' - ) - self.debug("Telnet management server (IP: %s)" % - self.apiclient.connection.mgtSvr) - except Exception as e: - self.fail( - "Telnet Access failed for %s: %s" % - (self.apiclient.connection.mgtSvr, e) - ) - - self.debug("Checking cloud process status") - - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and - # Hyper-V - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - cpvm.privateip, - "systemctl is-active cloud", - hypervisor=self.hypervisor - ) - else: - try: - host.user, host.passwd = get_host_credentials( - self.config, host.ipaddress) - result = get_process_status( - host.ipaddress, - 22, - host.user, - host.passwd, - cpvm.linklocalip, - "systemctl is-active cloud" - ) - except KeyError: - self.skipTest( - "Marvin configuration has no host\ - credentials to check router services") - res = str(result) - self.debug("Cloud Process status: %s" % res) - self.assertEqual( - res.count("active"), - 1, - "Check cloud service is running or not" - ) - - linklocal_ip = None - # Check status of cloud service - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and - # Hyper-V - linklocal_ip = cpvm.privateip - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - cpvm.privateip, - "cat /var/cache/cloud/cmdline | xargs | sed \"s/ /\\n/g\" | grep eth1ip= | sed \"s/\=/ /g\" | awk '{print $2}'", - hypervisor=self.hypervisor - ) - else: - try: - linklocal_ip = cpvm.linklocalip - host.user, host.passwd = get_host_credentials( - self.config, host.ipaddress) - result = get_process_status( - host.ipaddress, - 22, - host.user, - host.passwd, - cpvm.linklocalip, - "cat /var/cache/cloud/cmdline | xargs | sed \"s/ /\\n/g\" | grep eth0ip= | sed \"s/\=/ /g\" | awk '{print $2}'" - ) - except KeyError: - self.skipTest( - "Marvin configuration has no host\ - credentials to check router services") - res = result[0] - self.debug("Cached Link Local IP: %s" % res) - self.assertEqual( - linklocal_ip, - res, - "The cached Link Local should be the same as the current Link Local IP, but they are different! Current ==> %s; Cached ==> %s " % (linklocal_ip, res) - ) - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_05_stop_ssvm(self): - """Test stop SSVM - """ - - # Validate the following - # 1. The SSVM should go to stop state - # 2. After a brief delay of say one minute, the SSVM should be - # restarted once again and return to Running state with previous two - # test cases still passing - # 3. If either of the two above steps fail the test is a failure - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - ssvm = list_ssvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=ssvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - - self.debug("Stopping SSVM: %s" % ssvm.id) - cmd = stopSystemVm.stopSystemVmCmd() - cmd.id = ssvm.id - self.apiclient.stopSystemVm(cmd) - - ssvm_response = self.checkForRunningSystemVM(ssvm) - self.debug("SSVM state after debug: %s" % ssvm_response.state) - self.assertEqual( - ssvm_response.state, - 'Running', - "Check whether SSVM is running or not" - ) - - # Wait for the agent to be up - self.waitForSystemVMAgent(ssvm_response.name) - - # Call above tests to ensure SSVM is properly running - self.test_01_list_sec_storage_vm() - - self.test_03_ssvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_06_stop_cpvm(self): - """Test stop CPVM - """ - - # Validate the following - # 1. The CPVM should go to stop state - # 2. After a brief delay of say one minute, the SSVM should be - # restarted once again and return to Running state with previous - # two test cases still passing - # 3. If either of the two above steps fail the test is a failure - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - cpvm = list_cpvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=cpvm.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - - self.debug("Stopping CPVM: %s" % cpvm.id) - cmd = stopSystemVm.stopSystemVmCmd() - cmd.id = cpvm.id - self.apiclient.stopSystemVm(cmd) - - cpvm_response = self.checkForRunningSystemVM(cpvm) - self.debug("CPVM state after debug: %s" % cpvm_response.state) - - self.assertEqual( - cpvm_response.state, - 'Running', - "Check whether CPVM is running or not" - ) - - # Wait for the agent to be up - self.waitForSystemVMAgent(cpvm_response.name) - - # Call above tests to ensure CPVM is properly running - self.test_02_list_cpvm_vm() - - self.test_04_cpvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_07_reboot_ssvm(self): - """Test reboot SSVM - """ - # Validate the following - # 1. The SSVM should go to stop and return to Running state - # 2. SSVM's public-ip and private-ip must remain the same - # before and after reboot - # 3. The cloud process should still be running within the SSVM - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - - ssvm_response = list_ssvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=ssvm_response.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - - # Store the public & private IP values before reboot - old_public_ip = ssvm_response.publicip - old_private_ip = ssvm_response.privateip - - self.debug("Rebooting SSVM: %s" % ssvm_response.id) - cmd = rebootSystemVm.rebootSystemVmCmd() - cmd.id = ssvm_response.id - self.apiclient.rebootSystemVm(cmd) - - ssvm_response = self.checkForRunningSystemVM(ssvm_response) - self.debug("SSVM State: %s" % ssvm_response.state) - self.assertEqual( - 'Running', - str(ssvm_response.state), - "Check whether CPVM is running or not" - ) - - self.assertEqual( - ssvm_response.publicip, - old_public_ip, - "Check Public IP after reboot with that of before reboot" - ) - - # Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745 - - # Wait for the agent to be up - self.waitForSystemVMAgent(ssvm_response.name) - - # Wait until NFS stores mounted before running the script - time.sleep(90) - # Call to verify cloud process is running - self.test_03_ssvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_08_reboot_cpvm(self): - """Test reboot CPVM - """ - # Validate the following - # 1. The CPVM should go to stop and return to Running state - # 2. CPVM's public-ip and private-ip must remain - # the same before and after reboot - # 3. the cloud process should still be running within the CPVM - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - cpvm_response = list_cpvm_response[0] - - hosts = list_hosts( - self.apiclient, - id=cpvm_response.hostid - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - - # Store the public & private IP values before reboot - old_public_ip = cpvm_response.publicip - old_private_ip = cpvm_response.privateip - - self.debug("Rebooting CPVM: %s" % cpvm_response.id) - - cmd = rebootSystemVm.rebootSystemVmCmd() - cmd.id = cpvm_response.id - self.apiclient.rebootSystemVm(cmd) - - cpvm_response = self.checkForRunningSystemVM(cpvm_response) - self.debug("CPVM state: %s" % cpvm_response.state) - self.assertEqual( - 'Running', - str(cpvm_response.state), - "Check whether CPVM is running or not" - ) - - self.assertEqual( - cpvm_response.publicip, - old_public_ip, - "Check Public IP after reboot with that of before reboot" - ) - - # Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745 - - # Wait for the agent to be up - self.waitForSystemVMAgent(cpvm_response.name) - - # Call to verify cloud process is running - self.test_04_cpvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_09_destroy_ssvm(self): - """Test destroy SSVM - """ - - # Validate the following - # 1. SSVM should be completely destroyed and a new one will spin up - # 2. listSystemVMs will show a different name for the - # systemVM from what it was before - # 3. new SSVM will have a public/private and link-local-ip - # 4. cloud process within SSVM must be up and running - - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - ssvm_response = list_ssvm_response[0] - - old_name = ssvm_response.name - - self.debug("Destroying SSVM: %s" % ssvm_response.id) - cmd = destroySystemVm.destroySystemVmCmd() - cmd.id = ssvm_response.id - self.apiclient.destroySystemVm(cmd) - - ssvm_response = self.checkForRunningSystemVM(ssvm_response, 'secondarystoragevm') - - # Verify Name, Public IP, Private IP and Link local IP - # for newly created SSVM - self.assertNotEqual( - ssvm_response.name, - old_name, - "Check SSVM new name with name of destroyed SSVM" - ) - self.assertEqual( - hasattr(ssvm_response, 'privateip'), - True, - "Check whether SSVM has private IP field" - ) - - self.assertEqual( - hasattr(ssvm_response, 'linklocalip'), - True, - "Check whether SSVM has link local IP field" - ) - - self.assertEqual( - hasattr(ssvm_response, 'publicip'), - True, - "Check whether SSVM has public IP field" - ) - - # Wait for the agent to be up - self.waitForSystemVMAgent(ssvm_response.name) - - # Call to verify cloud process is running - self.test_03_ssvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_10_destroy_cpvm(self): - """Test destroy CPVM - """ - - # Validate the following - # 1. CPVM should be completely destroyed and a new one will spin up - # 2. listSystemVMs will show a different name for the systemVM from - # what it was before - # 3. new CPVM will have a public/private and link-local-ip - # 4. cloud process within CPVM must be up and running - - list_cpvm_response = list_ssvms( - self.apiclient, - systemvmtype='consoleproxy', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(list_cpvm_response, list), - True, - "Check list response returns a valid list" - ) - cpvm_response = list_cpvm_response[0] - - old_name = cpvm_response.name - - self.debug("Destroying CPVM: %s" % cpvm_response.id) - cmd = destroySystemVm.destroySystemVmCmd() - cmd.id = cpvm_response.id - self.apiclient.destroySystemVm(cmd) - - cpvm_response = self.checkForRunningSystemVM(cpvm_response, 'consoleproxy') - - # Verify Name, Public IP, Private IP and Link local IP - # for newly created CPVM - self.assertNotEqual( - cpvm_response.name, - old_name, - "Check SSVM new name with name of destroyed CPVM" - ) - self.assertEqual( - hasattr(cpvm_response, 'privateip'), - True, - "Check whether CPVM has private IP field" - ) - - self.assertEqual( - hasattr(cpvm_response, 'linklocalip'), - True, - "Check whether CPVM has link local IP field" - ) - - self.assertEqual( - hasattr(cpvm_response, 'publicip'), - True, - "Check whether CPVM has public IP field" - ) - - # Wait for the agent to be up - self.waitForSystemVMAgent(cpvm_response.name) - - # Call to verify cloud process is running - self.test_04_cpvm_internals() - - @attr( - tags=[ - "advanced", - "advancedns", - "smoke", - "basic", - "sg"], - required_hardware="true") - def test_11_ss_nfs_version_on_ssvm(self): - """Test NFS Version on Secondary Storage mounted properly on SSVM - """ - - # 1) List SSVM in zone - # 2) Get id and url from mounted nfs store - # 3) Update NFS version for previous image store - # 4) Stop SSVM - # 5) Check NFS version of mounted nfs store after SSVM starts - - nfs_version = self.config.nfsVersion - if nfs_version == None: - self.skipTest('No NFS version provided in test data') - - #List SSVM for zone id - list_ssvm_response = list_ssvms( - self.apiclient, - systemvmtype='secondarystoragevm', - state='Running', - zoneid=self.zone.id - ) - self.assertNotEqual( - list_ssvm_response, - None - ) - self.assertEqual( - isinstance(list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertEqual( - len(list_ssvm_response), - 1, - "Check list System VMs response" - ) - - ssvm = list_ssvm_response[0] - image_stores_response = ImageStore.list(self.apiclient,zoneid=self.zone.id) - - if self.hypervisor.lower() in ('vmware', 'hyperv'): - # SSH into SSVMs is done via management server for Vmware and Hyper-V - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - ssvm.privateip, - "mount | grep 'type nfs'", - hypervisor=self.hypervisor) - - for res in result: - split_res = res.split("on") - mounted_img_store_url = split_res[0].strip() - for img_store in image_stores_response: - img_store_url = str(img_store.url) - if img_store_url.startswith("nfs://"): - img_store_url = img_store_url[6:] - #Add colon after ip address to match output from mount command - first_slash = img_store_url.find('/') - img_store_url = img_store_url[0:first_slash] + ':' + img_store_url[first_slash:] - if img_store_url == mounted_img_store_url: - img_store_id = img_store.id - break - - self.assertNotEqual( - img_store_id, - None, - "Check image store id mounted on SSVM" - ) - - #Update NFS version for image store mounted on SSVM - updateConfigurationCmd = updateConfiguration.updateConfigurationCmd() - updateConfigurationCmd.name = "secstorage.nfs.version" - updateConfigurationCmd.value = nfs_version - updateConfigurationCmd.imagestoreuuid = img_store_id - - updateConfigurationResponse = self.apiclient.updateConfiguration(updateConfigurationCmd) - self.logger.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value)) - - #Stop SSVM - self.debug("Stopping SSVM: %s" % ssvm.id) - cmd = stopSystemVm.stopSystemVmCmd() - cmd.id = ssvm.id - self.apiclient.stopSystemVm(cmd) - - new_list_ssvm_response = self.checkForRunningSystemVM(ssvm) - - self.assertNotEqual( - new_list_ssvm_response, - None - ) - self.assertEqual( - isinstance(new_list_ssvm_response, list), - True, - "Check list response returns a valid list" - ) - ssvm = new_list_ssvm_response[0] - self.debug("SSVM state after debug: %s" % ssvm.state) - self.assertEqual( - ssvm.state, - 'Running', - "Check whether SSVM is running or not" - ) - # Wait for the agent to be up - self.waitForSystemVMAgent(ssvm.name) - - #Check NFS version on mounted image store - result = get_process_status( - self.apiclient.connection.mgtSvr, - 22, - self.apiclient.connection.user, - self.apiclient.connection.passwd, - ssvm.privateip, - "mount | grep '%s'"%mounted_img_store_url, - hypervisor=self.hypervisor) - - self.assertNotEqual( - result, - None - ) - self.assertEqual( - len(result), - 1, - "Check result length" - ) - - res = result[0] - mounted_nfs_version = res.split("vers=")[1][0:1] - self.assertEqual( - int(mounted_nfs_version), - int(nfs_version), - "Check mounted NFS version to be the same as provided" - ) diff --git a/Ansible/roles/marvin/files/smoke/test_vm_life_cycle.py b/Ansible/roles/marvin/files/smoke/test_vm_life_cycle.py deleted file mode 100644 index d06c4916caa..00000000000 --- a/Ansible/roles/marvin/files/smoke/test_vm_life_cycle.py +++ /dev/null @@ -1,1088 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -""" BVT tests for Virtual Machine Life Cycle -""" -#Import Local Modules -from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (recoverVirtualMachine, - destroyVirtualMachine, - attachIso, - detachIso, - provisionCertificate, - updateConfiguration) -from marvin.lib.utils import * - -from marvin.lib.base import (Account, - ServiceOffering, - VirtualMachine, - Host, - Iso, - Router, - Configurations) -from marvin.lib.common import (get_domain, - get_zone, - get_template, - get_test_template, - list_hosts) -from marvin.codes import FAILED, PASS -from nose.plugins.attrib import attr -#Import System modules -import time -import re - -_multiprocess_shared_ = True - -def getTemplateForTest(apiclient, zoneid, ostypeid, hypervisor): - template = FAILED - if hypervisor.lower() in ["xenserver"]: - template = get_test_template( - apiclient, - zoneid, - hypervisor) - if template == FAILED: - template = get_template( - apiclient, - zoneid, - ostypeid) - return template - -class Test01DeployVM(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - testClient = super(Test01DeployVM, cls).getClsTestClient() - cls.apiclient = testClient.getApiClient() - cls.services = testClient.getParsedTestDataConfig() - - # Get Zone, Domain and templates - cls.domain = get_domain(cls.apiclient) - cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) - cls.services['mode'] = cls.zone.networktype - cls.hypervisor = testClient.getHypervisorInfo() - - #If local storage is enabled, alter the offerings to use localstorage - #this step is needed for devcloud - if cls.zone.localstorageenabled == True: - cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' - cls.services["service_offerings"]["small"]["storagetype"] = 'local' - cls.services["service_offerings"]["medium"]["storagetype"] = 'local' - - template = getTemplateForTest(cls.apiclient, cls.zone.id, cls.services["ostype"], cls.hypervisor) - if template == FAILED: - assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] - - # Set Zones and disk offerings - cls.services["small"]["zoneid"] = cls.zone.id - cls.services["small"]["template"] = template.id - - cls.services["iso1"]["zoneid"] = cls.zone.id - - cls.account = Account.create( - cls.apiclient, - cls.services["account"], - domainid=cls.domain.id - ) - cls.debug(cls.account.id) - - cls.service_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["tiny"] - ) - - cls.virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services["small"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services['mode'] - ) - - cls.cleanup = [ - cls.service_offering, - cls.account - ] - - @classmethod - def tearDownClass(cls): - try: - cleanup_resources(cls.apiclient, cls.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_01_deploy_vm(self): - """Test Deploy Virtual Machine - """ - # Validate the following: - # 1. Virtual Machine is accessible via SSH - # 2. listVirtualMachines returns accurate information - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.virtual_machine.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM available in List Virtual Machines" - ) - vm_response = list_vm_response[0] - self.assertEqual( - - vm_response.id, - self.virtual_machine.id, - "Check virtual machine id in listVirtualMachines" - ) - self.assertEqual( - vm_response.name, - self.virtual_machine.name, - "Check virtual machine name in listVirtualMachines" - ) - self.assertEqual( - vm_response.state, - 'Running', - msg="VM is not in Running state" - ) - return - - - @attr(tags = ["advanced"], required_hardware="false") - def test_02_advZoneVirtualRouter(self): - #TODO: SIMENH: duplicate test, remove it - """ - Test advanced zone virtual router - 1. Is Running - 2. is in the account the VM was deployed in - 3. Has a linklocalip, publicip and a guestip - @return: - """ - routers = Router.list(self.apiclient, account=self.account.name) - self.assertTrue(len(routers) > 0, msg = "No virtual router found") - router = routers[0] - - self.assertEqual(router.state, 'Running', msg="Router is not in running state") - self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account") - - #Has linklocal, public and guest ips - self.assertIsNotNone(router.linklocalip, msg="Router has no linklocal ip") - self.assertIsNotNone(router.publicip, msg="Router has no public ip") - self.assertIsNotNone(router.guestipaddress, msg="Router has no guest ip") - - - @attr(mode = ["basic"], required_hardware="false") - def test_03_basicZoneVirtualRouter(self): - #TODO: SIMENH: duplicate test, remove it - """ - Tests for basic zone virtual router - 1. Is Running - 2. is in the account the VM was deployed in - @return: - """ - routers = Router.list(self.apiclient, account=self.account.name) - self.assertTrue(len(routers) > 0, msg = "No virtual router found") - router = routers[0] - - self.assertEqual(router.state, 'Running', msg="Router is not in running state") - self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account") - - @attr(tags = ['advanced','basic','sg'], required_hardware="false") - def test_04_deploy_vm_multiple(self): - """Test Multiple Deploy Virtual Machine - - # Validate the following: - # 1. deploy 2 virtual machines - # 2. listVirtualMachines using 'ids' parameter returns accurate information - """ - account = Account.create( - self.apiclient, - self.services["account"], - domainid=self.domain.id - ) - self.cleanup.append(account) - - virtual_machine1 = VirtualMachine.create( - self.apiclient, - self.services["small"], - accountid=account.name, - domainid=account.domainid, - serviceofferingid=self.service_offering.id - ) - virtual_machine2 = VirtualMachine.create( - self.apiclient, - self.services["small"], - accountid=account.name, - domainid=account.domainid, - serviceofferingid=self.service_offering.id - ) - - list_vms = VirtualMachine.list(self.apiclient, ids=[virtual_machine1.id, virtual_machine2.id], listAll=True) - self.debug( - "Verify listVirtualMachines response for virtual machines: %s, %s" % (virtual_machine1.id, virtual_machine2.id) - ) - self.assertEqual( - isinstance(list_vms, list), - True, - "List VM response was not a valid list" - ) - self.assertEqual( - len(list_vms), - 2, - "List VM response was empty, expected 2 VMs" - ) - - def tearDown(self): - try: - # Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - -class Test02VMLifeCycle(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - testClient = super(Test02VMLifeCycle, cls).getClsTestClient() - cls.apiclient = testClient.getApiClient() - cls.services = testClient.getParsedTestDataConfig() - cls.hypervisor = testClient.getHypervisorInfo() - - # Get Zone, Domain and templates - domain = get_domain(cls.apiclient) - cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) - cls.services['mode'] = cls.zone.networktype - - #if local storage is enabled, alter the offerings to use localstorage - #this step is needed for devcloud - if cls.zone.localstorageenabled == True: - cls.services["service_offerings"]["tiny"]["storagetype"] = 'local' - cls.services["service_offerings"]["small"]["storagetype"] = 'local' - cls.services["service_offerings"]["medium"]["storagetype"] = 'local' - - template = getTemplateForTest(cls.apiclient, cls.zone.id, cls.services["ostype"], cls.hypervisor) - if template == FAILED: - assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] - - # Set Zones and disk offerings - cls.services["small"]["zoneid"] = cls.zone.id - cls.services["small"]["template"] = template.id - - cls.services["iso1"]["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.apiclient, - cls.services["account"], - domainid=domain.id - ) - - cls.small_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["small"] - ) - - cls.medium_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["medium"] - ) - #create small and large virtual machines - cls.small_virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services["small"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.small_offering.id, - mode=cls.services["mode"] - ) - cls.medium_virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services["small"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.medium_offering.id, - mode=cls.services["mode"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.apiclient, - cls.services["small"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.small_offering.id, - mode=cls.services["mode"] - ) - cls._cleanup = [ - cls.small_offering, - cls.medium_offering, - cls.account - ] - - @classmethod - def tearDownClass(cls): - cls.apiclient = super(Test02VMLifeCycle, cls).getClsTestClient().getApiClient() - try: - cleanup_resources(cls.apiclient, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - def tearDown(self): - try: - #Clean up, terminate the created ISOs - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_05_stop_vm(self): - """Test Stop Virtual Machine - """ - - # Validate the following - # 1. Should Not be able to login to the VM. - # 2. listVM command should return - # this VM.State of this VM should be ""Stopped"". - try: - self.small_virtual_machine.stop(self.apiclient) - except Exception as e: - self.fail("Failed to stop VM: %s" % e) - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_06_stop_vm_forced(self): - """Test Force Stop Virtual Machine - """ - try: - self.small_virtual_machine.stop(self.apiclient, forced=True) - except Exception as e: - self.fail("Failed to stop VM: %s" % e) - - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM avaliable in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].state, - "Stopped", - "Check virtual machine is in stopped state" - ) - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_07_start_vm(self): - """Test Start Virtual Machine - """ - # Validate the following - # 1. listVM command should return this VM.State - # of this VM should be Running". - - self.debug("Starting VM - ID: %s" % self.virtual_machine.id) - self.small_virtual_machine.start(self.apiclient) - - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM avaliable in List Virtual Machines" - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" \ - % self.small_virtual_machine.id - ) - self.assertEqual( - list_vm_response[0].state, - "Running", - "Check virtual machine is in running state" - ) - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_08_reboot_vm(self): - """Test Reboot Virtual Machine - """ - - # Validate the following - # 1. Should be able to login to the VM. - # 2. listVM command should return the deployed VM. - # State of this VM should be "Running" - - self.debug("Rebooting VM - ID: %s" % self.virtual_machine.id) - self.small_virtual_machine.reboot(self.apiclient) - - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM avaliable in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].state, - "Running", - "Check virtual machine is in running state" - ) - return - - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_09_destroy_vm(self): - """Test destroy Virtual Machine - """ - - # Validate the following - # 1. Should not be able to login to the VM. - # 2. listVM command should return this VM.State - # of this VM should be "Destroyed". - - self.debug("Destroy VM - ID: %s" % self.small_virtual_machine.id) - self.small_virtual_machine.delete(self.apiclient, expunge=False) - - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM avaliable in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].state, - "Destroyed", - "Check virtual machine is in destroyed state" - ) - return - - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_10_restore_vm(self): - #TODO: SIMENH: add another test the data on the restored VM. - """Test recover Virtual Machine - """ - - # Validate the following - # 1. listVM command should return this VM. - # State of this VM should be "Stopped". - # 2. We should be able to Start this VM successfully. - - self.debug("Recovering VM - ID: %s" % self.small_virtual_machine.id) - - cmd = recoverVirtualMachine.recoverVirtualMachineCmd() - cmd.id = self.small_virtual_machine.id - self.apiclient.recoverVirtualMachine(cmd) - - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(list_vm_response), - 0, - "Check VM avaliable in List Virtual Machines" - ) - - self.assertEqual( - list_vm_response[0].state, - "Stopped", - "Check virtual machine is in Stopped state" - ) - - return - - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"], required_hardware="false") - def test_11_migrate_vm(self): - """Test migrate VM - """ - # Validate the following - # 1. Environment has enough hosts for migration - # 2. DeployVM on suitable host (with another host in the cluster) - # 3. Migrate the VM and assert migration successful - - suitable_hosts = None - - hosts = Host.list( - self.apiclient, - zoneid=self.zone.id, - type='Routing' - ) - self.assertEqual(validateList(hosts)[0], PASS, "hosts list validation failed") - - if len(hosts) < 2: - self.skipTest("At least two hosts should be present in the zone for migration") - - if self.hypervisor.lower() in ["lxc"]: - self.skipTest("Migration is not supported on LXC") - - # For KVM, two hosts used for migration should be present in same cluster - # For XenServer and VMware, migration is possible between hosts belonging to different clusters - # with the help of XenMotion and Vmotion respectively. - - if self.hypervisor.lower() in ["kvm","simulator"]: - #identify suitable host - clusters = [h.clusterid for h in hosts] - #find hosts withe same clusterid - clusters = [cluster for index, cluster in enumerate(clusters) if clusters.count(cluster) > 1] - - if len(clusters) <= 1: - self.skipTest("In " + self.hypervisor.lower() + " Live Migration needs two hosts within same cluster") - - suitable_hosts = [host for host in hosts if host.clusterid == clusters[0]] - else: - suitable_hosts = hosts - - target_host = suitable_hosts[0] - migrate_host = suitable_hosts[1] - - #deploy VM on target host - self.vm_to_migrate = VirtualMachine.create( - self.apiclient, - self.services["small"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.small_offering.id, - mode=self.services["mode"], - hostid=target_host.id - ) - self.debug("Migrating VM-ID: %s to Host: %s" % ( - self.vm_to_migrate.id, - migrate_host.id - )) - - self.vm_to_migrate.migrate(self.apiclient, migrate_host.id) - - retries_cnt = 3 - while retries_cnt >=0: - list_vm_response = VirtualMachine.list(self.apiclient, - id=self.vm_to_migrate.id) - self.assertNotEqual( - list_vm_response, - None, - "Check virtual machine is listed" - ) - vm_response = list_vm_response[0] - self.assertEqual(vm_response.id,self.vm_to_migrate.id,"Check virtual machine ID of migrated VM") - self.assertEqual(vm_response.hostid,migrate_host.id,"Check destination hostID of migrated VM") - retries_cnt = retries_cnt - 1 - return - - @attr(configuration = "expunge.interval") - @attr(configuration = "expunge.delay") - @attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false") - def test_12_expunge_vm(self): - """Test destroy(expunge) Virtual Machine - """ - # Validate the following - # 1. listVM command should NOT return this VM any more. - - self.debug("Expunge VM-ID: %s" % self.small_virtual_machine.id) - - cmd = destroyVirtualMachine.destroyVirtualMachineCmd() - cmd.id = self.small_virtual_machine.id - self.apiclient.destroyVirtualMachine(cmd) - - config = Configurations.list( - self.apiclient, - name='expunge.delay' - ) - - expunge_delay = int(config[0].value) - time.sleep(expunge_delay * 2) - - #VM should be destroyed unless expunge thread hasn't run - #Wait for two cycles of the expunge thread - config = Configurations.list( - self.apiclient, - name='expunge.interval' - ) - expunge_cycle = int(config[0].value) - wait_time = expunge_cycle * 4 - while wait_time >= 0: - list_vm_response = VirtualMachine.list( - self.apiclient, - id=self.small_virtual_machine.id - ) - if not list_vm_response: - break - self.debug("Waiting for VM to expunge") - time.sleep(expunge_cycle) - wait_time = wait_time - expunge_cycle - - self.debug("listVirtualMachines response: %s" % list_vm_response) - - self.assertEqual(list_vm_response,None,"Check Expunged virtual machine is in listVirtualMachines response") - return - - @attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="true") - def test_13_attachAndDetach_iso(self): - """Test for attach and detach ISO to virtual machine""" - - # Validate the following - # 1. Create ISO - # 2. Attach ISO to VM - # 3. Log in to the VM. - # 4. The device should be available for use - # 5. Detach ISO - # 6. Check the device is properly detached by logging into VM - - if self.hypervisor.lower() in ["lxc"]: - self.skipTest("ISOs are not supported on LXC") - - iso = Iso.create( - self.apiclient, - self.services["iso1"], - account=self.account.name, - domainid=self.account.domainid - ) - - self.debug("Successfully created ISO with ID: %s" % iso.id) - try: - iso.download(self.apiclient) - except Exception as e: - self.fail("Exception while downloading ISO %s: %s"\ - % (iso.id, e)) - - self.debug("Attach ISO with ID: %s to VM ID: %s" % ( - iso.id, - self.virtual_machine.id - )) - #Attach ISO to virtual machine - cmd = attachIso.attachIsoCmd() - cmd.id = iso.id - cmd.virtualmachineid = self.virtual_machine.id - self.apiclient.attachIso(cmd) - - try: - ssh_client = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - mount_dir = "/mnt/tmp" - cmds = "mkdir -p %s" % mount_dir - self.assert_(ssh_client.execute(cmds) == [], "mkdir failed within guest") - - iso_unsupported = False - for diskdevice in self.services["diskdevice"]: - res = ssh_client.execute("mount -rt iso9660 {} {}".format(diskdevice, mount_dir)) - if res == []: - self.services["mount"] = diskdevice - break - if str(res).find("mount: unknown filesystem type 'iso9660'") != -1: - iso_unsupported = True - log_msg = "Test template does not supports iso9660 filesystem. Proceeding with test without mounting." - self.debug(log_msg) - print log_msg - break - else: - self.fail("No mount points matched. Mount was unsuccessful") - - if iso_unsupported == False: - c = "mount |grep %s|head -1" % self.services["mount"] - res = ssh_client.execute(c) - size = ssh_client.execute("du %s | tail -1" % self.services["mount"]) - self.debug("Found a mount point at %s with size %s" % (res, size)) - - # Get ISO size - iso_response = Iso.list( - self.apiclient, - id=iso.id) - self.assertEqual( - isinstance(iso_response, list), - True, - "Check list response returns a valid list") - - try: - # Unmount ISO - command = "umount %s" % mount_dir - ssh_client.execute(command) - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Detach from VM - cmd = detachIso.detachIsoCmd() - cmd.virtualmachineid = self.virtual_machine.id - self.apiclient.detachIso(cmd) - - if iso_unsupported == False: - try: - res = ssh_client.execute(c) - except Exception as e: - self.fail("SSH failed for virtual machine: %s - %s" % - (self.virtual_machine.ipaddress, e)) - - # Check if ISO is properly detached from VM (using fdisk) - result = self.services["mount"] in str(res) - - self.assertEqual( - result, - False, - "Check if ISO is detached from virtual machine") - return - -class Test03SecuredVmMigration(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - testClient = super(Test03SecuredVmMigration, cls).getClsTestClient() - cls.apiclient = testClient.getApiClient() - cls.services = testClient.getParsedTestDataConfig() - cls.hypervisor = testClient.getHypervisorInfo() - cls._cleanup = [] - - if cls.hypervisor.lower() not in ["kvm"]: - return - - # Get Zone, Domain and templates - domain = get_domain(cls.apiclient) - cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) - cls.services['mode'] = cls.zone.networktype - cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ - cls.management_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"] - - template = getTemplateForTest(cls.apiclient, cls.zone.id, cls.services["ostype"], cls.hypervisor) - if template == FAILED: - assert False, "get_template() failed to return template with description %s" % cls.services["ostype"] - - # Set Zones and disk offerings - cls.services["small"]["zoneid"] = cls.zone.id - cls.services["small"]["template"] = template.id - - cls.services["iso1"]["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.apiclient, - cls.services["account"], - domainid=domain.id - ) - - cls.small_offering = ServiceOffering.create( - cls.apiclient, - cls.services["service_offerings"]["small"] - ) - - cls._cleanup = [ - cls.small_offering, - cls.account - ] - - @classmethod - def tearDownClass(cls): - if cls.hypervisor.lower() in ["kvm"]: - cls.apiclient = super(Test03SecuredVmMigration, cls).getClsTestClient().getApiClient() - cls.hosts = Host.list( - cls.apiclient, - zoneid=cls.zone.id, - type='Routing', - hypervisor='KVM') - for cls.host in cls.hosts: - Test03SecuredVmMigration.secure_host(cls.host) - - try: - cleanup_resources(cls.apiclient, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - - if self.hypervisor.lower() not in ["kvm"]: - self.skipTest("Secured migration is not supported on other than KVM") - - self.hosts = Host.list( - self.apiclient, - zoneid=self.zone.id, - type='Routing', - hypervisor='KVM', - state='Up') - - if len(self.hosts) < 2: - self.skipTest("Requires at least two hosts for performing migration related tests") - - self.updateConfiguration("ca.plugin.root.auth.strictness", "false") - - def tearDown(self): - self.updateConfiguration("ca.plugin.root.auth.strictness", "true") - try: - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - - def get_target_host(self, secured, virtualmachineid): - target_hosts = Host.listForMigration(self.apiclient, - virtualmachineid=virtualmachineid) - for host in target_hosts: - h = list_hosts(self.apiclient,type='Routing', id=host.id)[0] - if h.details.secured == secured: - return h - - cloudstackTestCase.skipTest(self, "No target hosts available, skipping test.") - - def check_migration_protocol(self, protocol, host): - resp = SshClient(host.ipaddress, port=22, user=self.hostConfig["username"],passwd=self.hostConfig["password"])\ - .execute("grep -a listen_%s.*=.*1 /etc/libvirt/libvirtd.conf | tail -1" % protocol) - - if protocol not in resp[0]: - cloudstackTestCase.fail(self, "Libvirt listen protocol expected: '" + protocol + "\n" - "does not match actual: " + resp[0]) - - def migrate_and_check(self, vm, src_host, dest_host, proto='tls'): - """ - Migrates a VM from source host to destination host and checks status - """ - self.check_migration_protocol(protocol=proto, host=src_host) - vm.migrate(self.apiclient, hostid=dest_host.id) - vm_response = VirtualMachine.list(self.apiclient, id=vm.id)[0] - self.assertEqual(vm_response.hostid, dest_host.id, "Check destination host ID of migrated VM") - - @classmethod - def waitUntilHostInState(self, hostId, state="Up", interval=5, retries=20): - while retries > -1: - time.sleep(interval) - host = Host.list( - self.apiclient, - hostid=hostId, - type='Routing' - )[0] - print("Waiting for host: %s to be %s. Currently %s. %s retries left." % (hostId, state, host.details.secured, retries)) - print("Host state is: %s" % host.state) - if host.state != state: - if retries >= 0: - retries = retries - 1 - continue - else: - print("Host %s now showing as %s" % (hostId, state)) - return - - @classmethod - def unsecure_host(self, host): - print("host %s secured parameter is: %s and should be 'false'" % (host.name, host.details.secured)) - if "false" not in host.details.secured: - print("Unsecuring Host: %s" % host.name) - SshClient(host.ipaddress, port=22, user=self.hostConfig["username"], passwd=self.hostConfig["password"])\ - .execute("rm -f /etc/cloudstack/agent/cloud* && \ - service cloudstack-agent stop ; \ - service libvirtd stop ; \ - service libvirt-bin stop ; \ - sed -i '/listen_tls.*/ c\listen_tls = 0' /etc/libvirt/libvirtd.conf ; \ - sed -i '/listen_tcp.*/ c\listen_tcp = 1' /etc/libvirt/libvirtd.conf ; \ - sed -i '/.*_file.*=.*/d' /etc/libvirt/libvirtd.conf ; \ - service libvirtd start ; \ - service libvirt-bin start ; \ - sleep 30 ; \ - service cloudstack-agent start") - print("Allowing quiet time to allow CloudStack to see host %s state" % host.name) - time.sleep(30) - self.waitUntilHostInState(hostId=host.id, state="Up") - self.check_connection(secured='false', host=host) - return host - else: - print("Host %s already unsecure, continuing" % (host.name)) - return host - - @classmethod - def secure_host(self, host): - print("host %s secured parameter is: %s and should be 'true'" % (host.name, host.details.secured)) - if "true" in host.details.secured: - print ("Host %s already secure, continuing" % (host.name)) - return host - else: - print("Securing Host %s" % host.name) - cmd = provisionCertificate.provisionCertificateCmd() - cmd.hostid = host.id - cmd.reconnect = True - self.apiclient.provisionCertificate(cmd) - print("Allowing quiet time to allow CloudStack to see host %s state" % host.name) - time.sleep(30) - self.waitUntilHostInState(hostId=host.id, state="Up") - self.check_connection(secured='true', host=host) - return host - - def deploy_vm(self, origin_host): - return VirtualMachine.create( - self.apiclient, - self.services["small"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.small_offering.id, - mode=self.services["mode"], - hostid=origin_host.id) - - @classmethod - def check_connection(self, secured, host, retries=20, interval=6): - print("Checking connection for host: %s" % host.name) - while retries > -1: - time.sleep(interval) - host = Host.list( - self.apiclient, - zoneid=self.zone.id, - hostid=host.id, - type='Routing' - )[0] - - if 'secured' in host.details.secured: - if retries >= 0: - retries = retries - 1 - continue - else: - return - - raise Exception("Host detail 'secured' was expected: " + secured + - ", actual is: " + host.details.secured.rstrip()) - - def updateConfiguration(self, name, value): - cmd = updateConfiguration.updateConfigurationCmd() - cmd.name = name - cmd.value = value - self.apiclient.updateConfiguration(cmd) - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false") - def test_14_secure_to_secure_vm_migration(self): - """Test secure VM migration""" - # Validate the following - # 1. Environment has enough hosts for migration - # 2. DeployVM on suitable host (with another host in the cluster) - # 3. Migrate the VM and assert migration successful - - for host in self.hosts: - print("Test requires host %s to be secure" % (host.name)) - self.secure_host(host) - self.waitUntilHostInState(hostId=host.id, state="Up") - - src_host = self.hosts[0] - vm = self.deploy_vm(src_host) - self.cleanup.append(vm) - - dest_host = self.get_target_host(secured='true', virtualmachineid=vm.id) - self.migrate_and_check(vm, src_host, dest_host) - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false") - def test_15_secured_to_nonsecured_vm_migration(self): - """Test destroy Virtual Machine - """ - # Validate the following - # 1. Makes one of the hosts non-secured - # 2. Deploys a VM to a Secured host - # 3. Migrates the VM to the non-secured host via TLS, and ensure exception - - print("Test requires host %s to be unsecure" % (self.hosts[0].name)) - unsecure_host = self.unsecure_host(self.hosts[0]) - print("Test requires host %s to be secure" % (self.hosts[1].name)) - secure_host = self.secure_host(self.hosts[1]) - - vm = self.deploy_vm(secure_host) - self.cleanup.append(vm) - - try: - self.migrate_and_check(vm, secure_host, unsecure_host, proto='tls') - except Exception: - pass - else: self.fail("Migration succeeded, instead it should fail") - - @attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg", "security"], required_hardware="false") - def test_16_nonsecured_to_secured_vm_migration(self): - """Test Non-secured VM Migration - """ - # Validate the following - # 1. Makes one of the hosts non-secured - # 2. Deploys a VM to the non-secured host - # 3. Migrates the VM to the non-secured host via TCP, and ensure exception - - - print("Test requires host %s to be unsecure" % (self.hosts[0].name)) - unsecure_host = self.unsecure_host(self.hosts[0]) - print("Test requires host %s to be secure" % (self.hosts[1].name)) - secure_host = self.secure_host(self.hosts[1]) - - vm = self.deploy_vm(unsecure_host) - self.cleanup.append(vm) - - try: - self.migrate_and_check(vm, unsecure_host, secure_host, proto='tcp') - except Exception: - pass - else: self.fail("Migration succeeded, instead it should fail") diff --git a/Ansible/roles/marvin/files/xunit-reader.py b/Ansible/roles/marvin/files/xunit-reader.py index ffa00a8b038..6e402e53af0 100644 --- a/Ansible/roles/marvin/files/xunit-reader.py +++ b/Ansible/roles/marvin/files/xunit-reader.py @@ -80,7 +80,7 @@ def parse_reports(file_path_list): tests = [] for file_path in file_path_list: filename = file_path[file_path.find('test_'):].replace('.xml', '') - data = lxml.etree.iterparse(file_path, tag='testcase') + data = lxml.etree.iterparse(file_path, tag='testcase', huge_tree=True) for event, elem in data: name = '' status = 'Success' @@ -103,7 +103,7 @@ def parse_reports(file_path_list): for test in tests: print("%s | %s | %.2f | %s" % (test[0], test[1], float(test[2]), test[3])) - print("") + # print("") return exit_code diff --git a/Ansible/roles/marvin/tasks/fix_tests.yml b/Ansible/roles/marvin/tasks/fix_tests.yml index 1cb2e6887f2..244d7803067 100644 --- a/Ansible/roles/marvin/tasks/fix_tests.yml +++ b/Ansible/roles/marvin/tasks/fix_tests.yml @@ -42,11 +42,8 @@ dest: /marvin/tests/smoke/ mode: 0755 with_fileglob: - - ../files/smoke/* + - ../files/smoke/*.py tags: - marvin - marvin_cfg - marvin_fix_tests - - - diff --git a/Ansible/roles/marvin/tasks/install_marvin_prereqs.yml b/Ansible/roles/marvin/tasks/install_marvin_prereqs.yml index e5036d49763..0e3968cbf00 100644 --- a/Ansible/roles/marvin/tasks/install_marvin_prereqs.yml +++ b/Ansible/roles/marvin/tasks/install_marvin_prereqs.yml @@ -80,6 +80,18 @@ - marvin - marvin_install +- name: Install mysql-connector-python + yum: name=mysql-connector-python state=latest + tags: + - marvin + - marvin_install + +- name: Install mysql-connector-python + yum: name=mysql-connector-python state=latest + tags: + - marvin + - marvin_install + - name: remove yum openSSL package yum: name: pyOpenSSL @@ -94,23 +106,28 @@ - six - pyOpenSSL - wheel==0.34.2 - - kubernetes - '"requests[security]"' - pyasn1 - wget - texttable - lxml + - paramiko tags: - marvin - marvin_install +- name: Workaround for pip install kubernetes + pip: + name: "kubernetes" + extra_args: '--ignore-installed' + - name: Update pip3 and components pip: name: "{{ item }}" executable: pip3 extra_args: '--upgrade' with_items: - - pip==20.2.1 + - pip==21.3.1 - six - pyOpenSSL - wheel==0.34.2 @@ -121,10 +138,15 @@ - texttable - lxml - pycparser==2.13 + - paramiko + - mysql-connector-python==8.0.29 tags: - marvin - marvin_install +- name: Clear all yum cache + command: yum clean all + - name: Ensure CA-Certificates are up to date yum: name: ca-certificates diff --git a/Ansible/roles/marvin/tasks/main.yml b/Ansible/roles/marvin/tasks/main.yml index 07bd01d9119..2caba03ab8e 100644 --- a/Ansible/roles/marvin/tasks/main.yml +++ b/Ansible/roles/marvin/tasks/main.yml @@ -179,6 +179,12 @@ - marvin - marvin_cfg +- name: create common functions file + template: src="common_functions.sh.j2" dest="/marvin/common_functions.sh" mode=0755 + tags: + - marvin + - marvin_cfg + - name: create smoketest file template: src="smoketests.sh.j2" dest="/marvin/smoketests.sh" mode=0755 tags: diff --git a/Ansible/roles/marvin/templates/advanced-cfg.j2 b/Ansible/roles/marvin/templates/advanced-cfg.j2 index f27efad96eb..6fd74efe554 100644 --- a/Ansible/roles/marvin/templates/advanced-cfg.j2 +++ b/Ansible/roles/marvin/templates/advanced-cfg.j2 @@ -115,11 +115,13 @@ "gateway": "{{ env_podgw }}" }], "internaldns1": "{{ env_zone_intdns1 }}", - "secondaryStorages": [{ + "secondaryStorages": [ {% for secpool in env_secpools %} + { "url": "nfs://{{ env_sechost }}{{ env_secpath }}{{ env_name_clean }}/{{ secpool }}/", "name": "{{ secpool }}", - "provider": "NFS"}{% if not loop.last %},{% endif %} + "provider": "NFS" + }{% if not loop.last %},{% endif %} {% endfor %} ] }], @@ -260,4 +262,4 @@ "certCAPath": "NA", "certPath": "NA" }] -} \ No newline at end of file +} diff --git a/Ansible/roles/marvin/templates/common_functions.sh.j2 b/Ansible/roles/marvin/templates/common_functions.sh.j2 new file mode 100644 index 00000000000..b2a34df7de3 --- /dev/null +++ b/Ansible/roles/marvin/templates/common_functions.sh.j2 @@ -0,0 +1,219 @@ +#!/bin/bash +#Copyright 2016 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +remove_old_files() { + rm -f $CLEAN_UP_LOG + rm -f $SUMMARY_FILE + rm -rf $TESTDIR/test_*.pyc + rm -f /usr/lib/python2.7/site-packages/marvin/*pyc + rm -f /usr/lib/python2.7/site-packages/marvin/config/*pyc + rm -f /usr/lib/python2.7/site-packages/marvin/lib/*pyc + rm -f /usr/local/lib/python3.6/site-packages/marvin/*pyc + rm -f /usr/local/lib/python3.6/site-packages/marvin/config/*pyc + rm -f /usr/local/lib/python3.6/site-packages/marvin/lib/*pyc + touch $CLEAN_UP_LOG +} + +record_existing_entities() { + cmk list accounts listall=true name="baremetal-system-account" | jq -r '.account[] .id' > .skipdeletingaccounts + cmk list accounts listall=true name="ACSuser" | jq -r '.account[] .id' >> .skipdeletingaccounts + cmk list accounts listall=true name="admin" | jq -r '.account[] .id' >> .skipdeletingaccounts + cmk list serviceofferings listall=true issystem=false name='medium instance' | jq -r '.serviceoffering[].id' > .skipdeleteofferings + cmk list serviceofferings listall=true issystem=false name='small instance' | jq -r '.serviceoffering[].id' >> .skipdeleteofferings + cmk list diskofferings listall=true issystem=false name='small' | jq -r '.diskoffering[].id' > .skipdeletediskofferings + cmk list diskofferings listall=true issystem=false name='medium' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings + cmk list diskofferings listall=true issystem=false name='large' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings + cmk list diskofferings listall=true issystem=false name='custom' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings + cmk list domains listall=true name="root" | jq -r '.domain[].id' > .skipdeletingdomains +} + +cleanup() { + # dont wait for async job - execute in parallel until told otherwise + cmk set asyncblock false + cmk set output json + # TODO: destroy accounts, domains, templates + echo "Destroy alerts" + for id in $(cmk list alerts listall=true keyword=vm | jq -r '.alert[] .id'); do + cmk delete alerts ids=$id || true + done + + echo "Destroy vms, all in parallel" + NUM_GCVMS=`cmk list virtualmachines listall=true $GCVMS | jq -r '.virtualmachine[].id' | wc -l` + if [[ $NUM_GCVMS -gt $STUCKVMS ]]; then + echo "$(basename $file) left behind $(($NUM_GCVMS-$STUCKVMS)) VMs" >> $CLEAN_UP_LOG + for vmid in $(cmk list virtualmachines listall=true $GCVMS | jq -r '.virtualmachine[].id'); do + cmk destroy virtualmachine id=$vmid expunge=true || true + done + echo "wait ${sleepduration}s to give VMs some time to be destroyed" + sleep $sleepduration + fi + + tries=$retries + while [ $tries -gt 0 ] + do + echo "retrying destroying remaining vms $tries more times, again in parallel" + NUM_GCVMS=`cmk list virtualmachines listall=true| jq -r '.virtualmachine[].id' | wc -l` + if [[ $NUM_GCVMS -gt $STUCKVMS ]]; then + echo "Still $NUM_GCVMS left. waiting.." + sleep $sleepduration + tries=$((tries)-1) + if [ $tries -eq 0 ]; then STUCKVMS=$NUM_GCVMS; fi + else + tries=0 + fi + done + + echo "Destroy templates, forced, since some VMs might exist." + NUM_GCTEMPLATES=`cmk list templates templatefilter=self listall=true | jq -r '.template[].id' | wc -l` + if [[ $NUM_GCTEMPLATES -gt $STUCKTEMPLATES ]]; then + echo "$(basename $file) left behind $(($NUM_GCTEMPLATES-$STUCKTEMPLATES)) templates" >> $CLEAN_UP_LOG + cmk set asyncblock true + for templateid in $(cmk list templates templatefilter=self listall=true | jq -r '.template[].id'); do + cmk delete template id=$templateid forced=true || true + done + STUCKTEMPLATES=`cmk list templates templatefilter=self | jq -r '.template[].id' | wc -l` + fi + + tries=$retries + echo "deleting networks" + NUM_GCNETWORKS=`cmk list networks listall=true | jq -r '.network[].id' | wc -l` + if [[ $NUM_GCNETWORKS -gt $STUCKNETWORKS ]]; then + echo "$(basename $file) left behind $(($NUM_GCNETWORKS-$STUCKNETWORKS)) Networks" >> $CLEAN_UP_LOG + while [ $tries -gt 0 ] + do + for netid in $(cmk list networks listall=true | jq -r '.network[].id'); do + cmk delete network id=$netid || true + done + echo "wait ${sleepduration}s to give Networks some time to destroy" + sleep $sleepduration + NUM_GCNETWORKS=`cmk list networks listall=true | jq -r '.network[].id' | wc -l` + if [[ $NUM_GCNETWORKS -gt $STUCKVMS ]]; then + tries=$((tries)-1) + else + tries=0 + fi + done + STUCKNETWORKS=$NUM_GCNETWORKS + fi + + tries=$retries + echo "deleting VPCs" + NUM_GCVPCS=`cmk list vpcs listall=true | jq -r '.vpc[].id' | wc -l` + if [[ $NUM_GCVPC -gt $STUCKVPCS ]]; then + echo "$(basename $file) left behind $(($NUM_GCVPCS-$STUCKVPCS)) VPCs" >> $CLEAN_UP_LOG + while [ $tries -gt 0 ]; do + for vid in $(cmk list vpcs listall=true | jq -r '.vpc[].id'); do + cmk delete vpc id=$vid || true + done + sleep $sleepduration + NUM_GCVPCS=`cmk list vpcs listall=true |jq -r '.vpc[].id' | wc -l` + if [ $NUM_GCVPCS -gt $STUCKVPCS ]; then + tries=$(($tries)-1) + else + tries=0 + fi + done + STUCKVPCS=$NUM_GCVPCS + fi + + # move to blocking async calls (just volume deletion, should be very fast), so later we can delete accounts and domains + cmk set asyncblock true + + # Destroy data volumes when zero attached (all VMs deleted) + NUM_GCVOLS=$(cmk list volumes type=data | jq -r '.volume[].id' | wc -l) + if [[ $NUM_GCVOLS -gt $STUCKVOLS ]]; then + echo "$(basename $file) left behind $(($NUM_GCVOLS-$STUCKVOLS)) volumes" >> $CLEAN_UP_LOG + for volumeid in $(cmk list volumes listall=true type=data | jq -r '.volume[] .id'); do + cmk delete volume id=$volumeid || true + done + sleep $sleepduration + NUM_GCVOLS=`cmk list volumes listall=true type=data | jq -r '.volume[].id' | wc -l` + STUCKVOLS=$NUM_GCVOLS + fi + + # Destroy accounts (keep some, delete all others) + cmk list accounts listall=true | jq -r '.account[] .id' > .deleteaccounts + NUM_LEFT=`cat .deleteaccounts | wc -l` + if [[ $NUM_LEFT -gt 3 ]]; then + echo "$(basename $file) left behind $(($NUM_LEFT-3)) accounts" >> $CLEAN_UP_LOG + for accountid in $(comm -13 <(sort -u .skipdeletingaccounts) <(sort -u .deleteaccounts)); do + cmk delete account id=$accountid || true + done + fi + + # Destroy domains (keep ROOT domain, delete all other) + cmk list domains listall=true | jq -r '.domain[] .id' > .deletedomains + NUM_LEFT=`cat .deletedomains | wc -l` + if [[ $NUM_LEFT -gt 1 ]]; then + echo "$(basename $file) left behind $(($NUM_LEFT-1)) domains" >> $CLEAN_UP_LOG + for domainid in $(comm -13 <(sort -u .skipdeletingdomains) <(sort -u .deletedomains)); do + cmk delete domain id=$domainid || true + done + fi + + cmk list serviceofferings listall=true issystem=false | jq -r '.serviceoffering[].id' > .deleteofferings + NUM_LEFT=`cat .deleteofferings | wc -l` + if [[ $NUM_LEFT -gt 2 ]]; then + echo "$(basename $file) left behind $(($NUM_LEFT-2)) service offerings" >> $CLEAN_UP_LOG + for offeringid in $(comm -13 <(sort -u .skipdeleteofferings) <(sort -u .deleteofferings)); do + cmk delete serviceoffering id=$offeringid || true + done + fi + + cmk list diskofferings listall=true issystem=false | jq -r '.diskoffering[].id' > .deletediskofferings + NUM_LEFT=`cat .deletediskofferings | wc -l ` + if [[ $NUM_LEFT -gt 4 ]]; then + "$(basename $file) left behind $(($NUM_LEFT-3)) disk offerings" >> $CLEAN_UP_LOG + for offeringid in $(comm -13 <(sort -u .skipdeletediskofferings) <(sort -u .deletediskofferings)); do + cmk delete diskoffering id=$offeringid || true + done + fi + + rm -f .deleteaccounts + rm -f .deletedomains + rm -f .deleteofferings + rm -f .deletediskofferings +} + +slackmsg() { + messagebody=$1 + messagecolor=$2 + slack chat send \ + --channel "#testing" \ + --color $messagecolor \ + --text "$messagebody" \ + --title "$TESTTYPE update for {{ env_name_clean }}" \ + --title-link "$jenkinslink" +} + +runtest() { + file=$1 + rm -fr $LOGDIR/$(basename $file).xml + TRIMFILE=$(echo $(basename $file) | sed 's/.py$//g') + OLDRESULT=$(ls $LOGDIR | grep -E $TRIMFILE'_[a-zA-Z0-9]{6}$' | head -1) + if [ ! -z "${OLDRESULT// }" ]; then + echo "Found old test results, removing:" $LOGDIR/$OLDRESULT + rm -fr $LOGDIR/$OLDRESULT + fi + ${NOSETESTS} --with-xunit --xunit-file=$LOGDIR/$(basename $file).xml --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -s -a tags={{ env_zonetype | lower }}{% if marvin_test_categories is defined %}{% for category in marvin_test_categories %},{{ category }}{% endfor %}{% endif %} $file + cleanup || true +} + +launchtest() { + file=$1 + runtest $file + # Run tests once again on error or failure + ${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/$(basename $file).xml | grep -e Failure -e Error && cleanup && runtest $file && echo "Intermittent failure detected: $file" >> $SUMMARY_FILE +} diff --git a/Ansible/roles/marvin/templates/componenttests.sh.j2 b/Ansible/roles/marvin/templates/componenttests.sh.j2 index 647067ca54d..47515bd01ff 100644 --- a/Ansible/roles/marvin/templates/componenttests.sh.j2 +++ b/Ansible/roles/marvin/templates/componenttests.sh.j2 @@ -1,5 +1,4 @@ #!/bin/bash - #Copyright 2016 ShapeBlue # #Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,19 +17,33 @@ set +e # stop erroneous failures reported by Jenkins TESTTYPE="Component tests" LOGDIR=/marvin/MarvinLogs +TESTDIR="/marvin/tests/component" +SUMMARY_FILE=/marvin/componenttest-summary.txt TMP_JSON_DIR="/marvin/json_results/" +CLEAN_UP_LOG="/marvin/cleanup.log" mkdir -p $LOGDIR echo "$(date --iso-8601=minutes)" > /marvin/testrunstartdate +## prefer python 3 versions of these: PYTHON=`which python3 || which python` NOSETESTS=/usr/local/bin/nosetests -if [ ! -x `type -p ${NOSETESTS}` ] +if [ ! -x ${NOSETESTS} ] then - NOSETESTS=/usr/bin/nosetest + NOSETESTS=/usr/bin/nosetests fi -rm -f /marvin/tests/component/*.pyc -rm -f /marvin/tests/component/maint/*.pyc +. /marvin/common_functions.sh + +STUCKTEMPLATES=0 +STUCKVMS=0 +STUCKNETWORKS=0 +STUCKVPCS=0 +STUCKVOLS=0 +sleepduration=10 +retries=12 + +rm -f $SUMMARY_FILE +rm -rf $TESTDIR/test_*.pyc rm -f /usr/lib/python2.7/site-packages/marvin/*pyc rm -f /usr/lib/python2.7/site-packages/marvin/config/*pyc rm -f /usr/lib/python2.7/site-packages/marvin/lib/*pyc @@ -38,122 +51,33 @@ rm -f /usr/local/lib/python3.6/site-packages/marvin/*pyc rm -f /usr/local/lib/python3.6/site-packages/marvin/config/*pyc rm -f /usr/local/lib/python3.6/site-packages/marvin/lib/*pyc -cleanup() { - cloudmonkey set asyncblock false - cloudmonkey set display default - # TODO: destroy accounts, domains, templates - # Destroy vms - for vmid in $(cloudmonkey list virtualmachines listall=true filter=id | grep '^id' | awk '{print $3}'); do - cloudmonkey destroy virtualmachine id=$vmid expunge=true || true - done - # Destroy routers - for rid in $(cloudmonkey list routers listall=true filter=id | grep '^id' | awk '{print $3}'); do - cloudmonkey destroy router id=$rid || true - done - # Destroy networks - for netid in $(cloudmonkey list networks listall=true filter=id | grep '^id' | awk '{print $3}'); do - cloudmonkey delete network id=$netid || true - done - # Destroy vpcs - for vid in $(cloudmonkey list vpcs listall=true filter=id | grep '^id' | awk '{print $3}'); do - cloudmonkey delete vpc id=$vid || true - done - # Destroy alerts - for id in $(cloudmonkey list alerts listall=true keyword=auth-error filter=id | grep '^id' | awk '{print $3}'); do - cloudmonkey delete alerts ids=$id || true - done -} - -slackmsg() { - messagebody=$1 - messagecolor=$2 - slack chat send \ - --channel "#testing" \ - --color $messagecolor \ - --text "$messagebody" \ - --title "$TESTTYPE update for {{ env_name_clean }}" \ - --title-link "$jenkinslink" -} - - -runtest() { - file=$1 - rm -fr $LOGDIR/$(basename $file).xml - TRIMFILE=$(echo $(basename $file) | sed 's/.py$//g') - OLDRESULT=$(ls $LOGDIR | grep -E $TRIMFILE'_[a-zA-Z0-9]{6}$' | head -1) - if [ ! -z "${OLDRESULT// }" ]; then - echo "Found old test results, removing:" $LOGDIR/$OLDRESULT - rm -fr $LOGDIR/$OLDRESULT - fi - ${NOSETESTS} --with-xunit --xunit-file=$LOGDIR/$(basename $file).xml --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -s -a tags={{ env_zonetype | lower }}{% if marvin_test_categories is defined %}{% for category in marvin_test_categories %},{{ category }}{% endfor %}{% endif %} $file - cleanup || true -} - -launchtest() { - file=$1 - runtest $file -} - - -NUMTESTS1=`find /marvin/tests/component/test*.py | wc -l` -NUMTESTS2=`find /marvin/tests/component/maint/test*.py | wc -l` -NUMTESTS=$((NUMTESTS1+NUMTESTS2)) +cmk list accounts listall=true name="baremetal-system-account" | jq -r '.account[] .id' > .skipdeletingaccounts +cmk list accounts listall=true name="ACSuser" | jq -r '.account[] .id' >> .skipdeletingaccounts +cmk list accounts listall=true name="admin" | jq -r '.account[] .id' >> .skipdeletingaccounts +cmk list serviceofferings listall=true issystem=false name='medium instance' | jq -r '.serviceoffering[].id' > .skipdeleteofferings +cmk list serviceofferings listall=true issystem=false name='small instance' | jq -r '.serviceoffering[].id' >> .skipdeleteofferings +cmk list diskofferings listall=true issystem=false name='small' | jq -r '.diskoffering[].id' > .skipdeletediskofferings +cmk list diskofferings listall=true issystem=false name='medium' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings +cmk list diskofferings listall=true issystem=false name='large' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings +cmk list diskofferings listall=true issystem=false name='custom' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings +cmk list domains listall=true name="root" | jq -r '.domain[].id' > .skipdeletingdomains + +NUMTESTS=`find $TESTDIR -name test_*.py | wc -l` run_start_time="$(date -u +%s)" PASSES=0 counter=1 -for file in /marvin/tests/component/test_*.py; do - echo -e "\e[92m ----> Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in: {{ env_name_clean }}\e[0m" - {% if use_hipchat %}hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in:
{{ env_name_clean }} - test ($counter of $NUMTESTS)" +# FIXME: make separate list of `dangerous` tests and those that may be run in parallel +FILES=$(find $TESTDIR/ -name "test_*py") +for file in $FILES; do + TESTFILENAME="$(basename $file)" + echo -e "\e[92m ----> Starting $TESTFILENAME on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in: {{ env_name_clean }}\e[0m" + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in:
{{ env_name_clean }} - test ($counter of $NUMTESTS)" {% endif %} {% if use_slack %} slackmsg "Starting $TESTFILENAME on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }}.\nTest ($counter of $NUMTESTS) " "#808080" {% endif %} - - # nosetests --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -a tags=advanced $file - # nosetests --with-xunit --xunit-file=$LOGDIR/$(basename $file).xml --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor=vmware -a tags=advanced $file - start_time="$(date -u +%s)" - launchtest $file - - end_time="$(date -u +%s)" - elapsed="$(($end_time-$start_time))" - all_tests_elapsed="$((($end_time-$run_start_time)/1440))" - tests_left="$(($NUMTESTS-$counter))" - echo "$(basename $file): $elapsed seconds" >> $LOGDIR/tests-time.txt - - LASTUPDATEDIR=`ls $LOGDIR/*/ -td | head -n 1` - if [[ -s ${LASTUPDATEDIR}failed_plus_exceptions.txt ]]; then - echo -e "\e[92m ----> test $(basename $file) in {{ env_name_clean }} looks to have errors\e[0m" - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $(basename $file) in {{ env_name_clean }} looks to have errors. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." -{% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks to have *errors*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "warning" - {% endif %} - else - echo -e "\e[92m ----> test $(basename $file) in {{ env_name_clean }} looks OK\e[0m" - PASSES=$((PASSES+1)) - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $(basename $file) in {{ env_name_clean }} looks OK. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." -{% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks *OK*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "good" -{% endif %} - - fi - counter=$((counter+1)) -done - -for file in /marvin/tests/component/maint/test_*.py; do - echo "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in: {{ env_name_clean }}" -{% if use_hipchat %}hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in:
{{ env_name_clean }} - test ($counter of $NUMTESTS)" -{% endif %} - {% if use_slack %} slackmsg "Starting $TESTFILENAME on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }}.\nTest ($counter of $NUMTESTS) " "#808080" - {% endif %} - - # nosetests --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -a tags=advanced $file - # nosetests --with-xunit --xunit-file=$LOGDIR/$(basename $file).xml --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -a tags=advanced $file - - start_time="$(date -u +%s)" - - launchtest $file - end_time="$(date -u +%s)" elapsed="$(($end_time-$start_time))" all_tests_elapsed="$((($end_time-$run_start_time)/1440))" @@ -163,19 +87,21 @@ for file in /marvin/tests/component/maint/test_*.py; do LASTUPDATEDIR=`ls $LOGDIR/*/ -td | head -n 1` if [[ -s ${LASTUPDATEDIR}failed_plus_exceptions.txt ]]; then echo "test $(basename $file) in {{ env_name_clean }} looks to have errors" - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $(basename $file) in {{ env_name_clean }} looks to have errors. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks to have errors. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." {% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks to have *errors*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "warning" + {% if use_slack %} + slackmsg "Test $TESTFILENAME looks to have *errors*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "warning" {% endif %} - else - echo "test $(basename $file) in {{ env_name_clean }} looks OK" PASSES=$((PASSES+1)) - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $(basename $file) in {{ env_name_clean }} looks OK. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." -{% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks *OK*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "good" -{% endif %} - + echo "test $TESTFILENAME in {{ env_name_clean }} looks OK" + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks OK. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." + {% endif %} + {% if use_slack %} + slackmsg "Test $TESTFILENAME looks *OK*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "good" + {% endif %} fi counter=$((counter+1)) done @@ -191,21 +117,25 @@ for file in $LOGDIR/*.xml; do fi done -echo "Component tests completed. $GOOD look ok, $BAD have errors" -{% if use_hipchat %}hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --message "Component tests for {{ env_name_clean }} completed.
$GOOD look ok, $BAD have errors" --colour "green" --notify +# Cleanup tmp files +rm -f .skipdeletingaccounts +rm -f .skipdeletingdomains +rm -f .skipdeleteofferings +rm -f .skipdeletediskofferings + +echo "$TESTTYPE completed. $GOOD look ok, $BAD have errors" +{% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --message "$TESTTYPE for {{ env_name_clean }} completed.
$GOOD look ok, $BAD have errors" --colour "green" --notify {% endif %} -{% if use_slack %}slackmsg "$TESTTYPE completed.\n*$GOOD* look ok, *$BAD* have errors" "good" +{% if use_slack %} + slackmsg "$TESTTYPE completed.\n*$GOOD* look ok, *$BAD* have errors" "good" {% endif %} -echo "Test completed. $GOOD look ok, $BAD have errors" > /marvin/componenttest-summary.txt -echo "$GOOD look ok, $BAD have errors" > /marvin/test-summary.txt - -echo "Only failed tests results shown below:" >> /marvin/componenttest-summary.txt -echo "" >> /marvin/componenttest-summary.txt -${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/ >> /marvin/componenttest-summary.txt -cat /marvin/componenttest-summary.txt +echo "$TESTTYPE completed. $GOOD look OK, $BAD have errors" > $SUMMARY_FILE +echo "Only failed tests results shown below:" >> $SUMMARY_FILE +echo "" >> $SUMMARY_FILE +${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/ >> $SUMMARY_FILE +cat $SUMMARY_FILE echo "processing json output" - bash /marvin/process_json_results.sh - diff --git a/Ansible/roles/marvin/templates/smoketests.sh.j2 b/Ansible/roles/marvin/templates/smoketests.sh.j2 index 39c347edcca..3b7fb89ba8e 100644 --- a/Ansible/roles/marvin/templates/smoketests.sh.j2 +++ b/Ansible/roles/marvin/templates/smoketests.sh.j2 @@ -18,6 +18,7 @@ set +e # stop erroneous failures reported by Jenkins TESTTYPE="Smoke tests" LOGDIR=/marvin/MarvinLogs TESTDIR="/marvin/tests/smoke" +SUMMARY_FILE=/marvin/smoketests-summary.txt TMP_JSON_DIR="/marvin/json_results/" CLEAN_UP_LOG="/marvin/cleanup.log" mkdir -p $LOGDIR @@ -45,219 +46,20 @@ STUCKVOLS=0 sleepduration=10 retries=12 -rm -f /marvin/smoketests-summary.txt -rm -f $TESTDIR/test_*.pyc -rm -f /usr/lib/python2.7/site-packages/marvin/*pyc -rm -f /usr/lib/python2.7/site-packages/marvin/config/*pyc -rm -f /usr/lib/python2.7/site-packages/marvin/lib/*pyc -rm -f /usr/local/lib/python3.6/site-packages/marvin/*pyc -rm -f /usr/local/lib/python3.6/site-packages/marvin/config/*pyc -rm -f /usr/local/lib/python3.6/site-packages/marvin/lib/*pyc -rm -f $CLEAN_UP_LOG +. /marvin/common_functions.sh -cmk list accounts listall=true name="baremetal-system-account" | jq -r '.account[] .id' > .skipdeletingaccounts -cmk list accounts listall=true name="ACSuser" | jq -r '.account[] .id' >> .skipdeletingaccounts -cmk list accounts listall=true name="admin" | jq -r '.account[] .id' >> .skipdeletingaccounts -cmk list serviceofferings listall=true issystem=false name='medium instance' | jq -r '.serviceoffering[].id' > .skipdeleteofferings -cmk list serviceofferings listall=true issystem=false name='small instance' | jq -r '.serviceoffering[].id' >> .skipdeleteofferings -cmk list diskofferings listall=true issystem=false name='small' | jq -r '.diskoffering[].id' > .skipdeletediskofferings -cmk list diskofferings listall=true issystem=false name='medium' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings -cmk list diskofferings listall=true issystem=false name='large' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings -cmk list diskofferings listall=true issystem=false name='custom' | jq -r '.diskoffering[].id' >> .skipdeletediskofferings -cmk list domains listall=true name="root" | jq -r '.domain[].id' > .skipdeletingdomains -touch $CLEAN_UP_LOG +remove_old_files +record_existing_entities - - -cleanup() { - - # dont wait for async job - execute in parallel until told otherwise - cloudmonkey set asyncblock false - cloudmonkey set output json - # TODO: N/A - - echo "Destroy alerts" - for id in $(cmk list alerts listall=true keyword=vm | jq -r '.alert[] .id'); do - cloudmonkey delete alerts ids=$id || true - done - - echo "Destroy templates, forced, since some VMs might exist." - NUM_GCTEMPLATES=`cmk list templates templatefilter=self listall=true | jq -r '.template[].id' | wc -l` - if [[ $NUM_GCTEMPLATES -gt $STUCKTEMPLATES ]]; then - echo "$(basename $file) left behind $(($NUM_GCTEMPLATES-$STUCKTEMPLATES)) templates" >> $CLEAN_UP_LOG - cloudmonkey set asyncblock true - for templateid in $(cmk list templates templatefilter=self listall=true | jq -r '.template[].id'); do - cmk delete template id=$templateid forced=true || true - done - STUCKTEMPLATES=`cmk list templates templatefilter=self | jq -r '.template[].id' | wc -l` - fi - - echo "Destroy vms, all in parallel" - - cloudmonkey set asyncblock false - NUM_GCVMS=`cmk list virtualmachines listall=true $GCVMS | jq -r '.virtualmachine[].id' | wc -l` - if [[ $NUM_GCVMS -gt $STUCKVMS ]]; then - echo "$(basename $file) left behind $(($NUM_GCVMS-$STUCKVMS)) VMs" >> $CLEAN_UP_LOG - for vmid in $(cmk list virtualmachines listall=true $GCVMS | jq -r '.virtualmachine[].id'); do - cmk destroy virtualmachine id=$vmid expunge=true || true - done - echo "wait ${sleepduration}s to give VMs some time to be destroyed" - sleep $sleepduration - fi - - tries=$retries - while [ $tries -gt 0 ] - do - NUM_GCVMS=`cmk list virtualmachines listall=true| jq -r '.virtualmachine[].id' | wc -l` - if [[ $NUM_GCVMS -gt $STUCKVMS ]]; then - echo "Still $NUM_GCVMS left. waiting.." - sleep $sleepduration - tries=$((tries)-1) - if [ retries -eq 0 ]; then STUCKVMS=$NUM_GCVMS; fi - else - tries=0 - fi - done - - tries=$retries - echo "deleting networks" - NUM_GCNETWORKS=`cmk list networks listall=true | jq -r '.network[].id' | wc -l` - if [[ $NUM_GCNETWORKS -gt $STUCKNETWORKS ]]; then - echo "$(basename $file) left behind $(($NUM_GCNETWORKS-$STUCKNETWORKS)) Networks" >> $CLEAN_UP_LOG - while [ $tries -gt 0 ] - do - for netid in $(cmk list networks listall=true | jq -r '.network[].id'); do - cmk delete network id=$netid || true - done - echo "wait ${sleepduration}s to give Networks some time to destroy" - sleep $sleepduration - NUM_GCNETWORKS=`cmk networks listall=true | jq -r '.network[].id' | wc -l` - if [[ $NUM_GCNETWORKS -gt $STUCKVMS ]]; then - tries=$((retries)-1) - else - tries=0 - fi - done - STUCKNETWORKS=$NUM_GCNETWORKS - fi - - tries=$retries - echo "deleting VPCs" - NUM_GCVPCS=`cmk list vpcs listall=true | jq -r '.vpc[].id' | wc -l` - if [[ $NUM_GCVPC -gt $STUCKVPCS ]]; then - echo "$(basename $file) left behind $(($NUM_GCVPCS-$STUCKVPCS)) VPCs" >> $CLEAN_UP_LOG - while [ $tries -gt 0 ]; do - for vid in $(cmk list vpcs listall=true | jq -r '.vpc[].id'); do - cmk delete vpc id=$vid || true - done - sleep $sleepduration - NUM_GCVPCS=`cmk list vpcs listall=true |jq -r '.vpc[].id' | wc -l` - if [ $NUM_GCVPCS -gt $STUCKVPCS ]; then - tries=$((retries)-1) - else - tries=0 - fi - done - STUCKVPCS=$NUM_GCVPCS - fi - - # move to blocking async calls (just volume deletion, should be very fast), so later we can delete accounts and domains - cloudmonkey set asyncblock true - - # Destroy data volumes when zero attached (all VMs deleted) - NUM_GCVOLS=$(cmk list volumes type=data | jq -r '.volume[].id' | wc -l) - if [[ $NUM_GCVOLS -gt $STUCKVOLS ]]; then - echo "$(basename $file) left behind $(($NUM_GCVOLS-$STUCKVOLS)) volumes" >> $CLEAN_UP_LOG - for volumeid in $(cmk list volumes listall=true type=data | jq -r '.volume[] .id'); do - cmk delete volume id=$volumeid || true - done - sleep $sleepduration - NUM_GCVOLS=`cmk list volumes listall=true type=data | jq -r '.volume[].id' | wc -l` - STUCKVOLS=$NUM_GCVOLS - fi - - # Destroy accounts (keep some, delete all others) - cmk list accounts listall=true | jq -r '.account[] .id' > .deleteaccounts - NUM_LEFT=`cat .deleteaccounts | wc -l` - if [[ $NUM_LEFT -gt 3 ]]; then - echo "$(basename $file) left behind $(($NUM_LEFT-3)) accounts" >> $CLEAN_UP_LOG - for accountid in $(comm -13 <(sort -u .skipdeletingaccounts) <(sort -u .deleteaccounts)); do - cmk delete account id=$accountid || true - done - fi - - # Destroy domains (keep ROOT domain, delete all other) - cmk list domains listall=true | jq -r '.domain[] .id' > .deletedomains - NUM_LEFT=`cat .deletedomains | wc -l` - if [[ $NUM_LEFT -gt 1 ]]; then - echo "$(basename $file) left behind $(($NUM_LEFT-1)) domains" >> $CLEAN_UP_LOG - for domainid in $(comm -13 <(sort -u .skipdeletingdomains) <(sort -u .deletedomains)); do - cmk delete domain id=$domainid || true - done - fi - - cmk list serviceofferings listall=true issystem=false | jq -r '.serviceoffering[].id' > .deleteofferings - NUM_LEFT=`cat .deleteofferings | wc -l` - if [[ $NUM_LEFT -gt 2 ]]; then - echo "$(basename $file) left behind $(($NUM_LEFT-2)) service offerings" >> $CLEAN_UP_LOG - for offeringid in $(comm -13 <(sort -u .skipdeleteofferings) <(sort -u .deleteofferings)); do - cmk delete serviceoffering id=$offeringid || true - done - fi - - cmk list diskofferings listall=true issystem=false | jq -r '.diskoffering[].id' > .deletediskofferings - NUM_LEFT=`cat .deletediskofferings | wc -l ` - if [[ $NUM_LEFT -gt 4 ]]; then - "$(basename $file) left behind $(($NUM_LEFT-3)) disk offerings" >> $CLEAN_UP_LOG - for offeringid in $(comm -13 <(sort -u .skipdeletediskofferings) <(sort -u .deletediskofferings)); do - cmk delete diskoffering id=$offeringid || true - done - fi - -# cleanup - -rm -f .deleteaccounts -rm -f .deletedomains -rm -f .deleteofferings -rm -f .deletediskofferings -} - -runtest() { - file=$1 - rm -fr $LOGDIR/$(basename $file).xml - TRIMFILE=$(echo $(basename $file) | sed 's/.py$//g') - OLDRESULT=$(ls $LOGDIR | grep -E $TRIMFILE'_[a-zA-Z0-9]{6}$' | head -1) - if [ ! -z "${OLDRESULT// }" ]; then - echo "Found old test results, removing:" $LOGDIR/$OLDRESULT - rm -fr $LOGDIR/$OLDRESULT - fi - ${NOSETESTS} --with-xunit --xunit-file=$LOGDIR/$(basename $file).xml --with-marvin --marvin-config=/marvin/{{ env_name_clean }}-advanced-cfg --hypervisor={{ env_hv }} -s -a tags={{ env_zonetype | lower }}{% if marvin_test_categories is defined %}{% for category in marvin_test_categories %},{{ category }}{% endfor %}{% endif %} $file - cleanup || true -} - -launchtest() { - file=$1 - runtest $file - # Run tests once again on error or failure - ${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/$(basename $file).xml | grep -e Failure -e Error && cleanup && runtest $file && echo "Intermittent failure detected: $file" >> /marvin/smoketests-summary.txt -} -slackmsg() { - messagebody=$1 - messagecolor=$2 - slack chat send \ - --channel "#testing" \ - --color $messagecolor \ - --text "$messagebody" \ - --title "$TESTTYPE update for {{ env_name_clean }}" \ - --title-link "$jenkinslink" -} - -NUMTESTS=`find $TESTDIR/test_*.py | wc -l` +NUMTESTS=`find $TESTDIR -name test_*.py | wc -l` run_start_time="$(date -u +%s)" counter=1 -PASSES=0 +GOOD=0 +BAD=0 +SKIPPED=0 +SKIPPED_TESTS="" # FIXME: make separate list of `dangerous` tests and those that may be run in parallel -FILES=$(ls $TESTDIR/test_*py | grep -v test_host_maintenance | grep -v test_hostha_kvm) +FILES=$(find $TESTDIR/ -name "test_*py" | grep -v test_host_maintenance | grep -v test_hostha_kvm) if [ -f /$TESTDIR/test_host_maintenance.py ]; then FILES="$FILES $TESTDIR/test_host_maintenance.py" fi @@ -267,7 +69,8 @@ fi for file in $FILES; do TESTFILENAME="$(basename $file)" echo -e "\e[92m ----> Starting $TESTFILENAME on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in: {{ env_name_clean }}\e[0m" - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in:
{{ env_name_clean }} - test ($counter of $NUMTESTS)" + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "Starting $(basename $file) on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }} in:
{{ env_name_clean }} - test ($counter of $NUMTESTS)" {% endif %} {% if use_slack %} slackmsg "Starting $TESTFILENAME on {{ hostvars[groups['marvin_host'][0]]['ansible_ssh_host'] }}.\nTest ($counter of $NUMTESTS) " "#808080" {% endif %} @@ -279,34 +82,33 @@ for file in $FILES; do tests_left="$(($NUMTESTS-$counter))" echo "$(basename $file): $elapsed seconds" >> $LOGDIR/tests-time.txt - LASTUPDATEDIR=`ls $LOGDIR/*/ -td | head -n 1` - if [[ -s ${LASTUPDATEDIR}failed_plus_exceptions.txt ]]; then - echo "test $(basename $file) in {{ env_name_clean }} looks to have errors" - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks to have errors. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." -{% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks to have *errors*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "warning" -{% endif %} - else - PASSES=$((PASSES+1)) - echo "test $TESTFILENAME in {{ env_name_clean }} looks OK" - {% if use_hipchat %} hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks OK. $PASSES of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." -{% endif %} - {% if use_slack %} slackmsg "Test $TESTFILENAME looks *OK*.\n$PASSES of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "good" -{% endif %} - fi - counter=$((counter+1)) - -done - -GOOD=0 -BAD=0 -for file in $LOGDIR/*.xml; do - if grep --q 'errors="0" failures="0"' ${file} - then + TESTRESULTXML=${LOGDIR}/${TESTFILENAME}.xml + if [[ -s ${TESTRESULTXML} ]]; then + if grep --q 'errors="0" failures="0"' ${TESTRESULTXML}; then GOOD=$((GOOD+1)) + echo "test $TESTFILENAME in {{ env_name_clean }} looks OK" + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks OK. $GOOD of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." + {% endif %} + {% if use_slack %} + slackmsg "Test $TESTFILENAME looks *OK*.\n$GOOD of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "good" + {% endif %} else BAD=$((BAD+1)) + echo "test $(basename $file) in {{ env_name_clean }} looks to have errors" + {% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --colour "gray" --message "test $TESTFILENAME in {{ env_name_clean }} looks to have errors. $GOOD of $counter good so far.
Tests have taken $all_tests_elapsed hours so far. $tests_left tests to go." + {% endif %} + {% if use_slack %} + slackmsg "Test $TESTFILENAME looks to have *errors*.\n$GOOD of $counter good so far.\nTests have taken $all_tests_elapsed hours so far. $tests_left tests to go." "warning" + {% endif %} + fi + else + echo "test $TESTFILENAME in {{ env_name_clean }} did not run" + SKIPPED_TESTS="$SKIPPED_TESTS `echo $TESTFILENAME | sed 's/.py$//g'`" + SKIPPED=$((SKIPPED+1)) fi + counter=$((counter+1)) done # Cleanup tmp files @@ -315,17 +117,23 @@ rm -f .skipdeletingdomains rm -f .skipdeleteofferings rm -f .skipdeletediskofferings -echo "Test completed. $GOOD look ok, $BAD have errors" -{% if use_hipchat %}hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --message "$$TESTTYPE for {{ env_name_clean }} completed.
$GOOD look ok, $BAD have errors" --colour "green" --notify +echo "$TESTTYPE completed. $GOOD look ok, $BAD have errors, $SKIPPED did not run" +{% if use_hipchat %} + hipchat --action sendNotification --room "Marvin Notifications" --messageFormat "html" --message "$TESTTYPE for {{ env_name_clean }} completed.
$GOOD look ok, $BAD have errors, $SKIPPED did not run" --colour "green" --notify {% endif %} -{% if use_slack %}slackmsg "$TESTTYPE completed.\n*$GOOD* looks ok, *$BAD* have errors" "good" +{% if use_slack %} + slackmsg "$TESTTYPE completed.\n*$GOOD* look ok, *$BAD* have errors, *$SKIPPED* did not run" "good" {% endif %} -echo "Smoke tests completed. $GOOD look OK, $BAD have error(s)" >> /marvin/smoketests-summary.txt -echo "$GOOD look ok, $BAD have errors" > /marvin/test-summary.txt -echo "Only failed tests results shown below:" >> /marvin/smoketests-summary.txt -echo "" >> /marvin/smoketests-summary.txt -${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/ >> /marvin/smoketests-summary.txt -cat /marvin/smoketests-summary.txt +echo "$TESTTYPE completed. $GOOD look OK, $BAD have errors, $SKIPPED did not run" > $SUMMARY_FILE +echo "Only failed and skipped tests results shown below:" >> $SUMMARY_FILE +echo "" >> $SUMMARY_FILE +${PYTHON} /marvin/tools/xunit-reader.py $LOGDIR/ >> $SUMMARY_FILE +for test in $SKIPPED_TESTS; do + echo "all_$test | \`Skipped\` | --- | $test.py" >> $SUMMARY_FILE +done +echo "" >> $SUMMARY_FILE +cat $SUMMARY_FILE +echo "processing json output" bash /marvin/process_json_results.sh diff --git a/Ansible/roles/marvin/templates/test_data.py.j2 b/Ansible/roles/marvin/templates/test_data.py.j2 index 0a2b7ccec94..0d5e125644b 100644 --- a/Ansible/roles/marvin/templates/test_data.py.j2 +++ b/Ansible/roles/marvin/templates/test_data.py.j2 @@ -23,7 +23,7 @@ test_data = { }, "zone": "{{ env_name_clean }}", "hypervisor": "{{ env_hv }} ", - "deleteDC": "True", + "deleteDC": True, "vdomain": { "name": "domain" }, @@ -71,6 +71,15 @@ test_data = { "endip": "10.200.100.20", "forvirtualnetwork": "false" }, + "publicip6range": { + "ip6gateway": "fd17:ac56:1234:2000::1", + "ip6cidr": "fd17:ac56:1234:2000::/64", + "vlan": 301, + "forvirtualnetwork": "true" + }, + "guestip6prefix": { + "prefix": "fd17:ac56:1234:1000::/52" + }, "private_gateway": { "ipaddress": "172.16.1.2", "gateway": "172.16.1.1", @@ -85,15 +94,6 @@ test_data = { "username": "test-account", "password": "password" }, - "user": { - "email": "user@test.com", - "firstname": "User", - "lastname": "User", - "username": "User", - # Random characters are appended for unique - # username - "password": "fr3sca", - }, "account2": { "email": "test-account2@test.com", "firstname": "test2", @@ -101,6 +101,15 @@ test_data = { "username": "test-account2", "password": "password" }, + "user": { + "email": "user@test.com", + "firstname": "User", + "lastname": "User", + "username": "User", + # Random characters are appended for unique + # username + "password": "fr3sca", + }, "small": { "displayname": "testserver", "username": "root", @@ -109,7 +118,7 @@ test_data = { "hypervisor": "XenServer", "privateport": 22, "publicport": 22, - "protocol": "TCP" + "protocol": 'TCP', }, "service_offering": { "name": "Tiny Instance", @@ -154,7 +163,7 @@ test_data = { "cpuspeed": 100, "memory": 512 }, - "large": { + "large": { "name": "LargeInstance", "displaytext": "LargeInstance", "cpunumber": 1, @@ -168,7 +177,7 @@ test_data = { "cpuspeed": 100, "memory": 256, "hosttags": "ha", - "offerha": "True" + "offerha": True }, "taggedsmall": { "name": "Tagged Small Instance", @@ -180,37 +189,37 @@ test_data = { } }, "service_offering_h1": { - "name": "Tagged h1 Small Instance", - "displaytext": "Tagged h1 Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - "hosttags": "h1" + "name": "Tagged h1 Small Instance", + "displaytext": "Tagged h1 Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + "hosttags": "h1" }, "service_offering_h2": { - "name": "Tagged h2 Small Instance", - "displaytext": "Tagged h2 Small Instance", - "cpunumber": 1, - "cpuspeed": 100, - "memory": 256, - "hosttags": "h2" + "name": "Tagged h2 Small Instance", + "displaytext": "Tagged h2 Small Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 256, + "hosttags": "h2" }, "disk_offering": { "name": "Disk offering", "displaytext": "Disk offering", "disksize": 1 }, - "resized_disk_offering": { + 'resized_disk_offering': { "displaytext": "Resized", "name": "Resized", "disksize": 3 }, - "disk_offering_shared_5GB": { + 'disk_offering_shared_5GB': { "displaytext": "disk_offering_shared_5GB", "name": "disk_offering_shared_5GB", "disksize": 5 }, - "disk_offering_shared_15GB": { + 'disk_offering_shared_15GB': { "displaytext": "disk_offering_shared_5GB", "name": "disk_offering_shared_5GB", "disksize": 15 @@ -227,7 +236,7 @@ test_data = { "network2": { "name": "Test Network Shared", "displaytext": "Test Network Shared", - "vlan": 1201, + "vlan": 4000, "gateway": "172.16.15.1", "netmask": "255.255.255.0", "startip": "172.16.15.21", @@ -235,74 +244,85 @@ test_data = { "acltype": "Account" }, "l2-network_offering": { - "name": "Test L2 - Network offering", - "displaytext": "Test L2 - Network offering", - "guestiptype": "L2", - "supportedservices": "", - "traffictype": "GUEST", - "availability": "Optional" + "name": 'Test L2 - Network offering', + "displaytext": 'Test L2 - Network offering', + "guestiptype": 'L2', + "supportedservices": '', + "traffictype": 'GUEST', + "availability": 'Optional' }, "network_offering": { - "name": "Test Network offering", - "displaytext": "Test Network offering", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding", - "traffictype": "GUEST", - "availability": "Optional", + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "availability": 'Optional', "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter" - } + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, + }, + "nw_off_no_services": { + "name": 'Test Network offering without services', + "displaytext": 'Test Network offering without services', + "guestiptype": 'Isolated', + "supportedservices": '', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + }, }, "nw_off_isolated_netscaler": { - "name": "Netscaler", - "displaytext": "Netscaler", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "Netscaler", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" - } + "name": 'Netscaler', + "displaytext": 'Netscaler', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'Netscaler', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, }, "nw_off_isolated_persistent": { - "name": "Test Nw off isolated persistent", - "displaytext": "Test Nw off isolated persistent", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding", - "traffictype": "GUEST", - "ispersistent": "True", - "availability": "Optional", + "name": 'Test Nw off isolated persistent', + "displaytext": 'Test Nw off isolated persistent', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', + "tags": 'native', "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter" - } + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, }, "nw_off_isolated_persistent_lb": { - "name": "Test Nw off isolated persistent", - "displaytext": "Test Nw off isolated persistent", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Lb", - "traffictype": "GUEST", - "ispersistent": "True", - "availability": "Optional", + "name": 'Test Nw off isolated persistent', + "displaytext": 'Test Nw off isolated persistent', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Lb', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', "Lb": "VirtualRouter" } }, @@ -314,6 +334,7 @@ test_data = { "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", "traffictype": "GUEST", "availability": "Optional", + "tags": "native", "serviceProviderList": { "Dhcp": "VirtualRouter", "Dns": "VirtualRouter", @@ -335,32 +356,32 @@ test_data = { "specifyVlan": 'True' }, "network_offering_vlan": { - "name": "Test Network offering", - "displaytext": "Test Network offering", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding", - "traffictype": "GUEST", - "specifyVlan": "False", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter" - } + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', + "traffictype": 'GUEST', + "specifyVlan": 'False', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + }, }, "network_offering_without_sourcenat": { - "name": "Test Network offering", - "displaytext": "Test Network offering", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Dns,UserData", - "traffictype": "GUEST", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "UserData": "VirtualRouter" - } + "name": 'Test Network offering', + "displaytext": 'Test Network offering', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,UserData', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "UserData": 'VirtualRouter', + }, }, "isolated_network": { "name": "Isolated Network", @@ -454,6 +475,7 @@ test_data = { "specifyVlan": "False", "specifyIpRanges": "False", "traffictype": "GUEST", + "tags": "native", "serviceProviderList": { "Dhcp": "VirtualRouter", "Dns": "VirtualRouter", @@ -477,6 +499,7 @@ test_data = { "Vpn": "VirtualRouter", "Firewall": "VirtualRouter", "Lb": "VirtualRouter", + "UserData": "VirtualRouter", "StaticNat": "VirtualRouter" } }, @@ -538,15 +561,15 @@ test_data = { "displaytext": "VPC offering with multiple Lb service providers", "supportedservices": "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL", "serviceProviderList": { - "Vpn": "VpcVirtualRouter", - "Dhcp": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter", - "SourceNat": "VpcVirtualRouter", + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', "Lb": ["InternalLbVm", "VpcVirtualRouter"], - "PortForwarding": "VpcVirtualRouter", - "UserData": "VpcVirtualRouter", - "StaticNat": "VpcVirtualRouter", - "NetworkACL": "VpcVirtualRouter" + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' } }, "vpc": { @@ -555,67 +578,67 @@ test_data = { "cidr": "10.0.0.1/24" }, "vpc_network_domain": { - "name": "TestVPC", - "displaytext": "TestVPC", - "cidr": "10.0.0.1/24", - "network_domain": "TestVPC" + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.0.0.1/24', + "network_domain": "TestVPC" }, "clusters": { - "0": { + 0: { "clustername": "Xen Cluster", "clustertype": "CloudManaged", "hypervisor": "XenServer" }, - "1": { + 1: { "clustername": "KVM Cluster", "clustertype": "CloudManaged", "hypervisor": "KVM" }, - "2": { - "hypervisor": "VMware", - "clustertype": "ExternalManaged", - "username": "administrator", - "password": "fr3sca", - "url": "http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1", - "clustername": "VMWare Cluster" - } + 2: { + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "username": 'administrator', + "password": 'fr3sca', + "url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1', + "clustername": 'VMWare Cluster', + }, }, "hosts": { "xenserver": { - "hypervisor": "XenServer", - "clustertype": "CloudManaged", - "url": "http://192.168.100.211", + "hypervisor": 'XenServer', + "clustertype": 'CloudManaged', + "url": 'http://192.168.100.211', "username": "root", "password": "fr3sca" }, "kvm": { - "hypervisor": "KVM", - "clustertype": "CloudManaged", - "url": "http://192.168.100.212", + "hypervisor": 'KVM', + "clustertype": 'CloudManaged', + "url": 'http://192.168.100.212', "username": "root", "password": "fr3sca" }, "vmware": { - "hypervisor": "VMware", - "clustertype": "ExternalManaged", - "url": "http://192.168.100.203", + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "url": 'http://192.168.100.203', "username": "administrator", "password": "fr3sca" } }, "network_offering_shared": { - "name": "Test Network offering shared", - "displaytext": "Test Network offering Shared", - "guestiptype": "Shared", - "supportedservices": "Dhcp,Dns,UserData", - "traffictype": "GUEST", + "name": 'Test Network offering shared', + "displaytext": 'Test Network offering Shared', + "guestiptype": 'Shared', + "supportedservices": 'Dhcp,Dns,UserData', + "traffictype": 'GUEST', "specifyVlan": "True", "specifyIpRanges": "True", "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "UserData": "VirtualRouter" - } + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "UserData": 'VirtualRouter', + }, }, "nw_off_isolated_RVR": { "name": "Network offering-RVR services", @@ -647,24 +670,24 @@ test_data = { } }, "nw_off_persistent_RVR": { - "name": "Network offering-RVR services", - "displaytext": "Network off-RVR services", - "guestiptype": "Isolated", + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', "supportedservices": - "Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "ispersistent": "True", - "availability": "Optional", + 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', "serviceProviderList": { - "Vpn": "VirtualRouter", - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "VirtualRouter", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', }, "serviceCapabilityList": { "SourceNat": { @@ -685,6 +708,7 @@ test_data = { "availability": "Optional", "ispersistent": "False", "useVpc": "on", + "tags": 'native', "serviceProviderList": { "Dhcp": "VpcVirtualRouter", "Dns": "VpcVirtualRouter", @@ -784,34 +808,82 @@ test_data = { "cidr": "0.0.0.0/0", "protocol": "TCP" }, - "nw_off_isolated_persistent_netscaler": { - "name": "Netscaler", - "displaytext": "Netscaler", - "guestiptype": "Isolated", + "nw_off_ncc_SharedSP": { + "name": 'SharedSP', + "displaytext": 'SharedSP', + "guestiptype": 'Isolated', "supportedservices": - "Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat", - "traffictype": "GUEST", - "ispersistent": "True", - "availability": "Optional", + 'Dhcp,Dns,SourceNat,Lb,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', "serviceProviderList": { - "Dhcp": "VirtualRouter", - "Dns": "VirtualRouter", - "SourceNat": "VirtualRouter", - "PortForwarding": "VirtualRouter", - "Vpn": "VirtualRouter", - "Firewall": "VirtualRouter", - "Lb": "Netscaler", - "UserData": "VirtualRouter", - "StaticNat": "VirtualRouter" + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "Lb": 'Netscaler', + "StaticNat": 'VirtualRouter' + } + }, + "nw_off_ncc_DedicatedSP": { + "name": 'DedicatedSP', + "displaytext": 'DedicatedSP', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,Dns,SourceNat,Lb,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "Lb": 'Netscaler', + "StaticNat": 'VirtualRouter' } + }, + "NCC": { + "NCCIP": '10.102.195.215', + }, + "NSShared": { + "NSIP": '10.102.195.210', + }, + "NSDedicated": { + "NSIP": '10.102.195.212' + }, + "servicepackage_shared": { + "name": "SharedSP", + }, + "servicepackage_dedicated": { + "name": "DedicatedSP", + }, + + "nw_off_isolated_persistent_netscaler": { + "name": 'Netscaler', + "displaytext": 'Netscaler', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "ispersistent": 'True', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Vpn": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'Netscaler', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, }, "network_acl_rule": { - "protocol": "TCP", - "traffictype": "ingress", - "cidrlist": "0.0.0.0/0", - "startport": "1", - "endport": "1" + "protocol": "TCP", + "traffictype": "ingress", + "cidrlist": "0.0.0.0/0", + "startport": "1", + "endport": "1" }, "network_offering_internal_lb": { "name": "Network offering for internal lb service", @@ -852,7 +924,7 @@ test_data = { "privateport": 50, "privateendport": 55, }, - "egress_80": { + "egress_80": { "startport": 80, "endport": 80, "protocol": "TCP", @@ -863,14 +935,14 @@ test_data = { "alg": "roundrobin", "privateport": 22, "publicport": 2222, - "protocol": "TCP" + "protocol": 'TCP' }, "vpclbrule": { "name": "SSH", "alg": "roundrobin", "privateport": 22, "publicport": 22, - "protocol": "TCP" + "protocol": 'TCP' }, "internal_lbrule": { "name": "SSH", @@ -880,7 +952,7 @@ test_data = { "instanceport": 22, "scheme": "internal", "protocol": "TCP", - "cidrlist": "0.0.0.0/0" + "cidrlist": '0.0.0.0/0', }, "internal_lbrule_http": { "name": "HTTP", @@ -890,7 +962,7 @@ test_data = { "instanceport": 80, "scheme": "internal", "protocol": "TCP", - "cidrlist": "0.0.0.0/0" + "cidrlist": '0.0.0.0/0', }, "http_rule": { "privateport": 80, @@ -918,49 +990,60 @@ test_data = { "displaytext": "Test ISO", "name": "ISO", "url": "{{ marvin_images_location }}/dummy.iso", - "bootable": "False", - "ispublic": "False", + "bootable": False, + "ispublic": False, "ostype": "Other (64-bit)" }, "iso1": { "displaytext": "Test ISO 1", "name": "ISO 1", "url": "{{ marvin_images_location }}/dummy.iso", - "isextractable": "True", - "isfeatured": "True", - "ispublic": "True", + "isextractable": True, + "isfeatured": True, + "ispublic": True, "ostype": "CentOS 5.6 (64-bit)" }, "iso2": { "displaytext": "Test ISO 2", "name": "ISO 2", "url": "{{ marvin_images_location }}/dummy.iso", - "isextractable": "True", - "isfeatured": "True", - "ispublic": "True", + "isextractable": True, + "isfeatured": True, + "ispublic": True, "ostype": "CentOS 5.6 (64-bit)", - "mode": "HTTP_DOWNLOAD" + "mode": 'HTTP_DOWNLOAD', }, - "isfeatured": "True", - "ispublic": "True", - "isextractable": "True", - "bootable": "True", - "passwordenabled": "True", + "iso3": { + "displaytext": "Test ISO 3", + "name": "ISO 3", + "url": "{{ marvin_images_location }}/dummy.iso", + "isextractable": True, + "isfeatured": True, + "ispublic": True, + "ostype": "Windows Server 2012 (64-bit)", + "mode": 'HTTP_DOWNLOAD', + }, + "isfeatured": True, + "ispublic": True, + "isextractable": True, + "bootable": True, + "passwordenabled": True, + "template": { {% if env_hv == "kvm" %} "displaytext": "kvm", "name": "kvm", - "passwordenabled": "False", + "passwordenabled": False, "ostype": "CentOS 5.5 (64-bit)" {% elif env_hv == "xenserver" %} "displaytext": "xs", "name": "xs", - "passwordenabled": "False", + "passwordenabled": False, "ostype": "CentOS 5.6 (64-bit)" {% elif env_hv == "vmware" %} "displaytext": "vmware", "name": "vmware", - "passwordenabled": "False", + "passwordenabled": False, "ostype": "CentOS 5.3 (64-bit)" {% endif %} }, @@ -975,7 +1058,10 @@ test_data = { "url": "{{ openvm_images_location }}/cloudstack/macchinina/x86_64/macchinina-kvm.qcow2.bz2", "requireshvm": "True", "ispublic": "True", - "isextractable": "True" + "isextractable": "True", + "checksum": "{SHA-1}6952e58f39b470bd166ace11ffd20bf479bed936", + "md5": "88c60fd500ce7ced985cf845df0db9da", + "sha256": "bc4cc040bbab843000fab78db6cb4a33f3a06ae1ced2cf563d36b38c7fee3049" }, "xenserver": { "name": "tiny-xen", @@ -1007,10 +1093,67 @@ test_data = { "ostype": "Other Linux (64-bit)", "url": "{{ openvm_images_location }}/cloudstack/macchinina/x86_64/macchinina-vmware.ova", "requireshvm": "True", + "ispublic": "True", + "checksum": "{SHA-1}8b82224fd3c6429b6914f32d8339e650770c7526", + "md5": "b4e8bff3882b23175974e692533b4381", + "sha256": "e1dffca3c3ab545a753cb42d838a341624cf25841d1bcf3d1e45556c9fce7cf3", + "deployasis": "True" + } + }, + "test_ovf_templates": [ + { + "name": "test-ovf", + "displaytext": "test-ovf", + "format": "ova", + "hypervisor": "vmware", + "ostype": "Other Linux (64-bit)", + "url": "{{ marvin_images_location }}/machina-2dd-iso.ova", + "deployasis": "True", + "requireshvm": "True", "ispublic": "True" } + ], + "virtual_machine_vapps": { + "test-ovf": { + "name": "testvm-vapps", + "displayname": "Test VM vApps", + "properties": [ + { + "key": "used.by.admin", + "value": "marvin" + }, + { + "key": "use.type", + "value": "test" + }, + { + "key": "useful.property", + "value": "True" + } + ], + "nicnetworklist": [ + { + "network": "l2", + "nic": [15, 18] + }, + { + "network": "l2", + "nic": [16] + }, + { + "network": "l2", + "nic": [17] + } + ] + } + }, + "custom_service_offering": { + "name": "Custom Service Offering for vApps", + "displaytext": "Custom Service Offering for vApps", + "cpunumber": "", + "cpuspeed": "", + "memory": "" }, - "coreos_volume": { "diskname": "Volume_core", "urlvmware": "{{ openvm_images_location }}/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-vmware.ova", @@ -1021,7 +1164,7 @@ test_data = { "CentOS6.3template": { "displaytext": "Centos", "name": "Centos", - "passwordenabled": "False", + "passwordenabled": False, "ostype": "CentOS 6.3 (64-bit)", "url": "{{ marvin_images_location }}/centos63.ova", "format": "OVA", @@ -1030,10 +1173,10 @@ test_data = { "CentOS7template": { "displaytext": "Centos", "name": "Centos", - "passwordenabled": "False", - "isdynamicallyscalable": "True", + "passwordenabled": False, + "isdynamicallyscalable":True, "ostype": "CentOS 7", - "url": "{{ openvm_images_location }}/cloudstack/centos/vanilla/7/x86_64/CentOS-7-x86_64-vanilla-xen.vhd.bz2", + "url": "{{ openvm_images_location }}/cloudstack/centos/vanilla/7/x86_64/centos-7-xen.vhd.bz2", "format": "VHD", "ispublic": "true", "hypervisor":"Xenserver" @@ -1041,7 +1184,7 @@ test_data = { "Rhel7template": { "displaytext": "Rhel", "name": "Rhel", - "passwordenabled": "False", + "passwordenabled": False, "ostype": "Red Hat Enterprise Linux 7", "format": "OVA", "ispublic": "true" @@ -1050,16 +1193,16 @@ test_data = { "displaytext": "Public Template", "name": "Public template", "ostype": "CentOS 5.6 (64-bit)", - "isfeatured": "True", - "ispublic": "True", - "isextractable": "True", + "isfeatured": True, + "ispublic": True, + "isextractable": True, "mode": "HTTP_DOWNLOAD", "templatefilter": "self" }, "Windows 7 (64-bit)": { "displaytext": "Windows 7 (64-bit)", "name": "Windows 7 (64-bit)", - "passwordenabled": "False", + "passwordenabled": False, "url": "{{ marvin_images_location }}/windows7.vhd", "format": "VHD", "ostype": "Windows 7 (64-bit)", @@ -1067,40 +1210,40 @@ test_data = { "hypervisor": "XenServer" }, "Windows Server 2012": { - "displaytext": "Windows Server 2012", - "name": "Windows Server 2012", - "passwordenabled": "False", - "format": "OVA", - "ostype": "Windows Server 2012 (64-bit)", - "ispublic": "true", - "hypervisor": "Vmware" - }, + "displaytext": "Windows Server 2012", + "name": "Windows Server 2012", + "passwordenabled": False, + "format": "OVA", + "ostype": "Windows Server 2012 (64-bit)", + "ispublic": "true", + "hypervisor": "Vmware" + }, "privatetemplate": { "displaytext": "Public Template", "name": "Public template", "ostype": "CentOS 5.6 (64-bit)", - "isfeatured": "True", - "ispublic": "False", - "isextractable": "True", + "isfeatured": True, + "ispublic": False, + "isextractable": True, "mode": "HTTP_DOWNLOAD", "templatefilter": "self" }, "volume_from_snapshot": { - "diskname": "Volume from snapshot", + "diskname": 'Volume from snapshot', "size": "1", "zoneid": "" }, - "templatefilter": "self", + "templatefilter": 'self', "templates": { - "displaytext": "Template", - "name": "Template", + "displaytext": 'Template', + "name": 'Template', "ostype": "CentOS 5.3 (64-bit)", - "templatefilter": "self" + "templatefilter": 'self', }, "win2012template": { "displaytext": "win2012", "name": "win2012", - "passwordenabled": "False", + "passwordenabled": False, "url": "{{ marvin_images_location }}/WindowsServer2012.ova", "format": "OVA", "ostype": "Windows 8 (64-bit)" @@ -1108,7 +1251,7 @@ test_data = { "rhel60template": { "displaytext": "Rhel60", "name": "Rhel60", - "passwordenabled": "False", + "passwordenabled": False, "url": "{{ marvin_images_location }}/Rhel6-64bit.ova", "format": "OVA", "ostype": "Red Hat Enterprise Linux 6.0 (64-bit)" @@ -1121,11 +1264,11 @@ test_data = { "cidrlist": "0.0.0.0/0" }, "ingress_rule_ICMP": { - "name": "ICMP", - "protocol": "ICMP", + "name": 'ICMP', + "protocol": 'ICMP', "startport": -1, "endport": -1, - "cidrlist": "0.0.0.0/0" + "cidrlist": '0.0.0.0/0', }, "vpncustomergateway": { "ipsecpsk": "secreatKey", @@ -1154,7 +1297,7 @@ test_data = { "timeout": 10, "page": 1, "pagesize": 2, - "listall": "true", + "listall": 'true', "advanced_sg": { "zone": { "name": "", @@ -1165,6 +1308,7 @@ test_data = { }, "securitygroupenabled": "true" }, + "vlan": "10", "portableiprange_vlan": { "part": ["4090-4091", "4092-4095"], "full": "4090-4095" @@ -1173,6 +1317,10 @@ test_data = { "url": "{{ env_priprot }}://{{ env_prihost }}{{ env_pripath }}{{ env_name_clean }}/marvin_pri1", "name": "Marvin Primary Pool" }, + "nfs2": { + "url": "{{ env_priprot }}://{{ env_prihost }}{{ env_pripath }}{{ env_name_clean }}/nfs2", + "name": "Test nfs2 primary" + }, "iscsi": { {% if env_iscsi_test_host == "marvin" %} "url": "iscsi://{{ hostvars[groups["marvin_host"][0]]["ansible_ssh_host"] }}/{{ env_iscsi_test_target }}", @@ -1181,10 +1329,6 @@ test_data = { {% endif %} "name": "Test iSCSI" }, - "nfs2": { - "url": "{{ env_priprot }}://{{ env_prihost }}{{ env_pripath }}{{ env_name_clean }}/nfs2", - "name": "Test nfs2 primary" - }, "volume": {"diskname": "Test Volume", "size": 1 }, @@ -1192,24 +1336,24 @@ test_data = { "diskname": "APP Data Volume", "size": 1, # in GBs "xenserver": {"rootdiskdevice":"/dev/xvda", - "datadiskdevice_1": "/dev/xvdb", - "datadiskdevice_2": "/dev/xvdc" # Data Disk - }, + "datadiskdevice_1": '/dev/xvdb', + "datadiskdevice_2": '/dev/xvdc', # Data Disk + }, "kvm": {"rootdiskdevice": "/dev/vda", - "datadiskdevice_1": "/dev/vdb", - "datadiskdevice_2": "/dev/vdc" - }, + "datadiskdevice_1": "/dev/vdb", + "datadiskdevice_2": "/dev/vdc" + }, "vmware": {"rootdiskdevice": "/dev/hda", - "datadiskdevice_1": "/dev/hdb", - "datadiskdevice_2": "/dev/hdc" - } + "datadiskdevice_1": "/dev/hdb", + "datadiskdevice_2": "/dev/hdc" + } }, "data_write_paths": { - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data" + "mount_dir": "/mnt/tmp", + "sub_dir": "test", + "sub_lvl_dir1": "test1", + "sub_lvl_dir2": "test2", + "random_data": "random.data" }, "custom_volume": { "customdisksize": 1, @@ -1221,18 +1365,17 @@ test_data = { "schedule": 1 }, "volume_offerings": { - "0": {"diskname": "TestDiskServ"} + 0: {"diskname": "TestDiskServ"} }, - "diskdevice": ["/dev/vdc", "/dev/vdb", "/dev/hdb", "/dev/hdc", - "/dev/xvdd", "/dev/cdrom", "/dev/sr0", "/dev/cdrom1"], + "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', + '/dev/xvdd', '/dev/cdrom', '/dev/sr0', '/dev/cdrom1'], # test_vpc_vpn.py "vpn_user": { "username": "test", "password": "password" }, - # renamed to fix duplication vpc - "vpntest_vpc": { + "vpntest_vpc": { "name": "vpc_vpn", "displaytext": "vpc-vpn", "cidr": "10.1.1.0/24" @@ -1256,15 +1399,14 @@ test_data = { }, "privateport": 22, "publicport": 22, - "protocol": "TCP", + "protocol": 'TCP', "forvirtualnetwork": "true", "customdisksize": 1, "diskname": "Test Volume", "sparse": { "name": "Sparse Type Disk offering", - "displaytext": - "Sparse Type Disk offering", - "disksize": 1, + "displaytext": "Sparse Type Disk offering", + "disksize": 1, # in GB "provisioningtype": "sparse" }, "fat": { @@ -1311,7 +1453,7 @@ test_data = { "templateregister1": { "displaytext": "win8withpv", "name": "win8withpv", - "passwordenabled": "False", + "passwordenabled": False, "url": "http://pleaseupdateURL/dummy.vhd", "format": "VHD", "ostype": "Windows 8 (64-bit)", @@ -1321,7 +1463,7 @@ test_data = { "Windows 8 (64-bit)": { "displaytext": "Windows 8 (64-bit)", "name": "win8withpv", - "passwordenabled": "False", + "passwordenabled": False, "url": "http://pleaseupdateURL/dummy.vhd", "format": "VHD", "ostype": "Windows 8 (64-bit)", @@ -1331,7 +1473,7 @@ test_data = { "Windows Server 2012 (64-bit)": { "displaytext": "Windows Server 2012 (64-bit)", "name": "Windows Server 2012 (64-bit)", - "passwordenabled": "False", + "passwordenabled": False, "url": "http://pleaseupdateURL/dummy.vhd", "format": "VHD", "ostype": "Windows Server 2012 (64-bit)", @@ -1342,7 +1484,7 @@ test_data = { "Windows 7 (64-bit)": { "displaytext": "Windows 7 (64-bit)", "name": "Windows 7 (64-bit)", - "passwordenabled": "False", + "passwordenabled": False, "url": "http://pleaseupdateURL/dummy.vhd", "format": "VHD", "ostype": "Windows 7 (64-bit)", @@ -1350,15 +1492,15 @@ test_data = { "hypervisor": "XenServer" }, "RHEL 7 (64-bit)": { - "displaytext": "RHEL7 (64-bit)", - "name": "RHEL 7 Insta1", - "passwordenabled": "False", - "url": "{{ marvin_images_location }}/RHEL764bitwithtools.vhd", - "format": "VHD" , - "ostype": "RHEL 7 (64-bit)", - "ispublic": "true", - "hypervisor": "XenServer" - }, + "displaytext": "RHEL7 (64-bit)", + "name": "RHEL 7 Insta1", + "passwordenabled": False, + "url": "{{ marvin_images_location }}/RHEL764bitwithtools.vhd", + "format": "VHD" , + "ostype": "RHEL 7 (64-bit)", + "ispublic": "true", + "hypervisor": "XenServer" + }, "clusters": { "clustername": "Xen Cluster Vgpu", "clustertype": "CloudManaged", @@ -1366,9 +1508,9 @@ test_data = { }, "hosts": { "nonvgpuxenserver": { - "hypervisor": "XenServer", - "clustertype": "CloudManaged", - "url": "http://10.102.192.57", + "hypervisor": 'XenServer', + "clustertype": 'CloudManaged', + "url": 'http://10.102.192.57', "username": "root", "password": "freebsd" } @@ -1460,13 +1602,13 @@ test_data = { } }, - "diskdevice": ["/dev/vdc", "/dev/vdb", "/dev/hdb", "/dev/hdc", "/dev/xvdd", "/dev/cdrom", "/dev/sr0", - "/dev/cdrom1"], + "diskdevice": ['/dev/vdc', '/dev/vdb', '/dev/hdb', '/dev/hdc', '/dev/xvdd', '/dev/cdrom', '/dev/sr0', + '/dev/cdrom1'], # Disk device where ISO is attached to instance "mount_dir": "/mnt/tmp", "sleep": 180, "timeout": 60, - "ostype": "Windows 8 (64-bit)", + "ostype": 'Windows 8 (64-bit)', "nongpu_host_ip": "10.102.192.57" }, "acl": { @@ -1721,11 +1863,11 @@ test_data = { "name": "Test iSCSI" }, "host": { - "publicport": 22, - "username": "root", - "password": "password" + "publicport": 22, + "username": "root", + "password": "password" }, - "ldap_account": { + "ldap_account": { "email": "", "firstname": "", "lastname": "", @@ -1743,14 +1885,14 @@ test_data = { "ldapPassword": "" }, "systemVmDelay": 120, - "setUsageConfigurationThroughTestCase": "False", - "vmware_cluster" : { - "hypervisor": "VMware", - "clustertype": "ExternalManaged", - "username": "", - "password": "", - "url": "", - "clustername": "VMWare Cluster with Space in DC name", + "setUsageConfigurationThroughTestCase": False, + "vmware_cluster" : { + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "username": '', + "password": '', + "url": '', + "clustername": 'VMWare Cluster with Space in DC name', "startip": "10.223.1.2", "endip": "10.223.1.100" }, @@ -1768,7 +1910,7 @@ test_data = { }, "test_34_DeployVM_in_SecondSGNetwork": { "zone": "advsg", - "config": "D:/ACS-Repo/setup/dev//advancedsg.cfg", + "config": "D:/ACS-Repo/setup/dev//advancedsg.cfg", "template": "CentOS 5.3(64-bit) no GUI (Simulator)", "dbSvr": { "dbSvr": "10.146.0.133", @@ -1796,420 +1938,407 @@ test_data = { ] }, -"interop": - { - "VHD": - { - "displaytext": "Windows 8 (64-bit)", - "name": "win8withpvxen", - "passwordenabled": "False", - "url": "http://people.apache.org/~sanjeev/79211594-1d4a-4dee-ae6c-c5c315ded2be.vhd", - "format": "VHD" , - "ostype": "Windows 8 (64-bit)", - "ispublic": "true", - "hypervisor": "XenServer" - - }, - "OVA": - { - "displaytext": "Windows 8 (64-bit)", - "name": "win8withpvvmware", - "passwordenabled": "False", - "url": "http://pleaseupdateURL/", - "format": "OVA" , - "ostype": "Windows 8 (64-bit)", - "ispublic": "true", - "hypervisor": "VMware" - }, - "template": { - "displaytext": "windowsxdtemplate", - "name": "windowsxdtemplate", - "passwordenabled": "False", - "ostype": "Windows 8 (64-bit)" - } -}, - - - + "interop": + { + "VHD": + { + "displaytext": "Windows 8 (64-bit)", + "name": "win8withpvxen", + "passwordenabled": False, + "url": "http://people.apache.org/~sanjeev/79211594-1d4a-4dee-ae6c-c5c315ded2be.vhd", + "format": "VHD" , + "ostype": "Windows 8 (64-bit)", + "ispublic": "true", + "hypervisor": "XenServer" + }, + "OVA": + { + "displaytext": "Windows 8 (64-bit)", + "name": "win8withpvvmware", + "passwordenabled": False, + "url": "http://pleaseupdateURL/", + "format": "OVA" , + "ostype": "Windows 8 (64-bit)", + "ispublic": "true", + "hypervisor": "VMware" + }, + "template": { + "displaytext": "windowsxdtemplate", + "name": "windowsxdtemplate", + "passwordenabled": False, + "ostype": "Windows 8 (64-bit)" + } + }, "configurableData": { "browser_upload_volume":{ - "VHD": { - "diskname": "XenUploadVol", - "url": "{{ marvin_images_location }}/rajani-thin-volume.vhd", - "checksum": "09b08b6abb1b903fca7711d3ac8d6598" - }, - "OVA": { - "diskname": "VMwareUploadVol", - "url": "{{ marvin_images_location }}/CentOS5.5(64bit)-vmware-autoscale.ova", - "checksum": "da997b697feaa2f1f6e0d4785b0cece2" - }, - "QCOW2": { - "diskname": "KVMUploadVol", - "url": "{{ marvin_images_location }}/rajani-thin-volume.qcow2", - "checksum": "02de0576dd3a61ab59c03fd795fc86ac" - }, - "browser_resized_disk_offering": { - "displaytext": "Resizeddisk", - "name": "Resizeddisk", - "disksize": 3 - } -}, - "browser_upload_template": { - "VHD": { - "templatename": "XenUploadtemplate", - "displaytext": "XenUploadtemplate", - "url": "{{ marvin_images_location }}/centos56-x86_64.vhd.bz2", - "hypervisor":"XenServer", - "checksum": "09b08b6abb1b903fca7711d3ac8d6598", - "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4" - }, - "OVA": { - "templatename": "VMwareUploadtemplate", - "displaytext": "VMwareUploadtemplate", - "url": "{{ marvin_images_location }}/CentOS5.3-x86_64.ova", - "checksum": "02de0576dd3a61ab59c03fd795fc86ac", - "hypervisor":"VMware", - "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4" - }, - "QCOW2": { - "templatename": "KVMUploadtemplate", - "displaytext": "VMwareUploadtemplate", - "url": "{{ marvin_images_location }}/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2", - "checksum": "da997b697feaa2f1f6e0d4785b0cece2", - "hypervisor":"KVM", - "ostypeid":"2e02e376-cdf3-11e4-beb3-8aa6272b57ef" + "VHD": { + "diskname": "XenUploadVol", + "url": "{{ marvin_images_location }}/rajani-thin-volume.vhd", + "checksum": "09b08b6abb1b903fca7711d3ac8d6598" + }, + "OVA": { + "diskname": "VMwareUploadVol", + "url": "{{ marvin_images_location }}/CentOS5.5(64bit)-vmware-autoscale.ova", + "checksum": "da997b697feaa2f1f6e0d4785b0cece2" + }, + "QCOW2": { + "diskname": "KVMUploadVol", + "url": "{{ marvin_images_location }}/rajani-thin-volume.qcow2", + "checksum": "02de0576dd3a61ab59c03fd795fc86ac" + }, + 'browser_resized_disk_offering': { + "displaytext": "Resizeddisk", + "name": "Resizeddisk", + "disksize": 3 + } + }, + "vpc_vpn": { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + "password": "password", + }, + "host1": None, + "host2": None, + "compute_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "network_offering": { + "name": 'VPC Network offering', + "displaytext": 'VPC Network', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,Lb,PortForwarding,UserData,StaticNat,NetworkACL', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' + }, + }, + "network_offering_internal_lb": { + "name": 'VPC Network Internal Lb offering', + "displaytext": 'VPC Network internal lb', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL,Lb', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "serviceCapabilityList": { + "Lb": { + "SupportedLbIsolation": 'dedicated', + "lbSchemes": 'internal' } - }, - - - - "portableIpRange": { - "gateway": "10.223.59.1", - "netmask": "255.255.255.0", - "startip": "10.223.59.200", - "endip": "10.223.59.240", - "vlan": "1000" }, - "netscaler": { - "ipaddress": "", - "username": "", - "password": "", - "networkdevicetype": "", - "publicinterface": "", - "privateinterface": "", - "numretries": "", - "lbdevicededicated": "False", - "lbdevicecapacity": 2, - "port": 22 + "serviceProviderList": { + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter', + "Lb": 'InternalLbVm' }, - "iscsi": { + "egress_policy": "true", + }, + "vpc_offering": { + "name": 'VPC off', + "displaytext": 'VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat', + }, + "redundant_vpc_offering": { + "name": 'Redundant VPC off', + "displaytext": 'Redundant VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat', + "serviceProviderList": { + "Vpn": 'VpcVirtualRouter', + "Dhcp": 'VpcVirtualRouter', + "Dns": 'VpcVirtualRouter', + "SourceNat": 'VpcVirtualRouter', + "PortForwarding": 'VpcVirtualRouter', + "Lb": 'VpcVirtualRouter', + "UserData": 'VpcVirtualRouter', + "StaticNat": 'VpcVirtualRouter', + "NetworkACL": 'VpcVirtualRouter' + }, + "serviceCapabilityList": { + "SourceNat": { + "RedundantRouter": 'true' + } + }, + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.254.0.0/16' + }, + "vpc1": { + "name": "TestVPC", + "displaytext": "VPC1", + "cidr": '10.254.0.0/16' + }, + "vpc2": { + "name": "TestVPC", + "displaytext": "VPC2", + "cidr": '10.253.0.0/16' + }, + "network_1": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0', + "gateway": "10.254.1.1" + }, + "network_2": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0', + "gateway": "10.253.1.1" + }, + "vpn": { + "vpn_user": "root", + "vpn_pass": "Md1sdc", + "vpn_pass_fail": "abc!123", # too short + "iprange": "10.253.2.1-10.253.2.10", + "fordisplay": "true" + }, + "vpncustomergateway": { + "esppolicy": "3des-md5;modp1536", + "ikepolicy": "3des-md5;modp1536", + "ipsecpsk": "ipsecpsk" + }, + "natrule": { + "protocol": "TCP", + "cidrlist": '0.0.0.0/0', + }, + "http_rule": { + "privateport": 80, + "publicport": 80, + "startport": 80, + "endport": 80, + "cidrlist": '0.0.0.0/0', + "protocol": "TCP" + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + } + }, + "browser_upload_template": { + "VHD": { + "templatename": "XenUploadtemplate", + "displaytext": "XenUploadtemplate", + "url": "{{ marvin_images_location }}/centos56-x86_64.vhd.bz2", + "hypervisor":"XenServer", + "checksum": "09b08b6abb1b903fca7711d3ac8d6598", + "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4" + }, + "OVA": { + "templatename": "VMwareUploadtemplate", + "displaytext": "VMwareUploadtemplate", + "url": "{{ marvin_images_location }}/CentOS5.3-x86_64.ova", + "checksum": "02de0576dd3a61ab59c03fd795fc86ac", + "hypervisor":"VMware", + "ostypeid":"74affaea-c658-11e4-ad38-a6d1374244b4" + }, + "QCOW2": { + "templatename": "KVMUploadtemplate", + "displaytext": "VMwareUploadtemplate", + "url": "{{ marvin_images_location }}/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2", + "checksum": "da997b697feaa2f1f6e0d4785b0cece2", + "hypervisor":"KVM", + "ostypeid":"2e02e376-cdf3-11e4-beb3-8aa6272b57ef" + } + }, + "portableIpRange": { + "gateway": "10.223.59.1", + "netmask": "255.255.255.0", + "startip": "10.223.59.200", + "endip": "10.223.59.240", + "vlan": "4005" + }, + "netscaler": { + "ipaddress": "", + "username": "", + "password": "", + "networkdevicetype": "", + "publicinterface": "", + "privateinterface": "", + "numretries": "", + "lbdevicededicated": "False", + "lbdevicecapacity": 2, + "port": 22 + }, + "iscsi": { {% if env_iscsi_test_host == "marvin" %} "url": "iscsi://{{ hostvars[groups["marvin_host"][0]]["ansible_ssh_host"] }}/{{ env_iscsi_test_target }}", {% else %} "url": "iscsi://{{ env_iscsi_test_host }}/{{ env_iscsi_test_target }}", {% endif %} - "name": "Test iSCSI" - }, - "host": { - "publicport": 22, - "username": "root", - "password": "password" - }, - "ldap_account": { - "email": "", - "firstname": "", - "lastname": "", - "username": "", - "password": "" - }, - "link_ldap_details": { - "domain_name": "", - "accounttype": "", - "name": "", - "type": "", - "admin": "", - "linkLdapUsername": "", - "linkLdapPassword": "", - "linkLdapNestedUser": "", - "linkLdapNestedPassword": "" + "name": "Test iSCSI" + }, + "host": { + "publicport": 22, + "username": "root", + "password": "password" + }, + "ldap_account": { + "email": "", + "firstname": "", + "lastname": "", + "username": "", + "password": "" + }, + "link_ldap_details": { + "domain_name": "", + "accounttype": "", + "name": "", + "type": "", + "admin": "", + "linkLdapUsername": "", + "linkLdapPassword": "", + "linkLdapNestedUser": "", + "linkLdapNestedPassword": "" - }, - "ldap_configuration": { - "basedn": "", - "emailAttribute": "", - "userObject": "", - "usernameAttribute": "", - "hostname": "", - "port": "", - "ldapUsername": "", - "ldapPassword": "" - }, - "systemVmDelay": 120, - "setUsageConfigurationThroughTestCase": "True", - "vmware_cluster": { - "hypervisor": "VMware", - "clustertype": "ExternalManaged", - "username": "", - "password": "", - "url": "", - "clustername": "VMWare Cluster with Space in DC name" - }, - "upload_volume": { - "diskname": "UploadVol", - "format": "VHD", - "url": "{{ marvin_images_location }}/UbuntuServer-10-04-64bit.vhd.bz2", - "checksum": "" - }, - "bootableIso": - { - "displaytext": "Test Bootable ISO", - "name": "testISO", - "bootable": "True", - "ispublic": "False", - "url": "{{ marvin_images_location }}/TinyCore-current.iso", - "ostype": "Other Linux (64-bit)", - "mode": "HTTP_DOWNLOAD" - }, - "setHostConfigurationForIngressRule": "False", - "restartManagementServerThroughTestCase": "False", - "vmxnet3template": { + }, + "ldap_configuration": { + "basedn": "", + "emailAttribute": "", + "userObject": "", + "usernameAttribute": "", + "hostname": "", + "port": "", + "ldapUsername": "", + "ldapPassword": "" + }, + "systemVmDelay": 120, + "setUsageConfigurationThroughTestCase": True, + "vmware_cluster": { + "hypervisor": 'VMware', + "clustertype": 'ExternalManaged', + "username": '', + "password": '', + "url": '', + "clustername": 'VMWare Cluster with Space in DC name', + }, + "upload_volume": { + "diskname": "UploadVol", + "format": "VHD", + "url": "{{ marvin_images_location }}/UbuntuServer-10-04-64bit.vhd.bz2", + "checksum": "" + }, + "bootableIso": { + "displaytext": "Test Bootable ISO", + "name": "testISO", + "bootable": True, + "ispublic": False, + "url": "{{ marvin_images_location }}/TinyCore-current.iso", + "ostype": "Other Linux (64-bit)", + "mode": "HTTP_DOWNLOAD" + }, + "setHostConfigurationForIngressRule": False, + "restartManagementServerThroughTestCase": False, + "vmxnet3template": { "displaytext": "VMXNET3 Template", "name": "VMXNET3 template", "ostype": "CentOS 5.3 (64-bit)", - "isfeatured": "True", - "ispublic": "False", - "isextractable": "True", + "isfeatured": True, + "ispublic": False, + "isextractable": True, "mode": "HTTP_DOWNLOAD", "templatefilter": "self", "url": "{{ marvin_images_location }}/systemvm64template-2014-09-30-4.3-vmware.ova", "hypervisor": "vmware", "format": "OVA", "nicadapter": "vmxnet3", - "kvm": {"url": ""}, - "vmware": {"url": ""}, - "xenserver": {"url": ""}, - "hyperv": {"url": ""} - } - }, - # Nuage VSP SDN plugin specific test data - "nuagevsp": { - # Services supported by the Nuage VSP plugin for Isolated networks - "isolated_network_offering": { - "name": "nuage_marvin", - "displaytext": "nuage_marvin", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall,Dns", - "traffictype": "GUEST", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "StaticNat": "NuageVsp", - "SourceNat": "NuageVsp", - "Firewall": "NuageVsp", - "Connectivity": "NuageVsp", - "UserData": "VirtualRouter", - "Dns": "VirtualRouter" + "kvm": { + "url": "" }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"} - } - }, - # Services supported by the Nuage VSP plugin for VPC networks - "vpc_network_offering": { - "name": "nuage_vpc_marvin", - "displaytext": "nuage_vpc_marvin", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData,Dns", - "traffictype": "GUEST", - "availability": "Optional", - "useVpc": "on", - "ispersistent": "True", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "StaticNat": "NuageVsp", - "SourceNat": "NuageVsp", - "NetworkACL": "NuageVsp", - "Connectivity": "NuageVsp", - "UserData": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter" + "vmware": { + "url": "" }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"} - } - }, - "vpc_network_offering_internal_lb": { - "name": "nuage_vpc_marvin_internal_lb", - "displaytext": "nuage_vpc_marvin_internal_lb", - "guestiptype": "Isolated", - "supportedservices": "Dhcp,Lb,StaticNat,SourceNat,NetworkACL,Connectivity,UserData,Dns", - "traffictype": "GUEST", - "availability": "Optional", - "useVpc": "on", - "ispersistent": "True", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "Lb": "InternalLbVm", - "StaticNat": "NuageVsp", - "SourceNat": "NuageVsp", - "NetworkACL": "NuageVsp", - "Connectivity": "NuageVsp", - "UserData": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter" + "xenserver": { + "url": "" }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"}, - "Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"} - } - }, - # Services supported by the Nuage VSP plugin for VPCs - "vpc_offering": { - "name": "Nuage VSP VPC offering", - "displaytext": "Nuage VSP VPC offering", - "supportedservices": "Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData,Dns", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "StaticNat": "NuageVsp", - "SourceNat": "NuageVsp", - "NetworkACL": "NuageVsp", - "Connectivity": "NuageVsp", - "UserData": "VpcVirtualRouter", - "Dns": "VpcVirtualRouter" - } - }, - "vpc_offering_lb": { - "name": "Nuage VSP VPC offering with Lb", - "displaytext": "Nuage VSP VPC offering with Lb", - "supportedservices": "Dhcp,Lb,StaticNat,SourceNat,NetworkACL,Connectivity,UserData,Dns", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "Lb": "InternalLbVm", - "StaticNat": "NuageVsp", - "SourceNat": "NuageVsp", - "NetworkACL": "NuageVsp", - "Connectivity": "NuageVsp", - "UserData": "VpcVirtualRouter", - - "Dns": "VpcVirtualRouter" - } - }, - "shared_nuage_network_offering": { - "name": "nuage_marvin", - "displaytext": "nuage_marvin", - "guestiptype": "shared", - "supportedservices": "Dhcp,Connectivity", - "traffictype": "GUEST", - "specifyVlan": "False", - "specifyIpRanges": "True", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "Connectivity": "NuageVsp" - } - }, - "shared_nuage_public_network_offering": { - "name": "nuage_marvin", - "displaytext": "nuage_marvin", - "guestiptype": "shared", - "supportedservices": "Dhcp,Connectivity", - "traffictype": "GUEST", - "specifyVlan": "False", - "specifyIpRanges": "True", - "availability": "Optional", - "serviceProviderList": { - "Dhcp": "NuageVsp", - "Connectivity": "NuageVsp" + "hyperv": { + "url": "" }, - "serviceCapabilityList": { - "Connectivity": { - "PublicAccess": "true" - } - } - }, - # Test data for Shared Network creation - "network_all": { - "name": "SharedNetwork-All-nuage", - "displaytext": "SharedNetwork-All-nuage", - "gateway": "10.223.1.1", - "netmask": "255.255.255.0", - "startip": "10.223.1.21", - "endip": "10.223.1.100", - "acltype": "Domain" - }, - "network_domain_with_no_subdomain_access": { - "name": "SharedNetwork-Domain-nosubdomain-nuage", - "displaytext": "SharedNetwork-Domain-nosubdomain-nuage", - "gateway": "10.222.1.1", - "netmask": "255.255.255.0", - "startip": "10.222.1.2", - "endip": "10.222.1.100", - "acltype": "Domain", - "subdomainaccess": "false" - }, - "network_domain_with_subdomain_access": { - "name": "SharedNetwork-Domain-withsubdomain-nuage", - "displaytext": "SharedNetwork-Domain-withsubdomain-nuage", - "gateway": "10.221.1.1", - "netmask": "255.255.255.0", - "startip": "10.221.1.2", - "endip": "10.221.1.100", - "acltype": "Domain", - "subdomainaccess": "true" - }, - "network_account": { - "name": "SharedNetwork-Account-nuage", - "displaytext": "SharedNetwork-Account-nuage", - "gateway": "10.220.1.1", - "netmask": "255.255.255.0", - "startip": "10.220.1.2", - "endip": "10.220.1.100", - "acltype": "Account" - }, - "publiciprange1": { - "gateway": "10.223.1.1", - "netmask": "255.255.255.0", - "startip": "10.223.1.101", - "endip": "10.223.1.105", - "forvirtualnetwork": "false" - }, - "publiciprange2": { - "gateway": "10.219.1.1", - "netmask": "255.255.255.0", - "startip": "10.219.1.2", - "endip": "10.219.1.5", - "forvirtualnetwork": "false" - }, - "publiciprange3": { - "gateway": "10.223.1.1", - "netmask": "255.255.255.0", - "startip": "10.223.1.2", - "endip": "10.223.1.20", - "forvirtualnetwork": "false" + "ostype": 'CentOS 5.3 (64-bit)', + "mode": 'HTTP_DOWNLOAD' } }, "cks_kubernetes_versions": { "1.14.9": { "semanticversion": "1.14.9", - "url": "http://10.2.0.4/cks/setup-1.14.9.iso", + "url": "{{ cks_images_location }}/setup-1.14.9.iso", "mincpunumber": 2, "minmemory": 2048 }, "1.15.0": { "semanticversion": "1.15.0", - "url": "http://10.2.0.4/cks/setup-1.15.0.iso", + "url": "{{ cks_images_location }}/setup-1.15.0.iso", "mincpunumber": 2, "minmemory": 2048 }, "1.16.0": { "semanticversion": "1.16.0", - "url": "http://10.2.0.4/cks/setup-1.16.0.iso", + "url": "{{ cks_images_location }}/setup-1.16.0.iso", "mincpunumber": 2, "minmemory": 2048 }, "1.16.3": { "semanticversion": "1.16.3", - "url": "http://10.2.0.4/cks/setup-1.16.3.iso", + "url": "{{ cks_images_location }}/setup-1.16.3.iso", + "mincpunumber": 2, + "minmemory": 2048 + }, + "1.20.9": { + "semanticversion": "1.20.9", + "url": "{{ cks_images_location }}/setup-1.20.9.iso", + "mincpunumber": 2, + "minmemory": 2048 + }, + "1.21.3": { + "semanticversion": "1.21.3", + "url": "{{ cks_images_location }}/setup-1.21.3.iso", + "mincpunumber": 2, + "minmemory": 2048 + }, + "1.21.5": { + "semanticversion": "1.21.5", + "url": "{{ cks_images_location }}/setup-1.21.5.iso", + "mincpunumber": 2, + "minmemory": 2048 + }, + "1.23.3": { + "semanticversion": "1.23.3", + "url": "{{ cks_images_location }}/setup-1.23.3.iso", + "mincpunumber": 2, + "minmemory": 2048 + }, + "1.24.0": { + "semanticversion": "1.24.0", + "url": "{{ cks_images_location }}/setup-1.24.0.iso", "mincpunumber": 2, "minmemory": 2048 } @@ -2221,7 +2350,7 @@ test_data = { "format": "qcow2", "hypervisor": "kvm", "ostype": "CoreOS", - "url": "http://10.2.0.4/cks/coreos_production_cloudstack_image-kvm.qcow2.bz2", + "url": "{{ cks_images_location }}/coreos_production_cloudstack_image-kvm.qcow2.bz2", "requireshvm": "True", "ispublic": "True", "isextractable": "True" @@ -2232,7 +2361,7 @@ test_data = { "format": "vhd", "hypervisor": "xenserver", "ostype": "CoreOS", - "url": "http://10.2.0.4/cks/coreos_production_cloudstack_image-xen.vhd.bz2", + "url": "{{ cks_images_location }}/coreos_production_cloudstack_image-xen.vhd.bz2", "requireshvm": "True", "ispublic": "True", "isextractable": "True" @@ -2243,7 +2372,7 @@ test_data = { "format": "ova", "hypervisor": "vmware", "ostype": "CoreOS", - "url": "http://10.2.0.4/cks/coreos_production_cloudstack_image-vmware.ova", + "url": "{{ cks_images_location }}/coreos_production_cloudstack_image-vmware.ova", "requireshvm": "True", "ispublic": "True", "details": [{"keyboard":"us","nicAdapter":"Vmxnet3","rootDiskController":"pvscsi"}] diff --git a/Ansible/roles/mysql/tasks/centos.yml b/Ansible/roles/mysql/tasks/centos.yml index 1c85c38c7df..e89174c68b1 100644 --- a/Ansible/roles/mysql/tasks/centos.yml +++ b/Ansible/roles/mysql/tasks/centos.yml @@ -39,38 +39,45 @@ - name: Ensure mysql server is installed (centos/rhel6) yum: name=mysql-server state=present + register: mysqlinstalled tags: services when: ansible_distribution_major_version == "6" - name: Ensure mariadb server is installed (centos/rhel7) yum: name=mariadb-server state=present + register: mysqlinstalled tags: services when: ansible_distribution_major_version == "7" - name: Ridiculous fix for mysql permissions file: path=/var/lib/mysql state=directory mode=0666 + when: mysqlinstalled.changed - name: replace MySQL my.cnf using Template (centos/rhel6) action: template src=my.cnf.j2 dest=/etc/my.cnf - when: ansible_distribution_major_version == "6" + when: ansible_distribution_major_version == "6" and mysqlinstalled.changed tags: - mysqlconf - name: replace MySQL my.cnf using Template (centos/rhel7) action: template src=mariadb-my.cnf.j2 dest=/etc/my.cnf - when: ansible_distribution_major_version == "7" + when: ansible_distribution_major_version == "7" and mysqlinstalled.changed + +# - name: Nuke everything since it's starting from scratch +# shell: rm -rf /var/lib/mysql/* - name: Ensure MySQL service is started and set to start on boot (centos/rhel6) service: name=mysqld state=restarted enabled=yes tags: services - when: ansible_distribution_major_version == "6" + when: ansible_distribution_major_version == "6" and mysqlinstalled.changed - name: Ensure MySQL service is started and set to start on boot (centos/rhel7) service: name=mariadb state=restarted enabled=yes tags: services - when: ansible_distribution_major_version == "7" + when: ansible_distribution_major_version == "7" and mysqlinstalled.changed - include: ./secure_mysql.yml + when: ansible_distribution_major_version == "6" or mysqlinstalled.changed - name: Ensure Firewall Rules are in place for MySQL shell: "iptables -I INPUT -p tcp -m tcp --dport 3306 -j ACCEPT" diff --git a/Ansible/roles/mysql/tasks/centos8.yml b/Ansible/roles/mysql/tasks/centos8.yml index 6e6531bd8d5..a3183f539a9 100644 --- a/Ansible/roles/mysql/tasks/centos8.yml +++ b/Ansible/roles/mysql/tasks/centos8.yml @@ -27,12 +27,6 @@ - mysql - mysqlconf -- name: now i'm connected, get facts - setup: - tags: - - mysql - - mysqlconf - - name: Ensure selinux and mysql python bindings are installed (Ansible requirement) dnf: name: @@ -62,6 +56,7 @@ dnf: name: mysql-server state: present + register: mysqlinstalled tags: - mysql - mysqlconf @@ -70,12 +65,14 @@ template: src: my-centos8.cnf.j2 dest: /etc/my.cnf + when: mysqlinstalled.changed tags: - mysql - mysqlconf - name: Initialise MySQL shell: mysqld --initialize-insecure --user=mysql + when: mysqlinstalled.changed tags: - mysql - mysqlconf @@ -85,15 +82,20 @@ path: /var/log/mysql state: directory mode: 0750 + when: mysqlinstalled.changed tags: - mysql - mysqlconf +# - name: Nuke everything since it's starting from scratch +# shell: rm -rf /var/lib/mysql/* + - name: Ensure MySQL service is started and set to start on boot (centos/rhel7) service: name: mysqld state: restarted enabled: yes + when: mysqlinstalled.changed tags: - mysql - mysqlconf @@ -119,6 +121,7 @@ - name: set root password shell: mysql -h localhost -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'P@ssword123';FLUSH PRIVILEGES;" + when: mysqlinstalled.changed tags: - mysql - mysqlconf @@ -126,6 +129,7 @@ - name: grant permissions shell: mysql -h localhost -u root -pP@ssword123 -e "CREATE USER 'root'@'%' IDENTIFIED BY 'P@ssword123';GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;FLUSH PRIVILEGES" ignore_errors: yes + when: mysqlinstalled.changed tags: - mysql - mysqlconf diff --git a/Ansible/roles/mysql/tasks/main.yml b/Ansible/roles/mysql/tasks/main.yml index b1559e6e5d0..8607abf5437 100644 --- a/Ansible/roles/mysql/tasks/main.yml +++ b/Ansible/roles/mysql/tasks/main.yml @@ -29,7 +29,6 @@ tags: - mysql - mysqlconf - - name: wait for ssh local_action: wait_for port=22 host="{{ ansible_ssh_host }}" timeout={{ ssh_retries }} connect_timeout=5 @@ -53,6 +52,18 @@ - mysql - mysqlconf +# For some weird reason, it thinks SUSE is Ubuntu +- name: Check if SUSE + shell: cat /etc/os-release | grep -i suse + register: result + when: ansible_distribution == 'Ubuntu' + ignore_errors: yes + +- name: Set distro as SUSE + set_fact: + ansible_distribution: "SUSE" + when: ansible_distribution == 'Ubuntu' and result is succeeded + - include: ./centos.yml when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int < 8 ) tags: @@ -65,6 +76,11 @@ - mysql - mysqlconf +- include: ./suse.yml + when: ansible_distribution == 'SUSE' + tags: + - mysql + - mysqlconf - include: ./ubuntu.yml when: ansible_distribution == 'Ubuntu' diff --git a/Ansible/roles/mysql/tasks/secure_mysql.yml b/Ansible/roles/mysql/tasks/secure_mysql.yml index 23b9c9115a1..85024add13d 100644 --- a/Ansible/roles/mysql/tasks/secure_mysql.yml +++ b/Ansible/roles/mysql/tasks/secure_mysql.yml @@ -49,7 +49,7 @@ tags: - mysql - mysqlconf - + - name: delete anonymous MySQL server user for ansible_hostname mysql_user: user='' host="{{ item }}" state="absent" login_user="root" login_password="{{ mysql_root_password }}" with_items: diff --git a/Ansible/roles/mysql/tasks/suse.yml b/Ansible/roles/mysql/tasks/suse.yml new file mode 100644 index 00000000000..e91bd00fc42 --- /dev/null +++ b/Ansible/roles/mysql/tasks/suse.yml @@ -0,0 +1,113 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + + +- debug: + msg: "SUSE Specific MySQL Build" + tags: + - mysql + - mysqlconf + +- name: wait for ssh + local_action: wait_for port=22 host="{{ ansible_ssh_host }}" timeout=300 connect_timeout=5 + tags: + - mysql + - mysqlconf + +- name: now i'm connected, get facts + setup: + tags: + - mysql + - mysqlconf + +- name: Ensure selinux and mysql python bindings are installed (Ansible requirement) + zypper: + name: + - python3-PyMySQL + - python3-selinux + state: present + tags: + - mysql + - mysqlconf + +- name: Ensure selinux python bindings are installed (Ansible requirement) + zypper: + name: python3-selinux + state: present + tags: + - mysql + - mysqlconf + ignore_errors: yes + +- name: Set selinux to permissive + command: setenforce permissive + changed_when: false + tags: + - mysql + - mysqlconf + ignore_errors: yes + +- name: Ensure selinux is set permanently + selinux: policy=targeted state=permissive + tags: + - kvm + ignore_errors: yes + +- name: Ensure mysql server is installed + zypper: + name: mysql-server + state: present + register: mysqlinstalled + tags: + - mysql + - mysqlconf + +- name: replace MySQL my.cnf using Template + template: + src: mariadb-suse-my.cnf.j2 + dest: /etc/my.cnf + when: mysqlinstalled.changed + tags: + - mysql + - mysqlconf + +- name: Ensure MySQL service is started and set to start on boot + service: + name: mysql + state: restarted + enabled: yes + when: mysqlinstalled.changed + tags: + - mysql + - mysqlconf + +# - name: Nuke everything since it's starting from scratch +# shell: rm -rf /var/lib/mysql/* + +- name: set root password + shell: mysql -h localhost -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'P@ssword123';FLUSH PRIVILEGES;" + when: mysqlinstalled.changed + tags: + - mysql + - mysqlconf + +- name: grant permissions + shell: mysql -h localhost -u root -pP@ssword123 -e "CREATE USER 'root'@'%' IDENTIFIED BY 'P@ssword123';GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;FLUSH PRIVILEGES" + ignore_errors: yes + when: mysqlinstalled.changed + tags: + - mysql + - mysqlconf diff --git a/Ansible/roles/mysql/tasks/ubuntu.yml b/Ansible/roles/mysql/tasks/ubuntu.yml index 3da31b8bdd5..64719a99b06 100644 --- a/Ansible/roles/mysql/tasks/ubuntu.yml +++ b/Ansible/roles/mysql/tasks/ubuntu.yml @@ -59,6 +59,7 @@ - name: Ensure mysql server is installed (Ubuntu) apt: pkg=mysql-server state=present + register: mysqlinstalled tags: - mysql - mysqlconf @@ -89,6 +90,9 @@ - mysql - mysqlconf +# - name: Nuke everything since it's starting from scratch +# shell: rm -rf /var/lib/mysql/* + - name: Ensure MySQL service is started and set to start on boot (Ubuntu) service: name=mysql state=restarted enabled=yes tags: @@ -116,7 +120,7 @@ - name: set root password shell: mysql -h localhost -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'P@ssword123';FLUSH PRIVILEGES;" - when: ansible_distribution_major_version|int >= 20 + when: ansible_distribution_major_version|int >= 20 and mysqlinstalled.changed tags: - mysql - mysqlconf @@ -124,7 +128,7 @@ - name: grant permissions shell: mysql -h localhost -u root -pP@ssword123 -e "CREATE USER 'root'@'%' IDENTIFIED BY 'P@ssword123';GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;FLUSH PRIVILEGES" ignore_errors: yes - when: ansible_distribution_major_version|int >= 20 + when: ansible_distribution_major_version|int >= 20 and mysqlinstalled.changed tags: - mysql - mysqlconf diff --git a/Ansible/roles/mysql/templates/mariadb-suse-my.cnf.j2 b/Ansible/roles/mysql/templates/mariadb-suse-my.cnf.j2 new file mode 100644 index 00000000000..ef5e1c14633 --- /dev/null +++ b/Ansible/roles/mysql/templates/mariadb-suse-my.cnf.j2 @@ -0,0 +1,68 @@ + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +[client] +socket=/var/lib/mysql/mysql.sock + +[mysqld] +{% if inventory_hostname in groups["mysql_hosts"] %} +server-id={{ hostvars[inventory_hostname]['serverid'] }} +{% endif %} +datadir=/var/lib/mysql +socket=/var/lib/mysql/mysql.sock +user=mysql +skip_name_resolve + +max_connections={{ mysql_max_connections }} + +innodb_buffer_pool_size={{ mysql_innodb_buffer_pool_size }} +innodb_file_per_table=1 +innodb_log_buffer_size=16MB +innodb_flush_log_at_trx_commit=2 +innodb_rollback_on_timeout=1 +innodb_lock_wait_timeout=600 + +table_cache=512 +thread_cache=16 +query_cache_size=32M +max_allowed_packet=16M + +log_error=error.log +log_warnings=2 + +slow_query_log_file=slow.log +slow_query_log=0 +log_queries_not_using_indexes=1 +long_query_time=0.5 +min_examined_row_limit=100 +sort_buffer_size=2M +tmp_table_size=32M + +max_heap_table_size=64M + +log-bin=mysql-bin +binlog_cache_size=1M +max_binlog_size=128M + +sync_binlog=1 +expire_logs_days=5 +binlog-format=ROW + +# Disabling symbolic-links is recommended to prevent assorted security risks +symbolic-links=0 + +[mysqld_safe] +log-error=/var/log/mariadb/mariadb.log +pid-file=/var/run/mariadb/mariadb.pid diff --git a/Ansible/roles/mysql/templates/my-centos8.cnf.j2 b/Ansible/roles/mysql/templates/my-centos8.cnf.j2 index a1df947f241..4dd954365a8 100644 --- a/Ansible/roles/mysql/templates/my-centos8.cnf.j2 +++ b/Ansible/roles/mysql/templates/my-centos8.cnf.j2 @@ -22,6 +22,8 @@ datadir=/var/lib/mysql max_connections={{ mysql_max_connections }} skip_name_resolve +default_authentication_plugin=mysql_native_password + innodb_buffer_pool_size={{ mysql_innodb_buffer_pool_size }} innodb_file_per_table=1 innodb_log_buffer_size=16MB @@ -36,13 +38,13 @@ log_error=/var/log/mysql/error.log slow_query_log_file=slow.log slow_query_log=0 log_queries_not_using_indexes=1 -long_query_time=0.5 +long_query_time=0.5 min_examined_row_limit=100 sort_buffer_size=2M tmp_table_size=32M -max_heap_table_size=64M - +max_heap_table_size=64M + log-bin=mysql-bin binlog_cache_size=1M max_binlog_size=128M diff --git a/Ansible/roles/timezone/tasks/centos7.yml b/Ansible/roles/timezone/tasks/centos7.yml index 63022aa9c74..0a7718155c8 100644 --- a/Ansible/roles/timezone/tasks/centos7.yml +++ b/Ansible/roles/timezone/tasks/centos7.yml @@ -2,3 +2,14 @@ - name: "set Timezone to {{ env_timezone }}" command: "timedatectl set-timezone {{ env_timezone }}" + +- name: Install chrony + yum: + name: chrony + state: present + +- name: Start chrony CentOS + service: + name: chronyd + state: started + enabled: yes diff --git a/Ansible/roles/timezone/tasks/centos8.yml b/Ansible/roles/timezone/tasks/centos8.yml new file mode 100644 index 00000000000..7d8d4dd1320 --- /dev/null +++ b/Ansible/roles/timezone/tasks/centos8.yml @@ -0,0 +1,15 @@ +--- + +- name: "set Timezone to {{ env_timezone }}" + command: "timedatectl set-timezone {{ env_timezone }}" + +- name: Install chrony + dnf: + name: chrony + state: present + +- name: Start chrony CentOS + service: + name: chronyd + state: started + enabled: yes diff --git a/Ansible/roles/timezone/tasks/main.yml b/Ansible/roles/timezone/tasks/main.yml index 91d60944644..872040993ba 100644 --- a/Ansible/roles/timezone/tasks/main.yml +++ b/Ansible/roles/timezone/tasks/main.yml @@ -12,11 +12,37 @@ - name: Now I'm connected, get facts os_facts: +# For some weird reason, it thinks SUSE is Ubuntu +- name: Check if SUSE + shell: cat /etc/os-release | grep -i suse + register: result + when: ansible_distribution == 'Ubuntu' + ignore_errors: yes + +- name: Set distro as SUSE + set_fact: + ansible_distribution: "SUSE" + when: ansible_distribution == 'Ubuntu' and result is succeeded + - include: ./centos6.yml when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version == "6" ) - include: ./centos7.yml - when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int >= 7 ) + when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int == 7 ) + +- include: ./centos8.yml + when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( ansible_distribution_major_version|int == 8 ) - include: ./ubuntu.yml when: ansible_distribution == 'Ubuntu' + +- include: ./suse.yml + when: ansible_distribution == 'SUSE' + +- name: Get timestamp from the system + shell: "date" + register: tstamp + +- name: Display system date + debug: + msg: "tstamp" diff --git a/Ansible/roles/timezone/tasks/suse.yml b/Ansible/roles/timezone/tasks/suse.yml new file mode 100644 index 00000000000..db1df8189c4 --- /dev/null +++ b/Ansible/roles/timezone/tasks/suse.yml @@ -0,0 +1,30 @@ +--- + +#Copyright 2016-2021 ShapeBlue +# +#Licensed under the Apache License, Version 2.0 (the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. + +- name: "set Timezone to {{ env_timezone }}" + command: "timedatectl set-timezone {{ env_timezone }}" + +- name: Install chrony + zypper: + name: chrony + state: present + update_cache: yes + +- name: Start chrony SUSE + service: + name: chronyd + state: started + enabled: yes diff --git a/Ansible/roles/timezone/tasks/ubuntu.yml b/Ansible/roles/timezone/tasks/ubuntu.yml index bad98f6fead..e2eb221fe7e 100644 --- a/Ansible/roles/timezone/tasks/ubuntu.yml +++ b/Ansible/roles/timezone/tasks/ubuntu.yml @@ -6,3 +6,15 @@ - name: set new timezone file: src="/usr/share/zoneinfo/{{ env_timezone }}" dest=/etc/localtime state=link + +- name: Install chrony + apt: + pkg: chrony + state: latest + update_cache: yes + +- name: Start chrony + systemd: + name: chrony + state: started + enabled: yes diff --git a/Ansible/roles/vsphere/tasks/configure_vcenter.yml b/Ansible/roles/vsphere/tasks/configure_vcenter.yml index 9b831c0be02..6b0aba1694f 100644 --- a/Ansible/roles/vsphere/tasks/configure_vcenter.yml +++ b/Ansible/roles/vsphere/tasks/configure_vcenter.yml @@ -24,7 +24,7 @@ shell: "curl https://{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}/sdk/vimService.wsdl --insecure" register: result until: result.stdout.find("vim25Service") != -1 - retries: 60 + retries: 600 delay: 10 delegate_to: localhost tags: diff --git a/Ansible/roles/vsphere/tasks/main.yml b/Ansible/roles/vsphere/tasks/main.yml index 11a7602ade4..5a364ea1268 100644 --- a/Ansible/roles/vsphere/tasks/main.yml +++ b/Ansible/roles/vsphere/tasks/main.yml @@ -36,12 +36,12 @@ ignore_errors: true when: not esxi_use_dvswitch -- name: Set MTU on vSwitch 0 to 4500 - raw: esxcfg-vswitch -m 4500 vSwitch0 +- name: Set MTU on vSwitch 0 to 1500 + raw: esxcfg-vswitch -m 1500 vSwitch0 ignore_errors: true -- name: Set MTU on vmk0 to 4500 - raw: esxcli network ip interface set -m 4500 -i vmk0 +- name: Set MTU on vmk0 to 1500 + raw: esxcli network ip interface set -m 1500 -i vmk0 ignore_errors: true - name: Enable software iSCSI diff --git a/Ansible/tasks/buildvms.yml b/Ansible/tasks/buildvms.yml index d29babbba77..bfa72e330a2 100644 --- a/Ansible/tasks/buildvms.yml +++ b/Ansible/tasks/buildvms.yml @@ -26,22 +26,25 @@ #################################################################### +- name: create mavin cfg file + template: src=advanced-cfg.j2 dest="group_vars/{{ env_name_clean }}-advanced-cfg" + - name: determine number of db hosts set_fact: num_db_hosts="{{ groups['mysql_hosts'] | length }}" # Add SSH keys to Cloudstack for this project # TODO Add unquieness -- name: Remove previous SSH key from Project if it exists - local_action: - module: cs_sshkeypair - api_timeout: 120 - name: "{{ env_name_clean }}" - project: "{{ build_project }}" - state: absent +# - name: Remove previous SSH key from Project if it exists +# local_action: +# module: cs_sshkeypair +# api_timeout: 120 +# name: "{{ env_name_clean }}" +# project: "{{ build_project }}" +# state: absent - name: remove old keys from {{ def_env_ssh_key_path | dirname }}/ if they exist - local_action: + local_action: module: file path: "{{ item }}" state: absent @@ -57,20 +60,28 @@ state: directory mode: 0777 -- name: Generate SSH keys - shell: "ssh-keygen -t rsa -b 4096 -N '' -f {{ def_env_ssh_key_path }}-{{ env_name_clean }}" +- name: Copy SSH Key to current directory + shell: cp {{ def_env_ssh_key_path }}-{{ env_name_clean }}* ./ -- name: Add new public SSH Key to the project - local_action: - module: cs_sshkeypair - name: "{{ env_name_clean }}" - project: "{{ build_project }}" - state: present - api_timeout: 120 - public_key: "{{ lookup('file', '{{ def_env_ssh_key_path }}-{{ env_name_clean }}.pub') }}" +- name: Copy SSH Key to current directory + copy: + src: "{{ item }}" + dest: "id_rsa_trillian-{{ env_name_clean }}" + with_items: + - "{{ def_env_ssh_key_path }}-{{ env_name_clean }}" + - "{{ def_env_ssh_key_path }}-{{ env_name_clean }}.pub" + +# - name: Add new public SSH Key to the project +# local_action: +# module: cs_sshkeypair +# name: "{{ env_name_clean }}" +# project: "{{ build_project }}" +# state: present +# api_timeout: 120 +# public_key: "{{ lookup('file', '{{ def_env_ssh_key_path }}-{{ env_name_clean }}.pub') }}" - name: remove old keys from {{ def_env_ssh_key_path | dirname }}/ if they exist - local_action: + local_action: module: file path: "{{ item }}" state: absent @@ -90,7 +101,7 @@ template: "{{ mgmtsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -104,7 +115,7 @@ with_items: - "{{ groups['primary_cs_manager'] }}" register: mgmtsrv1_retval - when: not additional_zone + when: not additional_zone - name: Update inventory file with first management server IP addresses replace: @@ -113,7 +124,7 @@ replace='{{ item.default_ip }}' backup=no with_items: "{{mgmtsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone - name: Update in memory inventory with first management server IP addresses add_host: @@ -121,7 +132,7 @@ groups="primary_cs_manager" ansible_ssh_host={{ item.default_ip }} with_items: "{{mgmtsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone - name: Update inventory file with mgmt host instance names replace: @@ -130,7 +141,7 @@ replace='{{ item.instance_name }}' backup=no with_items: "{{mgmtsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone - name: Update in memory inventory with Mgmt host instance names add_host: @@ -138,7 +149,7 @@ groups="primary_cs_manager" instance_name={{ item.instance_name }} with_items: "{{mgmtsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone #################################################################### @@ -152,7 +163,7 @@ template: "{{ mgmtsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -208,7 +219,7 @@ template: "{{ dbsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -222,7 +233,7 @@ with_items: - "{{ groups['mysql_master_host'] }}" register: dbsrv1_retval - when: not additional_zone + when: not additional_zone - name: Update inventory file with first DB server IP addresses replace: @@ -231,7 +242,7 @@ replace='{{ item.default_ip }}' backup=no with_items: "{{dbsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone - name: Update in memory inventory with first DB server IP addresses add_host: @@ -239,7 +250,7 @@ groups="mysql_master_host" ansible_ssh_host={{ item.default_ip }} with_items: "{{dbsrv1_retval.results}}" - when: not additional_zone + when: not additional_zone #################################################################### # Additional DB servers @@ -252,7 +263,7 @@ template: "{{ dbsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -266,7 +277,7 @@ with_items: - "{{ groups['mysql_slave_hosts'] }}" register: dbsrvs_retval - when: not additional_zone + when: not additional_zone - name: Update inventory file with additional DB server IP addresseses replace: @@ -275,7 +286,7 @@ replace='{{ item.default_ip }}' backup=no with_items: "{{dbsrvs_retval.results}}" - when: not additional_zone + when: not additional_zone - name: Update in memory inventory with additional DB server IP addresses add_host: @@ -283,7 +294,7 @@ groups="mysql_slave_hosts" ansible_ssh_host={{ item.default_ip }} with_items: "{{dbsrvs_retval.results}}" - when: not additional_zone + when: not additional_zone #################################################################### # KVM hosts @@ -296,7 +307,7 @@ template: "{{ kvm_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -617,7 +628,7 @@ template: "{{ marvin_server_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: diff --git a/Ansible/tasks/buildvms_custom_allocator.yml b/Ansible/tasks/buildvms_custom_allocator.yml index 10e1958728d..98821008b11 100644 --- a/Ansible/tasks/buildvms_custom_allocator.yml +++ b/Ansible/tasks/buildvms_custom_allocator.yml @@ -30,7 +30,7 @@ set_fact: num_db_hosts="{{ groups['mysql_hosts'] | length }}" - name: get specified cluster id from name (if set) - shell: cs listClusters | jq -r --arg JQVAR "{{ env_specific_hv_cluster }}" '.cluster[]| select(.name| endswith($JQVAR))| .id' + shell: cmk listClusters | jq -r --arg JQVAR "{{ env_specific_hv_cluster }}" '.cluster[]| select(.name| endswith($JQVAR))| .id' register: found_cluster_id when: use_external_hv_hosts|bool == false and env_specific_hv_cluster != "na" delegate_to: localhost @@ -42,6 +42,14 @@ # Add SSH keys to Cloudstack for this project # TODO Add unquieness +# - name: "Fix: Create affinity group for VMware" +# local_action: +# module: cs_affinitygroup +# api_timeout: 120 +# name: "{{ env_name_clean }}-ag" +# project: "{{ build_project }}" +# affinty_type: host affinity + - name: Remove previous SSH key from Project if it exists local_action: module: cs_sshkeypair @@ -70,6 +78,9 @@ - name: Generate SSH keys shell: "ssh-keygen -t rsa -b 4096 -N '' -f {{ def_env_ssh_key_path }}-{{ env_name_clean }}" +- name: Copy SSH Key to current directory + shell: cp {{ def_env_ssh_key_path }}-{{ env_name_clean }}* ./ + - name: Add new public SSH Key to the project local_action: module: cs_sshkeypair @@ -99,6 +110,13 @@ debug: msg: "Is addtional pod- {{ additional_pod|bool }}. Is addtional zone- {{ additional_zone|bool }}." +- name: find least used cluster & host + custom_allocator: + algorithm: least_host_least_cluster + register: alg_output + +- debug: + msg: "{{ alg_output }}" # KVM hosts # @@ -110,7 +128,7 @@ template: "{{ kvm_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -175,20 +193,17 @@ with_items: "{{kvm_retval.results}}" when: use_local_storage and (use_external_hv_hosts|bool == false) -- name: find least used cluster - custom_allocator: - algorithm: least_cluster_mem - register: alg_output - when: use_external_hv_hosts|bool == false and env_specific_hv_cluster == "na" - -- debug: - msg: "{{ alg_output }}" - - name: Start KVM hosts - shell: "cs startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" + shell: "cmk startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" with_items: - "{{kvm_retval.results}}" - when: use_external_hv_hosts|bool == false + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == false + +- name: Start KVM hosts on the same parent host + shell: "cmk startVirtualMachine id={{ item.id }} hostid={{ allocator_host_id }}" + with_items: + - "{{kvm_retval.results}}" + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == true #################################################################### @@ -266,20 +281,17 @@ with_items: "{{xs_retval.results}}" when: use_local_storage and (use_external_hv_hosts|bool == false) -- name: find least used cluster - custom_allocator: - algorithm: least_cluster_mem - register: allocator_output - when: use_external_hv_hosts|bool == false and env_specific_hv_cluster == "na" - -- debug: - msg: "{{ allocator_output }}" - - name: Start XenServer hosts - shell: "cs startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" + shell: "cmk startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" with_items: - "{{xs_retval.results}}" - when: use_external_hv_hosts|bool == false + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == false + +- name: Start XenServer hosts on the same parent host + shell: "cmk startVirtualMachine id={{ item.id }} hostid={{ allocator_host_id }}" + with_items: + - "{{xs_retval.results}}" + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == true #################################################################### # VMware ESXi hosts @@ -294,6 +306,7 @@ project: "{{ build_project }}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" + # affinity_groups: ["{{ env_name_clean }}-ag"] tags: - { key: env_name, value: "{{ env_name_clean }}" } - { key: env_uuid, value: "{{ env_uuid }}" } @@ -356,21 +369,17 @@ with_items: "{{esxi_retval.results}}" when: use_local_storage and (use_external_hv_hosts|bool == false) -- name: find least used cluster - custom_allocator: - algorithm: least_cluster_mem - register: allocator_output - when: use_external_hv_hosts|bool == false and env_specific_hv_cluster == "na" - -- debug: - msg: "{{ allocator_output }}" - - name: Start ESXi hosts - shell: "cs startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" + shell: "cmk startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" with_items: - "{{esxi_retval.results}}" - when: use_external_hv_hosts|bool == false + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == false +- name: Start ESXi hosts on the same parent host + shell: "cmk startVirtualMachine id={{ item.id }} hostid={{ allocator_host_id }}" + with_items: + - "{{esxi_retval.results}}" + when: use_external_hv_hosts|bool == false and hypervisors_on_same_host|bool == true #################################################################### # VMware VC hosts @@ -379,12 +388,13 @@ local_action: module: cs_instance name: "{{ item }}" - service_offering: "{{ vc_service_offering }}" + service_offering: "{{ vc_nested_service_offering if esxi_nested_vcenter else vc_service_offering }}" template: "{{ vc_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" + # affinity_groups: ["{{ env_name_clean }}-ag"] tags: - { key: env_name, value: "{{ env_name_clean }}" } - { key: env_uuid, value: "{{ env_uuid }}" } @@ -397,6 +407,35 @@ - "{{ groups['vc_hosts'] }}" register: vc_retval +#################################################################### +# VMware 7 vCenter Appliance deployment +# + +- name: build dummy VM to obtain its IP and MAC - to be set for vcenter + local_action: + module: cs_instance + name: "{{ esxi_vc_dummy_container }}" + service_offering: "Small Instance" + template: "macchinina" + hypervisor: "{{ management_vm_hypervisor }}" + project: "{{ build_project }}" + zone: "{{ build_zone }}" + keyboard: "{{ build_keyboard }}" + tags: + - { key: env_name, value: "{{ env_name_clean }}" } + - { key: env_uuid, value: "{{ env_uuid }}" } + - { key: env_user, value: "{{ env_user }}" } + networks: + - "{{ management_network }}" + state: started + api_timeout: 120 + when: esxi_nested_vcenter + register: dummyVM + +- name: Stop dummy VM + shell: "sleep 60 && cmk stopVirtualMachine id={{ dummyVM.id }}" + when: esxi_nested_vcenter + - name: Update inventory file with VC host IP addresses replace: dest="hosts_{{ env_name_clean }}" @@ -427,10 +466,90 @@ instance_name={{ item.instance_name }} with_items: "{{vc_retval.results}}" -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start VC Host VM + shell: "cmk startVirtualMachine id={{ item.id }} clusterid={{ allocator_cluster_id }}" + with_items: + - "{{vc_retval.results}}" + when: hypervisors_on_same_host|bool == false + +- name: Start VC Host VM on the same parent host as ESXi + shell: "cmk startVirtualMachine id={{ item.id }} hostid={{ allocator_host_id }}" + with_items: + - "{{vc_retval.results}}" + when: hypervisors_on_same_host|bool == true + +- name: wait for ssh + local_action: wait_for port=22 host="{{ item.default_ip }}" timeout={{ ssh_retries }} connect_timeout=5 with_items: - "{{vc_retval.results}}" + when: esxi_nested_vcenter + +- name: Obtain the MAC address of the dummy VM + shell: "cmk listNics virtualmachineid={{ dummyVM.id }} | grep macaddress | cut -d '\"' -f4" + when: esxi_nested_vcenter + register: dummyVMMAC + +- name: SSH into VC container and restart services + shell: "sshpass -p 'P@ssword123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@{{ vc_retval.results[0].default_ip }} '{{ item }}'" + with_items: + - "services.sh restart" + - "sleep 200" + when: esxi_nested_vcenter + +- name: SSH into VC container and replace vmx file for VC + shell: "sshpass -p 'P@ssword123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@{{ vc_retval.results[0].default_ip }} '{{ item }}'" + with_items: + - "sed -i \"/^ethernet0.address =/d\" $(find -name VC.vmx)" + - "sed -i \"/^ethernet0.addressType =/d\" $(find -name VC.vmx)" + - "echo \"ethernet0.addressType = \"static\"\" >> $(find -name VC.vmx)" + - "echo \"ethernet0.address = \"{{ dummyVMMAC.stdout }}\"\" >> $(find -name VC.vmx)" + when: esxi_nested_vcenter + +- name: SSH into VC container and power on VC VM + shell: "sshpass -p 'P@ssword123' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@{{ vc_retval.results[0].default_ip }} '{{ item }}'" + with_items: + - "vim-cmd hostsvc/autostartmanager/enable_autostart 0" + - "vim-cmd vmsvc/getallvms" + - "vim-cmd vmsvc/reload 1" + - "vim-cmd vmsvc/power.on 1" + when: esxi_nested_vcenter + register: vmsout + +- debug: msg={{ vmsout }} + +- name: Update inventory file with VC host IP addresses + replace: + dest="hosts_{{ env_name_clean }}" + regexp='{{ item.name }}-ip' + replace='{{ dummyVM.default_ip }}' + backup=no + with_items: "{{vc_retval.results}}" + when: esxi_nested_vcenter + +- name: Update in memory inventory with VC host IP addresses + add_host: + name={{ item.name }} + groups="vc_hosts" + ansible_ssh_host={{ dummyVM.default_ip }} + with_items: "{{vc_retval.results}}" + when: esxi_nested_vcenter + +- name: Update inventory file with VC host instance names + replace: + dest="hosts_{{ env_name_clean }}" + regexp='{{ item.name }}-instance_name' + replace='{{ dummyVM.instance_name }}' + backup=no + with_items: "{{vc_retval.results}}" + when: esxi_nested_vcenter + +- name: Update in memory inventory with VC Mgt host instance names + add_host: + name={{ item.name }} + groups="vc_hosts" + instance_name={{ dummyVM.instance_name }} + with_items: "{{vc_retval.results}}" + when: esxi_nested_vcenter #################################################################### @@ -450,7 +569,7 @@ template: "{{ mgmtsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -500,8 +619,8 @@ with_items: "{{mgmtsrv1_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start Management Server VM + shell: "cmk startVirtualMachine id={{ item.id }}" with_items: - "{{mgmtsrv1_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) @@ -517,7 +636,7 @@ template: "{{ mgmtsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -567,8 +686,8 @@ with_items: "{{mgmtsrvs_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start Additional Management Servers VM + shell: "cmk startVirtualMachine id={{ item.id }}" with_items: - "{{mgmtsrvs_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) @@ -585,7 +704,7 @@ template: "{{ dbsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -618,8 +737,8 @@ with_items: "{{dbsrv1_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start DB Server VM + shell: "cmk startVirtualMachine id={{ item.id }}" with_items: - "{{dbsrv1_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) @@ -636,7 +755,7 @@ template: "{{ dbsrv_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -670,8 +789,8 @@ with_items: "{{dbsrvs_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start Additional DB Servers VM + shell: "cmk startVirtualMachine id={{ item.id }}" with_items: - "{{dbsrvs_retval.results}}" when: (additional_zone|bool == False) and (additional_pod|bool == False) @@ -688,7 +807,7 @@ template: "{{ marvin_server_template }}" hypervisor: "{{ management_vm_hypervisor }}" project: "{{ build_project }}" - ssh_key: "{{env_name_clean}}" + # ssh_key: "{{env_name_clean}}" zone: "{{ build_zone }}" keyboard: "{{ build_keyboard }}" tags: @@ -734,8 +853,8 @@ instance_name={{ item.instance_name }} with_items: "{{marvin_retval.results}}" -- name: Start VM - shell: "cs startVirtualMachine id={{ item.id }}" +- name: Start Marvin VM + shell: "cmk startVirtualMachine id={{ item.id }}" with_items: - "{{marvin_retval.results}}" diff --git a/Ansible/tasks/builtintemplate_hack.yml b/Ansible/tasks/builtintemplate_hack.yml index 64173b85d92..4a73f017cfa 100644 --- a/Ansible/tasks/builtintemplate_hack.yml +++ b/Ansible/tasks/builtintemplate_hack.yml @@ -12,7 +12,7 @@ - name: copy template and properties.template files get_url: - url: "{{ repohost }}/builtin_templates/xenserver/{{ item }}" + url: "{{ custom_repo }}/builtin_templates/xenserver/{{ item }}" dest: "/acs/secondary/{{ env_name_clean }}/{{ env_name_clean }}-sec1/template/tmpl/1/5/{{ item }}" with_items: - "b418e433-4ecd-3a1d-a90e-183157a165d5.vhd" @@ -28,7 +28,7 @@ - name: copy template and properties.template files get_url: - url: "{{ repohost }}/builtin_templates/kvm/{{ item }}" + url: "{{ custom_repo }}/builtin_templates/kvm/{{ item }}" dest: "/acs/secondary/{{ env_name_clean }}/{{ env_name_clean }}-sec1/template/tmpl/1/4/{{ item }}" with_items: - "0c364cce-8288-3a92-9234-4ffde372aec7.qcow2" @@ -44,7 +44,7 @@ - name: copy template and properties.template files get_url: - url: "{{ repohost }}/builtin_templates/esxi/{{ item }}" + url: "{{ custom_repo }}/builtin_templates/esxi/{{ item }}" dest: "/acs/secondary/{{ env_name_clean }}/{{ env_name_clean }}-sec1/template/tmpl/1/7/{{ item }}" with_items: - "0654e777-1660-3d44-a937-431b53f15ed7.ova" diff --git a/Ansible/tasks/looped_vm_start.yaml b/Ansible/tasks/looped_vm_start.yaml index 2451aac1ccc..46f2e603200 100644 --- a/Ansible/tasks/looped_vm_start.yaml +++ b/Ansible/tasks/looped_vm_start.yaml @@ -3,4 +3,4 @@ - debug: msg="clusterid={{ lowestclusterid }} vmid={{ item.id }}" - name: Start VM - shell: "cs startVirtualMachine id={{ item.id }} clusterid={{ lowestclusterid }}" + shell: "cmk startVirtualMachine id={{ item.id }} clusterid={{ lowestclusterid }}" diff --git a/Ansible/tasks/removeproject.yml b/Ansible/tasks/removeproject.yml index 034ce46498d..376ba4a495a 100644 --- a/Ansible/tasks/removeproject.yml +++ b/Ansible/tasks/removeproject.yml @@ -64,15 +64,15 @@ # poll: 0 # Async removed due to results not parsing, host file not updating as result. -- name: Delete SSH key - local_action: - module: cs_sshkeypair - name: "{{ env_name_clean }}" - project: "{{ build_project }}" - state: absent - api_timeout: 120 - when: (removeproject is defined) or destroy_forced - ignore_errors: yes +# - name: Delete SSH key +# local_action: +# module: cs_sshkeypair +# name: "{{ env_name_clean }}" +# project: "{{ build_project }}" +# state: absent +# api_timeout: 120 +# when: (removeproject is defined) or destroy_forced +# ignore_errors: yes #################################################################### diff --git a/Ansible/tasks/updateproject.yml b/Ansible/tasks/updateproject.yml index cd08a5afd09..2c6577c8330 100644 --- a/Ansible/tasks/updateproject.yml +++ b/Ansible/tasks/updateproject.yml @@ -30,4 +30,5 @@ - { key: created, value: "{{ env_builddate }}" } - { key: comment, value: "{{ env_comment | regex_replace(' ', '_') }}" } - { key: updated, value: "{{lookup('pipe','date +%d/%m/%y_%H:%M')}}" } + - { key: sensitive_data, value: "{{lookup('pipe', 'echo ${SENSITIVE_DATA:-false}')}}" } ignore_errors: true diff --git a/Ansible/templates/CentOS-AppStream.repo.j2 b/Ansible/templates/CentOS-AppStream.repo.j2 index c7e5ce84b14..d5ed3167f7a 100644 --- a/Ansible/templates/CentOS-AppStream.repo.j2 +++ b/Ansible/templates/CentOS-AppStream.repo.j2 @@ -13,7 +13,7 @@ [AppStream] name=CentOS-$releasever - AppStream #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra -baseurl={{ repohost }}/centos/$releasever/AppStream/$basearch/os/ +baseurl={{ os_repo }}/centos/$releasever/AppStream/$basearch/os/ gpgcheck=0 enabled=1 diff --git a/Ansible/templates/CentOS-Base.repo.j2 b/Ansible/templates/CentOS-Base.repo.j2 index 0b8df3aeff7..204e1566d23 100644 --- a/Ansible/templates/CentOS-Base.repo.j2 +++ b/Ansible/templates/CentOS-Base.repo.j2 @@ -13,7 +13,7 @@ [base] name=CentOS-$releasever - Base #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os -baseurl={{ repohost }}/centos/$releasever/os/$basearch/ +baseurl={{ os_repo }}/centos/$releasever/os/$basearch/ gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever enabled = {{ base_repo_enabled | default(1) }} @@ -22,7 +22,7 @@ enabled = {{ base_repo_enabled | default(1) }} [updates] name=CentOS-$releasever - Updates #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates -baseurl={{ repohost }}/centos/$releasever/updates/$basearch/ +baseurl={{ os_repo }}/centos/$releasever/updates/$basearch/ gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever enabled = {{ update_repo_enabled | default(1) }} diff --git a/Ansible/templates/CentOS8-Base.repo.j2 b/Ansible/templates/CentOS8-Base.repo.j2 index f592b47c9a9..1df1629dea3 100644 --- a/Ansible/templates/CentOS8-Base.repo.j2 +++ b/Ansible/templates/CentOS8-Base.repo.j2 @@ -13,7 +13,7 @@ [base] name=CentOS-$releasever - Base #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os -baseurl={{ repohost }}/centos/$releasever/os/$basearch/ +baseurl={{ os_repo }}/centos/$releasever/os/$basearch/ gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever enabled = {{ base_repo_enabled }} diff --git a/Ansible/templates/advanced-cfg.j2 b/Ansible/templates/advanced-cfg.j2 new file mode 100644 index 00000000000..1979a29aea6 --- /dev/null +++ b/Ansible/templates/advanced-cfg.j2 @@ -0,0 +1,263 @@ +{ + "zones": [{ + "name": "{{ env_name_clean }}", + "guestcidraddress": "{{ env_zone_guestcidr }}", + "dns1": "{{ env_zone_dns1 }}", + "physical_networks": [{ + "broadcastdomainrange": "Zone", + "name": "Trillian-Guest-Public", + "traffictypes": [{ + "type": "Guest", + "providers": [{ + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "VpcVirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "InternalLbVm" + }], + "isolationmethods": "VLAN" + }, { + "type": "Public" + }], + "providers": [{ + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "VpcVirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "InternalLbVm" + }], + "isolationmethods": "VLAN" + },{ + "broadcastdomainrange": "Zone", + "name": "Trillian-Mgmt", + "traffictypes": [{ + "type": "Management" + }], + "providers": [{ + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "VpcVirtualRouter" + }, { + "broadcastdomainrange": "ZONE", + "name": "InternalLbVm" + }], + "isolationmethods": "VLAN" + }], +{% if env_hv == "vmware" %} + "vmwaredc": { + "username": "{{ vmware_vcsa_user }}", + "vcenter": "{{ hostvars[groups['vc_hosts'][0]]['ansible_ssh_host'] }}", + "password": "{{ vmware_vcsa_pass }}", + "name": "{{ vmware_datacenter_name }}" + }, +{% endif %} + "ipranges": [{ + "startip": "{{ env_pubstartip }}", + "endip": "{{ env_pubendip }}", + "netmask": "{{ env_pubmask }}", + "vlan": "{{ env_pubvlan }}", + "gateway": "{{ env_pubgw }}" + }], + "networktype": "{{ env_zonetype }}", + "pods": [{ + "endip": "{{ env_podendip }}", + "name": "{{env_zone_podname}}", + "startip": "{{ env_podstartip }}", + "netmask": "{{ env_podmask }}", + "clusters": [{ + "clustername": "{{ env_zone_clustername }}", + "hypervisor": "{{ env_hv }}", +{% if env_hv == "kvm" %} + "hosts": [ +{% for host in groups['kvm_hosts'] %} { + "username": "root", + "url": "http://{{ hostvars[host]['ansible_ssh_host'] }}", + "password": "{{ hostvars[host]['ansible_ssh_pass'] }}" + }{% if not loop.last %},{% endif %}{% endfor %} + ], + "clustertype": "CloudManaged", +{% elif env_hv == "xenserver" %} + "hosts": [ +{% for host in groups['xenserver_hosts'] %} { + "username": "root", + "url": "http://{{ hostvars[host]['ansible_ssh_host'] }}", + "password": "{{ hostvars[host]['ansible_ssh_pass'] }}" + }{% if not loop.last %},{% endif %}{% endfor %} + ], + "clustertype": "CloudManaged", +{% elif env_hv == "vmware" %} + "hosts": [ +{% for host in groups['esxi_hosts'] %} { + "username": "root", + "url": "http://{{ hostvars[host]['ansible_ssh_host'] }}", + "password": "{{ hostvars[host]['ansible_ssh_pass'] }}" + }{% if not loop.last %},{% endif %}{% endfor %} + ], + "clustertype": "CloudManaged", +{% endif %} + "primaryStorages": [ +{% for pripool in env_pripools %} { + "url": "{{ env_priprot }}://{{ env_prihost }}{{ env_pripath }}{{ env_name_clean }}/{{ pripool }}/", + "name": "{{ pripool }}"}{% if not loop.last %},{% endif %} +{% endfor %} + ] + } + + ], + "gateway": "{{ env_podgw }}" + }], + "internaldns1": "{{ env_zone_intdns1 }}", + "secondaryStorages": [{ +{% for secpool in env_secpools %} + "url": "nfs://{{ env_sechost }}{{ env_secpath }}{{ env_name_clean }}/{{ secpool }}/", + "name": "{{ secpool }}", + "provider": "NFS"}{% if not loop.last %},{% endif %} +{% endfor %} + ] + }], + "dbSvr": { +{% if num_db_hosts == "0" %} "dbSvr": "{{ hostvars[groups['primary_cs_manager'][0]]['ansible_ssh_host'] }}",{% endif %} +{% if num_db_hosts != "0" %} "dbSvr": "{{ hostvars[groups['mysql_master_host'][0]]['ansible_ssh_host'] }}",{% endif %} + + "passwd": "{{ mysql_cloud_password }}", + "db": "cloud", + "port": 3306, + "user": "cloud" + }, + "logger": { + "LogFolderPath": "/marvin/" + }, + "globalConfig": [{ + "name": "account.cleanup.interval", + "value": 60 + }, { + "name": "extract.url.cleanup.interval", + "value": 300 + }, { + "name": "network.securitygroups.work.cleanup.interval", + "value": 120 + }, { + "name": "task.cleanup.retry.interval", + "value": 600 + }, { + "name": "vm.op.cleanup.interval", + "value": 600 + }, { + "name": "vm.op.cleanup.wait", + "value": 600 + }, { + "name": "vpc.cleanup.interval", + "value": 600 + }, { + "name": "alert.wait", + "value": 300 + }, { + "name": "backup.snapshot.wait", + "value": 600 + }, { + "name": "copy.volume.wait", + "value": 600 + }, { + "name": "create.private.template.from.snapshot.wait", + "value": 600 + }, { + "name": "create.private.template.from.volume.wait", + "value": 600 + }, { + "name": "create.volume.from.snapshot.wait", + "value": 600 + }, { + "name": "migratewait", + "value": 1200 + }, { + "name": "primary.storage.download.wait", + "value": 900 + }, { + "name": "storage.pool.max.waitseconds", + "value": 900 + }, { + "name": "update.wait", + "value": 300 + }, { + "name": "vm.op.cleanup.wait", + "value": 600 + }, { + "name": "vm.tranisition.wait.interval", + "value": 300 + }, { + "name": "vmsnapshot.create.wait", + "value": 900 + }, { + "name": "xapiwait", + "value": 300 + }, { + "name": "router.alerts.check.interval", + "value": 300 + }, { + "name": "network.gc.wait", + "value": "60" + }, { + "name": "storage.cleanup.interval", + "value": "300" + }, { + "name": "vm.op.wait.interval", + "value": "5" + }, { + "name": "default.page.size", + "value": "10000" + }, { + "name": "network.gc.interval", + "value": "60" + }, { + "name": "instance.name", + "value": "QA" + }, { + "name": "workers", + "value": "10" + }, { + "name": "guest.domain.suffix", + "value": "sandbox.simulator" + }, { + "name": "expunge.delay", + "value": "60" + }, { + "name": "vm.allocation.algorithm", + "value": "random" + }, { + "name": "expunge.interval", + "value": "60" + }, { + "name": "expunge.workers", + "value": "3" + }, { + "name": "check.pod.cidrs", + "value": "true" + }, { + "name": "secstorage.allowed.internal.sites", + "value": "10.0.0.0/8" + }, { + "name": "direct.agent.load.size", + "value": "1000" + }, { + "name": "enable.dynamic.scale.vm", + "value": "true" + }], + "mgtSvr": [{ + "mgtSvrIp": "{{ hostvars[groups['primary_cs_manager'][0]]['ansible_ssh_host'] }}", + "port": 8096, + "user": "root", + "passwd": "{{ mgmtsrv_password }}", + "hypervisor": "{{ env_hv }}", + "useHttps": "False", + "certCAPath": "NA", + "certPath": "NA" + }] +} \ No newline at end of file diff --git a/Ansible/templates/configure_cks.sh.j2 b/Ansible/templates/configure_cks.sh.j2 index 8edf1fca5ad..0eb14ee8e5d 100644 --- a/Ansible/templates/configure_cks.sh.j2 +++ b/Ansible/templates/configure_cks.sh.j2 @@ -11,20 +11,6 @@ cmk create serviceoffering cpunumber={{ min_cks_service_offering.cpunumber }} cp # upload versions {% for item in cks_version %} -cmk add kubernetessupportedversion semanticversion={{ item.semantic_version }} url={{ item.url }} mincpunumber=2 minmemory=2048 +cmk add kubernetessupportedversion semanticversion={{ item.semantic_version }} url={{ item.url }} mincpunumber={{ min_cks_service_offering.cpunumber }} minmemory={{ min_cks_service_offering.memory }} {% endfor %} -# Get CoreOS UUID -COREOS_UUID=`cmk list ostypes description="CoreOS" | jq -r '.ostype[].id'` - -# upload template(s) -if [ "{{ xs_ver | lower }}" != "na" ]; then - cmk register template name=Kubernetes-CoreOS-xenserver displaytext=Kubernetes-CoreOS-xenserver url={{ env_cks_coreos_template_xenserver }} zoneids=-1 format=VHD isextractable=false passwordenabled=false isdynamicallyscalable=false ostypeid=$COREOS_UUID hypervisor=XenServer ispublic=true isfeatured=false isrouting=false -fi -if [ "{{ kvm_os | lower }}" != "na" ]; then - cmk register template cmk register template name=Kubernetes-CoreOS-kvm displaytext=Kubernetes-CoreOS-kvm url={{ env_cks_coreos_template_kvm }} zoneids=-1 format=QCOW2 isextractable=false passwordenabled=false isdynamicallyscalable=false ostypeid=$COREOS_UUID hypervisor=KVM ispublic=true isfeatured=false isrouting=false -fi -if [ "{{ vmware_ver | lower }}" != "na" ]; then - cmk register template name=Kubernetes-CoreOS-vmware displaytext=Kubernetes-CoreOS-vmware url={{ env_cks_coreos_template_vmware }} zoneids=-1 format=OVA isextractable=false passwordenabled=false isdynamicallyscalable=false ostypeid=$COREOS_UUID hypervisor=VMware ispublic=true isfeatured=false isrouting=false details[0].rootDiskController=pvscsi details[0].nicAdapter=Vmxnet3 -fi - diff --git a/Ansible/templates/epel.repo.j2 b/Ansible/templates/epel.repo.j2 index f87cfa0d99f..847ddc9bd97 100644 --- a/Ansible/templates/epel.repo.j2 +++ b/Ansible/templates/epel.repo.j2 @@ -1,6 +1,6 @@ [epel] name=Extra Packages for Enterprise Linux 6 - $basearch -baseurl={{ repohost }}/epel/$releasever/$basearch +baseurl={{ os_repo }}/epel/$releasever/$basearch #mirrorlist=http://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 diff --git a/Ansible/templates/nestedgroupvars.j2 b/Ansible/templates/nestedgroupvars.j2 index 7252121bd51..b12835d5d79 100644 --- a/Ansible/templates/nestedgroupvars.j2 +++ b/Ansible/templates/nestedgroupvars.j2 @@ -36,6 +36,7 @@ use_custom_allocator: {{ use_custom_allocator | default(def_use_custom_allocator use_firewalld: {{ use_firewalld | default( def_use_firewalld ) }} base_repo_enabled: "{{ base_repo_enabled | default( def_base_repo_enabled ) }}" update_repo_enabled: "{{ update_repo_enabled | default( def_update_repo_enabled ) }}" +hypervisors_on_same_host: "{{ hypervisors_on_same_host | default(def_hypervisors_on_same_host) }}" # Environment database settings env_db_name: "{{ env_db_name | default( def_env_db_name ) }}" @@ -307,7 +308,7 @@ kvm_elrepo_kernel_version: "{{ kvm_elrepo_kernel_version| default( def_kvm_elrep {% else %} {% set kvmjava = kvm_java_ver %} {% endif %} -kvm_java_ver: "{{ kvmjava }}" +kvm_java_ver: "{{ kvmjava }}" {% if kvm_java_path is not defined %} {% set kvm_os_name = linux_os[kvm_os].os %} {% set kvmjavapath = java_paths[kvm_os_name][kvmjava] %} @@ -343,6 +344,7 @@ esxi_template: "{{ esxi_template | default( def_vmware_templates[vmware_ver].esx vc_template: "{{ vc_template | default( def_vmware_templates[vmware_ver].vc_template ) }}" esxi_service_offering: "{{ esxi_service_offering | default( def_esxi_service_offering ) }}" vc_service_offering: "{{ vc_service_offering | default( def_vc_service_offering ) }}" +vc_nested_service_offering: "{{ vc_nested_service_offering | default ( def_vc_nested_service_offering ) }}" esxi_use_dvswitch: {{ esxi_use_dvswitch | default( def_esxi_use_dvswitch ) }} esxi_use_mgmt_dvswitch: {{ esxi_use_mgmt_dvswitch | default( def_esxi_use_mgmt_dvswitch ) }} esxi_mgmt_network_label: "{{ esxi_mgmt_network_label | default( def_esxi_mgmt_network_label ) }}" @@ -352,6 +354,12 @@ esxi_mgmt_dvs_network_label: "{{ esxi_mgmt_dvs_network_label | default( def_esxi esxi_guest_dvs_network_label: "{{ esxi_guest_dvs_network_label | default( def_esxi_guest_dvs_network_label ) }}" esxi_public_dvs_network_label: "{{ esxi_public_dvs_network_label | default( def_esxi_public_dvs_network_label ) }}" +# VMware 7 support - deploy vCenter appliance on a dedicated host +{% if vmware_ver == "70u1" or vmware_ver == "70u2" or vmware_ver == "70u3" %}esxi_nested_vcenter: yes +esxi_vc_dummy_container: "{{ env_name_clean }}-dummy" +{% else %}esxi_nested_vcenter: no +{% endif %} + # VMware datacentre configuration {% if vmware_ver == "50u1" %}vmware_vcsa_user: "{{ vmware_vcsa_user | default( def_vmware_vcsa_50_51_user ) }}" {% elif vmware_ver == "51u1" %}vmware_vcsa_user: "{{ vmware_vcsa_user | default( def_vmware_vcsa_50_51_user ) }}" @@ -373,6 +381,7 @@ marvin_tests_source: "{{ marvin_tests_source | default ( def_marvin_tests_source marvin_tests_github_source: "{{ marvin_tests_github_source | default ( def_marvin_tests_github_source ) }}" marvin_images_location: "{{ marvin_images_location | default ( def_marvin_images_location ) }}" openvm_images_location: "{{ openvm_images_location | default ( def_openvm_images_location ) }}" +cks_images_location: "{{ cks_images_location | default ( def_cks_images_location ) }}" {% if run_component_tests is not defined %}{% set run_component_tests = no %}{% endif %}run_component_tests: {{ run_component_tests }} {% if run_smoke_tests is not defined %}{% set run_smoke_tests = no %}{% endif %}run_smoke_tests: {{ run_smoke_tests }} {% if baseurl_marvin is not defined %} @@ -429,9 +438,4 @@ slack_color: "{{ slack_color | default( def_slack_color ) }}" slack_webhook: "{{ slack_webhook | default( def_slack_webhook ) }}" # cks - -env_cks_coreos_template_hyperv: "{{ env_cks_coreos_template_hyperv | default( def_cks_coreos_template_hyperv ) }}" -env_cks_coreos_template_kvm: "{{ env_cks_coreos_template_kvm | default( def_cks_coreos_template_kvm )}}" -env_cks_coreos_template_vmware: "{{ env_cks_coreos_template_vmware | default( def_cks_coreos_template_vmware )}}" -env_cks_coreos_template_xenserver: "{{ env_cks_coreos_template_xenserver | default( def_cks_coreos_template_xenserver )}}" env_enable_cks: "{{ env_enable_cks | default( def_enable_cks ) }}" diff --git a/Ansible/templates/sources.list.j2 b/Ansible/templates/sources.list.j2 index 651c2d623a0..3436fe7a124 100644 --- a/Ansible/templates/sources.list.j2 +++ b/Ansible/templates/sources.list.j2 @@ -1,22 +1,22 @@ {% if ansible_distribution_release == "trusty" %} -deb [arch=amd64] {{ repohost }}/ubuntu/ trusty main restricted universe -deb-src {{ repohost }}/ubuntu/ trusty main restricted +deb [arch=amd64] {{ os_repo }}/ubuntu/ trusty main restricted universe +deb-src {{ os_repo }}/ubuntu/ trusty main restricted -deb [arch=amd64] {{ repohost }}/ubuntu/ trusty-updates main restricted universe -deb-src {{ repohost }}/ubuntu/ trusty-updates main restricted +deb [arch=amd64] {{ os_repo }}/ubuntu/ trusty-updates main restricted universe +deb-src {{ os_repo }}/ubuntu/ trusty-updates main restricted -deb [arch=amd64] {{ repohost }}/ubuntu trusty-security main restricted universe -deb-src {{ repohost }}/ubuntu trusty-security main restricted +deb [arch=amd64] {{ os_repo }}/ubuntu trusty-security main restricted universe +deb-src {{ os_repo }}/ubuntu trusty-security main restricted {% endif %} {% if ansible_distribution_release == "xenial" %} -# deb {{ repohost }}/ubuntu/ xenial main restricted -# deb {{ repohost }}/ubuntu/ xenial-updates main restricted -# deb {{ repohost }}/ubuntu/ xenial universe -# deb {{ repohost }}/ubuntu/ xenial-updates universe +# deb {{ os_repo }}/ubuntu/ xenial main restricted +# deb {{ os_repo }}/ubuntu/ xenial-updates main restricted +# deb {{ os_repo }}/ubuntu/ xenial universe +# deb {{ os_repo }}/ubuntu/ xenial-updates universe -# +# # deb cdrom:[Ubuntu-Server 16.04.1 LTS _Xenial Xerus_ - Release amd64 (20160719)]/ xenial main restricted @@ -40,9 +40,9 @@ deb http://gb.archive.ubuntu.com/ubuntu/ xenial universe deb http://gb.archive.ubuntu.com/ubuntu/ xenial-updates universe # deb-src http://gb.archive.ubuntu.com/ubuntu/ xenial-updates universe -## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu -## team, and may not be under a free licence. Please satisfy yourself as to -## your rights to use the software. Also, please note that software in +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team, and may not be under a free licence. Please satisfy yourself as to +## your rights to use the software. Also, please note that software in ## multiverse WILL NOT receive any review or updates from the Ubuntu ## security team. deb http://gb.archive.ubuntu.com/ubuntu/ xenial multiverse diff --git a/Ansible/test-test b/Ansible/test-test new file mode 100644 index 00000000000..c71c2eb3751 --- /dev/null +++ b/Ansible/test-test @@ -0,0 +1,49 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAgEAvIV3ETlqOYOG7VLXCWep6W4BxxZwBnKrJs5ZLJz+fsnY/Rr7mktR +p7MXaVr4yBFVM5JNT09/TjKGRhhfJk51fhRezKFodj+LhcB3ZPF128/3HTtl3W7MLEh6xh ++HVxAOs7Qzx8NoSik6s7w6svbDmU/j5RRndTsx7HgsrNd5kx2iS5sQOEVmENCU2zH4N6jB +U3eTvzUORVnR5SEbHfbEiBx1m8pJaE20L2nnu9nxeAdO7mamBhjnM1CwrFSax/LQgoSkzj +B7Xk4FbF/WYpvfoXLgTmY9RrPcM7CGe0jasuzuJy9d5sE5Op0mtGsnO/PQQIZ2p/ZKf2Fr +gRLkSFLX7Gcdgb2KIUKOWIHm+aB4j9oPwP+3wNBCQrLjE5QVCT8lYJIYRI2TsyBR3DFGPs +5Zrh8/56T4Jty8yIIFy3eHDpW+AxRERyxJTsKAN3tpP/jKOofWCctLiEWHsgW3ahLxjMPC +J68HYpekjvo1auZwSaA+dacGnBiqx7KhmnTl/TlyfGusEzCMhwlA2hmzuIdoCJe7oMMqIZ +EK6QjkxEANS0Km+AcIprFVI2UnB/lyCT2KsMJ6++h0wOCcsaPWLHAe0Arq/Y4a3mtxFq/A +KHLuDTxAmerRqcGXoRURT0S0I/IvsSzKuzdmQBTwzBYLiNHo3PfFiH+9o6rhq/J8ZuKdfw +0AAAdQ2Kuwt9irsLcAAAAHc3NoLXJzYQAAAgEAvIV3ETlqOYOG7VLXCWep6W4BxxZwBnKr +Js5ZLJz+fsnY/Rr7mktRp7MXaVr4yBFVM5JNT09/TjKGRhhfJk51fhRezKFodj+LhcB3ZP +F128/3HTtl3W7MLEh6xh+HVxAOs7Qzx8NoSik6s7w6svbDmU/j5RRndTsx7HgsrNd5kx2i +S5sQOEVmENCU2zH4N6jBU3eTvzUORVnR5SEbHfbEiBx1m8pJaE20L2nnu9nxeAdO7mamBh +jnM1CwrFSax/LQgoSkzjB7Xk4FbF/WYpvfoXLgTmY9RrPcM7CGe0jasuzuJy9d5sE5Op0m +tGsnO/PQQIZ2p/ZKf2FrgRLkSFLX7Gcdgb2KIUKOWIHm+aB4j9oPwP+3wNBCQrLjE5QVCT +8lYJIYRI2TsyBR3DFGPs5Zrh8/56T4Jty8yIIFy3eHDpW+AxRERyxJTsKAN3tpP/jKOofW +CctLiEWHsgW3ahLxjMPCJ68HYpekjvo1auZwSaA+dacGnBiqx7KhmnTl/TlyfGusEzCMhw +lA2hmzuIdoCJe7oMMqIZEK6QjkxEANS0Km+AcIprFVI2UnB/lyCT2KsMJ6++h0wOCcsaPW +LHAe0Arq/Y4a3mtxFq/AKHLuDTxAmerRqcGXoRURT0S0I/IvsSzKuzdmQBTwzBYLiNHo3P +fFiH+9o6rhq/J8ZuKdfw0AAAADAQABAAACAQCmPguBZOAHV7TkEukNohxzfE6VAXRIO1Yy +IkUA0nCZ3eU7TVAR/9lByOwcO9ymkKJRl/IUvkXE70j5BwThAs8ZH115ldxIakDe8ZpXqZ +YFAJ8pZ/esDMh/RGr/y03NuJs+XOpMfkS5ISJi3NnmdzSFPa35lMSm3Exp+o9q25iZ4sf7 +ZAIpnQkkSsr5gFcive29bPUc5+xtu4ccRtVi1vj4DiCoAPo6wErkhL+VJ9uHvOod0OcW+V +7oIX+qd/EF4Vl9vvqV2KrxvluJ9flXe5z5AhRLDl16u6Cy9Dei/9vbbJOWem6TzlBpH6vB +7bvrYlWCkRCRjN6k9YOXjtE/9c3xZlAGCBBiC8UfbJ/W4pmVlAiSbENFkA0L72kjrQIXnV +stDs7Wn2+NS5HLRXrkjFj1m+p85Z0GSFApCgaiOzWLV4UixKb+ggEWQeNrC8vElri63fqz +utJeISGn/MaZd2MOEZaytBnlWAz/gvlsSiyJSRkeiryXkTjwSIOhPePD1FYY3zpL+NRwNd +6Ld6Il2cuN5NwF+IV+DSRlKsR63D5g+7TFl1VVLwYOZrxdnS1p81rDiNdJHPIMaGssYDzn +keLdHVE+JtCZY5XwIZvmVHDElKUOfAYvvk9pnINLHCY4hGVJxAeAdGzmXfVTFkCI6+BiR5 +ll3EnNEScW1TFlbbsAAQAAAQEAiXz/XRMPvYJvUaC/xPqKMiH/3IfX+6D2Tu/GvDbFYgfu +sEhgUgWRc0jwtQ0x3X3FldCM1aygig2MvKkgU98Mxjm1lqBWHvgvUbz57+UB/Y2ES04Zqs +3OY82xocNaN21fcisfn4UeW5tDu56kwBhNn8tMkmCUMDpvE3sbm4H6pxejNl3UrPCmGk51 +aR03HPTeME5bs0CJpk3ov9DMEdUd6KTbokFPTC/K0pLNE6/dWrBoqlblEt4cwtdEAMDuOs +DL2A1+3kGzHIsCS6/qSH6THC+ajStgDgCZpt3gKegrmT+5zyH3b3lAcMOwUssJn9sXue0B +uUmok8kGxdwusCtHQAAAAQEA40RbjKP28oKQA1Dag6t7clUlR7k2v3DMttDn2JyFMOlAA2 +1OOVOxWgkdPbnPPC67/9iR37Q6XBCFcNAMz9SAJB5Zzhui1DQftV6ckLKw4HZ/zo2rjCGw +7cOG1E3mCgGoOIM+UiE79Zu7uU+8tM5kDUoXSK2zUxo821yTFOHVbPh2e6gSTDA+7cP+PB +fPTqv1h+XH5nL4ko4EkkBTfuoPFnBPtIZPB0LnF2lg1p7YbYSvQR2cqfLnMQlejBFLsl8o +0Zk4wVZ9IMolKqRC3vBKZGBITsIdF3DBkdaanwrw1N1uFofudSetVal/p8omo0Iw9dLsv1 +Fb9rrtYGZEsX8jDQAAAQEA1FsUOU4F5mkli6FyKsLoi1D549cyGGPn95VYteq+4lnZNoSG +JE+vTD3fKs287yqnU/4L/UiMg7Eld6Ak/X4UezCOA8bSFuEyKBd7zmdj2a+BWzUDAZ33Jn +A2Ze/LxOmhsDin06El2D5NXvq7yTHUCwGEe21z6KU7K85XUK9hquir1P+PRAorJQ+0pP2W +dS9IbcV/eAW7Mn/Jv1E1W6y+m9DgHjnaVpoLD1LBGtaPo8bTa7MxXpBovF7I+mLAo+drHw +g4gLlSmhsXQ0inj6LuMdg5pizW6+1t6xMfq63td+i8zwatl4TDLW/nvLKlLMRga226suMq +qtksBJVy2fDMAQAAABdwZWFybEBwZWFybC1YUFMtMTUtNzU5MAEC +-----END OPENSSH PRIVATE KEY----- diff --git a/Ansible/test-test.pub b/Ansible/test-test.pub new file mode 100644 index 00000000000..a64513cce77 --- /dev/null +++ b/Ansible/test-test.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8hXcROWo5g4btUtcJZ6npbgHHFnAGcqsmzlksnP5+ydj9GvuaS1GnsxdpWvjIEVUzkk1PT39OMoZGGF8mTnV+FF7MoWh2P4uFwHdk8XXbz/cdO2XdbswsSHrGH4dXEA6ztDPHw2hKKTqzvDqy9sOZT+PlFGd1OzHseCys13mTHaJLmxA4RWYQ0JTbMfg3qMFTd5O/NQ5FWdHlIRsd9sSIHHWbykloTbQvaee72fF4B07uZqYGGOczULCsVJrH8tCChKTOMHteTgVsX9Zim9+hcuBOZj1Gs9wzsIZ7SNqy7O4nL13mwTk6nSa0ayc789BAhnan9kp/YWuBEuRIUtfsZx2BvYohQo5Ygeb5oHiP2g/A/7fA0EJCsuMTlBUJPyVgkhhEjZOzIFHcMUY+zlmuHz/npPgm3LzIggXLd4cOlb4DFERHLElOwoA3e2k/+Mo6h9YJy0uIRYeyBbdqEvGMw8Inrwdil6SO+jVq5nBJoD51pwacGKrHsqGadOX9OXJ8a6wTMIyHCUDaGbO4h2gIl7ugwyohkQrpCOTEQA1LQqb4BwimsVUjZScH+XIJPYqwwnr76HTA4Jyxo9YscB7QCur9jhrea3EWr8Aocu4NPECZ6tGpwZehFRFPRLQj8i+xLMq7N2ZAFPDMFguI0ejc98WIf72jquGr8nxm4p1/DQ== pearl@pearl-XPS-15-7590