├── .gitignore ├── bms-ansible-nsx ├── templates │ ├── create_domain.json.j2 │ ├── suse_dhcp_network_template.j2 │ ├── create_trustvif_group.json.j2 │ ├── create_untrustvif_group.json.j2 │ ├── nsx-baremetal.j2 │ ├── check_rhel7_dependency.j2 │ ├── check_rhel8_dependency.j2 │ ├── check_suse_dependency.j2 │ ├── check_ubuntu16_dependency.j2 │ ├── check_ubuntu18_dependency.j2 │ ├── create_lsp.json.j2 │ ├── create_communication_map.json.j2 │ ├── bms_migrate.j2 │ ├── quarantine_rule_properties.json.j2 │ ├── bms_static_init.j2 │ ├── bms_dhcp_init.j2 │ ├── revert.j2 │ ├── bms_migrate_restore.j2 │ ├── bms_migrate_init.j2 │ └── migrate.j2 ├── docs │ └── Application_Interface_Installation_Guide.pdf ├── vif │ ├── win_detach_vif.yml │ ├── attach_vif.yml │ ├── int_br_name.yml │ ├── win_attach_vif.yml │ └── create_vif.yml ├── route │ ├── route.j2 │ └── route.yml ├── lsp │ ├── vif_id.yml │ ├── get_lsp_id.yml │ ├── check_legacy_lsp.yml │ ├── win_get_lsp_id.yml │ ├── create_lsp.yml │ ├── save_lsp_id.yml │ ├── win_save_lsp_id.yml │ ├── delete_lsp.yml │ ├── collect_untrust_vifid.yml │ ├── collect_trust_vifid.yml │ ├── create_lsp_by_name.yml │ └── create_lsp_by_id.yml ├── validation │ ├── vif_id_check.yml │ ├── migration_input_check.yml │ ├── static_input_check.yml │ ├── vlan_0_ls_check.yml │ ├── vlan_0_ls_check_by_id.yml │ └── vlan_0_ls_check_by_name.yml ├── policy │ ├── delete_rule.yml │ ├── create_domain.yml │ ├── create_trustvif_group.yml │ ├── create_untrustvif_group.yml │ └── create_communication_map.yml ├── config │ ├── app_intf_name.yml │ ├── tn_uuid.yml │ ├── fqdn.yml │ ├── win_tn_uuid.yml │ ├── config.yml │ ├── bms_config.yml │ └── bms_update.yml ├── debug.yml ├── windows │ ├── get_install_dir.yml │ └── ConfigureWinRMService.ps1 ├── auth │ ├── manager_thumbprint_validate.yml │ └── thumbprint_validate.py ├── win_restore.yml ├── system │ ├── del_service_bootup.yml │ ├── add_service_bootup.yml │ └── get_os_type.yml ├── restore.yml ├── win_dhcp_config.yml ├── win_migrate.yml ├── win_hosts ├── win_static_config.yml ├── debug │ └── debug.sh ├── quarantine_policy.yml ├── unprepare.yml ├── quarantine.yml ├── manual │ ├── static_dhcp_manual_restore.sh │ └── migration_manual_restore.sh ├── restore │ ├── bms_migrate_restore.yml │ └── bms_static_dhcp_restore.yml ├── static_config.yml ├── unquarantine.yml ├── dhcp_config.yml ├── hosts ├── migrate.yml ├── README.md └── prepare.yml ├── NOTICE.txt ├── LICENSE.txt ├── README.md └── CONTRIBUTING.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/create_domain.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "resource_type": "Domain", 3 | "description": "BareMetal Domain1", 4 | "display_name": "BareMetal domain1" 5 | } 6 | -------------------------------------------------------------------------------- /bms-ansible-nsx/docs/Application_Interface_Installation_Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware-archive/bare-metal-server-integration-with-nsxt/HEAD/bms-ansible-nsx/docs/Application_Interface_Installation_Guide.pdf -------------------------------------------------------------------------------- /bms-ansible-nsx/vif/win_detach_vif.yml: -------------------------------------------------------------------------------- 1 | - name: detach app vif 2 | win_shell: "& '{{ InstallDir.value }}\\win-bms-install.ps1' -operation vif-uninstall" 3 | become: yes 4 | become_user: Administrator 5 | async: 60 6 | poll: 10 7 | register: result 8 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/suse_dhcp_network_template.j2: -------------------------------------------------------------------------------- 1 | BOOTPROTO='dhcp' 2 | BROADCAST='' 3 | ETHTOOL_OPTIONS='' 4 | IPADDR='' 5 | MTU='' 6 | NAME='' 7 | NETMASK='' 8 | NETWORK='' 9 | REMOTE_IPADDR='' 10 | STARTMODE='auto' 11 | DHCLIENT_SET_DEFAULT_ROUTE='yes' 12 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/create_trustvif_group.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "resource_type": "Group", 3 | "display_name": "TrustVifGroup", 4 | "expression": [ 5 | { 6 | "resource_type": "VIFExpression", 7 | "external_ids": vif_trust_list 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/create_untrustvif_group.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "resource_type": "Group", 3 | "display_name": "UnTrustVifGroup", 4 | "expression": [ 5 | { 6 | "resource_type": "VIFExpression", 7 | "external_ids": vif_untrust_list 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/route/route.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | {% if routing_table is defined %} 7 | 8 | {% for item in routing_table %} 9 | echo {{ item }} 10 | route add {{ item }} dev {{ app_intf_name }} 11 | {% endfor %} 12 | 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/vif_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: generate vif id 6 | set_fact: 7 | vif_id: "{{ ansible_date_time.iso8601_micro | to_uuid }}" 8 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/vif_id_check.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check vif id 6 | fail: msg="vif id is not defined" 7 | when: vif_id is not defined 8 | -------------------------------------------------------------------------------- /bms-ansible-nsx/policy/delete_rule.yml: -------------------------------------------------------------------------------- 1 | - name: delte_rule 2 | uri: 3 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/firewall/sections/{{ section_id }}/rules/{{ item }} 4 | method: DELETE 5 | user: "{{ hostvars.nsxmanager.username }}" 6 | password: "{{ hostvars.nsxmanager.password }}" 7 | return_content: yes 8 | force_basic_auth: yes 9 | validate_certs: no 10 | status_code: 200 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/app_intf_name.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get App interface name 6 | set_fact: 7 | app_intf_name: "nsx-eth" 8 | when: app_intf_name is not defined 9 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/migration_input_check.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Validate migrate interface 6 | fail: msg="migrate interface is not defined" 7 | when: migrate_intf is not defined 8 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/nsx-baremetal.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | bms_node 4 | {{ underlay_mode | bool | lower }} 5 | 6 | 7 | {{ hostvars.nsxmanager.ip }} 8 | 1234 9 | 6 10 | true 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/get_lsp_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Get LP Id 6 | command: cat /etc/vmware/nsx-bm/lpid 7 | register: lspid 8 | - name: check logical port id 9 | fail: msg="lspid not found" 10 | when: lspid.stdout == "" 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/route/route.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: config routing table 6 | command: route add {{ item }} dev {{ app_intf_name }} 7 | with_items: "{{ routing_table }}" 8 | when: routing_table is defined 9 | ignore_errors: yes 10 | -------------------------------------------------------------------------------- /bms-ansible-nsx/debug.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: TransportNodes 7 | tasks: 8 | - name: Show Logical Switch Port ID 9 | shell: cat /etc/vmware/nsx-bm/lpid 10 | register: lpid 11 | - debug: msg="Logical Switch Port ID {{lpid.stdout}}" 12 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/static_input_check.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check static ip 6 | fail: msg="static ip is not defined" 7 | when: static_ip is not defined 8 | - name: check netmask 9 | fail: msg="netmask is not defined" 10 | when: netmask is not defined 11 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Ansible Playbook for Bare Metal Server Integration with NSX-T 2 | 3 | Copyright (c) 2018 VMware, Inc. All Rights Reserved. 4 | 5 | This product is licensed to you under the BSD-2 license (the "License"). You may not use this product except in compliance with the BSD-2 License. 6 | 7 | This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. 8 | 9 | 10 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/tn_uuid.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get transport node uuid 6 | command: bash -c "grep -oP '(?<=UUID>)[^<]+' /etc/vmware/nsx/controller-info.xml" 7 | register: tn_uuid 8 | - name: 9 | fail: msg="invalid transport node uuid" 10 | when: tn_uuid.stdout == "" 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/check_legacy_lsp.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get legacy lsp 6 | stat: 7 | path: /etc/vmware/nsx-bm/lpid 8 | register: stat_result 9 | - name: check legacy logical port id 10 | debug: msg="legacy lspid found, pls. remove it" 11 | when: stat_result.stat.exists == True 12 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/fqdn.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get fqdn tag 6 | command: bash -c "grep \ /etc/vmware/nsx/controller-info.xml | cat" 7 | register: fqdn_tag 8 | - name: set fqdn option 9 | set_fact: 10 | FQDN: true 11 | when: fqdn_tag.stdout != "" 12 | - debug: 13 | var: FQDN 14 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/win_tn_uuid.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get transport node uuid 6 | win_command: powershell.exe [xml]$cn = Get-Content '{{InstallDir.value}}\controller-info.xml'; $cn.config.transportNode.UUID 7 | register: tn_uuid 8 | - name: 9 | fail: msg="invalid transport node uuid" 10 | when: tn_uuid.stdout == "" 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/win_get_lsp_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Get LP Id 6 | win_command: powershell.exe Get-Content '{{InstallDir.value}}\lsp_id.txt' 7 | register: lspid 8 | - name: check logical port id 9 | fail: msg="lspid not found" 10 | when: lspid.stdout == "" 11 | - debug: msg="Logical Switch Port ID {{ lspid.stdout }}" 12 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/create_lsp.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check ls id or ls name 6 | fail: msg="ls_id or ls_name not defined" 7 | when: (ls_id is not defined) and (ls_name is not defined) 8 | - import_tasks: lsp/create_lsp_by_id.yml 9 | when: ls_id is defined 10 | - import_tasks: lsp/create_lsp_by_name.yml 11 | when: ls_name is defined 12 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/check_rhel7_dependency.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | mkdir -p /opt/baremetal/ 7 | dependency=/opt/baremetal/miss-dependency 8 | rm -rf $dependency 9 | touch $dependency 10 | 11 | {% for item in rhel7_dependency %} 12 | echo {{ item }} 13 | output=$(rpm -qa |grep {{ item }}) 14 | if [ ! -z "$output" ]; then 15 | echo "installed" 16 | else 17 | echo "no installed" 18 | echo {{ item }} >> $dependency 19 | fi 20 | {% endfor %} 21 | 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/check_rhel8_dependency.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | mkdir -p /opt/baremetal/ 7 | dependency=/opt/baremetal/miss-dependency 8 | rm -rf $dependency 9 | touch $dependency 10 | 11 | {% for item in rhel8_dependency %} 12 | echo {{ item }} 13 | output=$(rpm -qa |grep {{ item }}) 14 | if [ ! -z "$output" ]; then 15 | echo "installed" 16 | else 17 | echo "no installed" 18 | echo {{ item }} >> $dependency 19 | fi 20 | {% endfor %} 21 | 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/check_suse_dependency.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | mkdir -p /opt/baremetal/ 7 | dependency=/opt/baremetal/miss-dependency 8 | rm -rf $dependency 9 | touch $dependency 10 | 11 | {% for item in suse12_dependency %} 12 | echo {{ item }} 13 | output=$(rpm -qa |grep {{ item }}) 14 | if [ ! -z "$output" ]; then 15 | echo "installed" 16 | else 17 | echo "no installed" 18 | echo {{ item }} >> $dependency 19 | fi 20 | {% endfor %} 21 | 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/windows/get_install_dir.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Get Install Dir 6 | win_reg_stat: 7 | path: HKLM:\SOFTWARE\VMware, Inc.\NSX 8 | name: InstallDir 9 | register: InstallDir 10 | - name: Check Install Dir 11 | fail: msg="unknown install dir" 12 | when: (InstallDir.value == "") 13 | - debug: msg="{{InstallDir.value}}" 14 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: generate config file 6 | block: 7 | - name: create directory 8 | file: 9 | path: /etc/vmware/nsx-bm 10 | state: directory 11 | mode: 0755 12 | - name: generate config mode 13 | copy: 14 | content: "{{ config_mode }}" 15 | dest: /etc/vmware/nsx-bm/bms.conf 16 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/save_lsp_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: save lsp id 6 | block: 7 | - name: create directory 8 | file: 9 | path: /etc/vmware/nsx-bm 10 | state: directory 11 | mode: 0755 12 | - name: generate logical switch port config 13 | copy: 14 | content: "{{ lp_id }}" 15 | dest: /etc/vmware/nsx-bm/lpid 16 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/win_save_lsp_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: save lsp id 6 | block: 7 | - name: create file 8 | win_file: 9 | path: "{{ InstallDir.value }}\\lsp_id.txt" 10 | state: touch 11 | - name: Set the contents of a file 12 | win_copy: 13 | dest: "{{ InstallDir.value }}\\lsp_id.txt" 14 | content: "{{ lp_id }}" 15 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/check_ubuntu16_dependency.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | mkdir -p /opt/baremetal/ 7 | dependency=/opt/baremetal/miss-dependency 8 | rm -rf $dependency 9 | touch $dependency 10 | 11 | 12 | {% for item in ubuntu16_dependency %} 13 | echo {{ item }} 14 | output=$(dpkg -l |awk '/[a-z]i/{print $2}'|grep {{ item }}) 15 | if [ ! -z "$output" ]; then 16 | echo "installed" 17 | else 18 | echo "no installed" 19 | echo {{ item }} >> $dependency 20 | fi 21 | {% endfor %} 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/check_ubuntu18_dependency.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | mkdir -p /opt/baremetal/ 7 | dependency=/opt/baremetal/miss-dependency 8 | rm -rf $dependency 9 | touch $dependency 10 | 11 | 12 | {% for item in ubuntu18_dependency %} 13 | echo {{ item }} 14 | output=$(dpkg -l |awk '/[a-z]i/{print $2}'|grep {{ item }}) 15 | if [ ! -z "$output" ]; then 16 | echo "installed" 17 | else 18 | echo "no installed" 19 | echo {{ item }} >> $dependency 20 | fi 21 | {% endfor %} 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/vif/attach_vif.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: attach vif to int-br 6 | command: bash -c "ovs-vsctl --timeout=5 -- --if-exists del-port {{ app_intf_name }}-peer -- add-port {{ int_br_name.stdout }} {{ app_intf_name }}-peer -- set Interface {{ app_intf_name }}-peer external-ids:attached-mac={{ mac_address }} external-ids:iface-id={{ vif_id }} external-ids:iface-status=active" 7 | -------------------------------------------------------------------------------- /bms-ansible-nsx/vif/int_br_name.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get integration bridge name 6 | command: bash -c "ovs-vsctl list-br | while read line; do if [ $(ovs-vsctl br-get-external-id $line) ]; then echo $line; fi; done" 7 | register: int_br_name 8 | - name: check integration bridge name 9 | fail: msg="integration bridge not found" 10 | when: int_br_name.stdout== "" 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/auth/manager_thumbprint_validate.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Validate Manager Thumbprint 6 | command: python auth/thumbprint_validate.py {{ hostvars.nsxmanager.ip }} 443 {{ hostvars.nsxmanager.thumbprint }} 7 | when: hostvars.nsxmanager.thumbprint is defined 8 | delegate_to: 127.0.0.1 9 | register: thumbprint_checking_result 10 | failed_when: thumbprint_checking_result.rc != 0 11 | -------------------------------------------------------------------------------- /bms-ansible-nsx/win_restore.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_restoration 7 | any_errors_fatal: true 8 | become_method: runas 9 | vars: 10 | ansible_become_password: "{{ ansible_password }}" 11 | tasks: 12 | - import_tasks: windows/get_install_dir.yml 13 | - import_tasks: vif/win_detach_vif.yml 14 | - import_tasks: lsp/win_get_lsp_id.yml 15 | - import_tasks: lsp/delete_lsp.yml 16 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/create_lsp.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "{{ ansible_hostname }}/{{ app_intf_name }}@{{ tn_uuid.stdout | trim }}", 3 | "logical_switch_id": "{{ ls_id }}", 4 | "attachment": { 5 | "attachment_type": "VIF", 6 | "id": "{{ vif_id }}", 7 | "context": { 8 | "resource_type": "VifAttachmentContext", 9 | "allocate_addresses": "None", 10 | "vif_type": "INDEPENDENT", 11 | "transport_node_uuid": "{{ tn_uuid.stdout | trim }}" 12 | } 13 | }, 14 | "address_bindings": [], 15 | "admin_state": "UP", 16 | "tags": [ 17 | { 18 | "scope": "bm/os_type", 19 | "tag": "{{ os_type.stdout }}" 20 | } 21 | ] 22 | } 23 | 24 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/bms_config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Set underlay mode 6 | set_fact: 7 | underlay_mode: "false" 8 | when: underlay_mode is not defined 9 | - name: Generate underlay config file 10 | template: 11 | src: ./templates/nsx-baremetal.j2 12 | dest: /etc/vmware/nsx/nsx-baremetal.xml 13 | owner: nsx-agent 14 | group: nsx-agent 15 | mode: 0660 16 | - name: Restart nsx-agent 17 | command: /etc/init.d/nsx-agent restart 18 | -------------------------------------------------------------------------------- /bms-ansible-nsx/system/del_service_bootup.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: del bootup script for Ubuntu 6 | command: update-rc.d -f nsx-baremetal remove 7 | when: os_type.stdout == "Ubuntu" 8 | - name: del bootup script for RHEL/CentOS 9 | command: chkconfig --del nsx-baremetal 10 | when: (os_type.stdout == "RedHatEnterpriseServer") or 11 | (os_type.stdout == "RedHatEnterprise") or 12 | (os_type.stdout == "CentOS") or 13 | (os_type.stdout == "SUSE") 14 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/vlan_0_ls_check.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check ls id or is name 6 | fail: msg="ls_id or ls_name not defined" 7 | when: (ls_id is not defined) and (ls_name is not defined) 8 | - name: ls id assignment 9 | set_fact: lsid={{ ls_id }} 10 | when: ls_id is defined 11 | - import_tasks: validation/vlan_0_ls_check_by_id.yml 12 | when: ls_id is defined 13 | - import_tasks: validation/vlan_0_ls_check_by_name.yml 14 | when: (ls_name is defined) and (ls_id is not defined) 15 | -------------------------------------------------------------------------------- /bms-ansible-nsx/system/add_service_bootup.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: add bootup script for Ubuntu 6 | command: update-rc.d nsx-baremetal defaults 9 7 | when: os_type.stdout == "Ubuntu" 8 | - name: add bootup script for RHEL/CentOS 9 | command: chkconfig --add nsx-baremetal 10 | when: (os_type.stdout == "RedHatEnterpriseServer") or 11 | (os_type.stdout == "RedHatEnterprise") or 12 | (os_type.stdout == "CentOS") or 13 | (os_type.stdout == "OracleServer") or 14 | (os_type.stdout == "SUSE") 15 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/delete_lsp.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018-2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: Delete Logical Switch Port 6 | delegate_to: localhost 7 | uri: 8 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports/{{ lspid.stdout | trim }}?detach=true 9 | method: DELETE 10 | user: "{{ hostvars.nsxmanager.username }}" 11 | password: "{{ hostvars.nsxmanager.password }}" 12 | headers: 13 | Content-Type: "application/json" 14 | force_basic_auth: yes 15 | validate_certs: no 16 | status_code: 200 17 | body_format: json 18 | -------------------------------------------------------------------------------- /bms-ansible-nsx/system/get_os_type.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get OS type 6 | command: /usr/bin/lsb_release -si 7 | register: os_type 8 | - name: check OS type 9 | fail: msg="unsupport OS type" 10 | when: (os_type.stdout == "") or 11 | ((os_type.stdout != "Ubuntu") and 12 | (os_type.stdout != "RedHatEnterpriseServer") and 13 | (os_type.stdout != "RedHatEnterprise") and 14 | (os_type.stdout != "CentOS") and 15 | (os_type.stdout != "OracleServer") and 16 | (os_type.stdout != "SUSE")) 17 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/create_communication_map.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "resource_type": "CommunicationMap", 3 | "description": "Quarantine communcation map", 4 | "display_name": "quarantine-section-1", 5 | "category":"Application", 6 | "communication_entries": [ 7 | { 8 | "resource_type": "CommunicationEntry", 9 | "description": " comm entry", 10 | "display_name": "ce-1", 11 | "sequence_number": 1, 12 | "source_groups": [ 13 | "/infra/domains/bare-metal/groups/untrustvifgroup" 14 | ], 15 | "destination_groups": [ 16 | "/infra/domains/bare-metal/groups/trustvifgroup" 17 | ], 18 | "services": [ 19 | "ANY" 20 | ], 21 | "action": "DROP" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /bms-ansible-nsx/policy/create_domain.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: create domain 6 | uri: 7 | url: https://{{ hostvars.policymanager.ip }}/policy/api/v1/infra/domains/bare-metal1 8 | method: PUT 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | body: "{{ lookup('template', 'create_domain.json.j2') }}" 14 | return_content: yes 15 | force_basic_auth: yes 16 | validate_certs: no 17 | status_code: 200 18 | body_format: json 19 | -------------------------------------------------------------------------------- /bms-ansible-nsx/restore.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_restoration 7 | tasks: 8 | - import_tasks: auth/manager_thumbprint_validate.yml 9 | - name: Get Config Mode 10 | command: bash -c "cat /etc/vmware/nsx-bm/bms.conf |grep config_mode" 11 | register: ConfigMode 12 | - import_tasks: restore/bms_static_dhcp_restore.yml 13 | when: (ConfigMode.stdout == "config_mode=static") or 14 | (ConfigMode.stdout == "config_mode=dhcp") 15 | - import_tasks: restore/bms_migrate_restore.yml 16 | when: ConfigMode.stdout == "config_mode=migrate" 17 | -------------------------------------------------------------------------------- /bms-ansible-nsx/config/bms_update.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_migration 7 | tasks: 8 | - name: Set underlay mode 9 | set_fact: 10 | underlay_mode: "false" 11 | when: underlay_mode is not defined 12 | - name: Generate underlay config file 13 | template: 14 | src: ../templates/nsx-baremetal.j2 15 | dest: /etc/vmware/nsx/nsx-baremetal.xml 16 | owner: nsx-agent 17 | group: nsx-agent 18 | mode: 0660 19 | - name: load underlay config file 20 | command: ovs-appctl -t /var/run/vmware/nsx-agent/nsxa-ctl bms/underlay-config 21 | -------------------------------------------------------------------------------- /bms-ansible-nsx/policy/create_trustvif_group.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: create trust group by vif 6 | uri: 7 | url: https://{{ hostvars.policymanager.ip }}/policy/api/v1/infra/domains/bare-metal/groups/trustvifgroup 8 | method: PUT 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | body: "{{ lookup('template', 'create_trustvif_group.json.j2') }}" 14 | return_content: yes 15 | force_basic_auth: yes 16 | validate_certs: no 17 | status_code: 200 18 | body_format: json 19 | 20 | -------------------------------------------------------------------------------- /bms-ansible-nsx/policy/create_untrustvif_group.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: create untrust group by vif 6 | uri: 7 | url: https://{{ hostvars.policymanager.ip }}/policy/api/v1/infra/domains/bare-metal/groups/untrustvifgroup 8 | method: PUT 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | body: "{{ lookup('template', 'create_untrustvif_group.json.j2') }}" 14 | return_content: yes 15 | force_basic_auth: yes 16 | validate_certs: no 17 | status_code: 200 18 | body_format: json 19 | 20 | -------------------------------------------------------------------------------- /bms-ansible-nsx/policy/create_communication_map.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: create domain 6 | uri: 7 | url: https://{{ hostvars.policymanager.ip }}/policy/api/v1/infra/domains/bare-metal/communication-maps/quarantine-section-1 8 | method: PUT 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | body: "{{ lookup('template', 'create_communication_map.json.j2') }}" 14 | return_content: yes 15 | force_basic_auth: yes 16 | validate_certs: no 17 | status_code: 200 18 | body_format: json 19 | 20 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/vlan_0_ls_check_by_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get logical switch 6 | uri: 7 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-switches/{{ lsid }} 8 | method: GET 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | return_content: yes 14 | force_basic_auth: yes 15 | validate_certs: no 16 | status_code: 200 17 | body_format: json 18 | register: ls_response 19 | - name: check vlan id 20 | fail: msg="not a valid vlan 0 logical swtich" 21 | when: ls_response.json.vlan != 0 22 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/collect_untrust_vifid.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get ls id 6 | uri: 7 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports/{{ item }} 8 | method: GET 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | return_content: yes 14 | force_basic_auth: yes 15 | validate_certs: no 16 | status_code: 200 17 | body_format: json 18 | register: lsp_info_response 19 | - set_fact: vif_id="{{lsp_info_response.json.attachment.id}}" 20 | - set_fact: 21 | vif_untrust_list: "{{ vif_untrust_list }} + [ '{{ vif_id }}' ]" 22 | - debug: var=vif_untrust_list 23 | 24 | 25 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/collect_trust_vifid.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get ls id 6 | uri: 7 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports/{{ item }} 8 | method: GET 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | return_content: yes 14 | force_basic_auth: yes 15 | validate_certs: no 16 | status_code: 200 17 | body_format: json 18 | register: lsp_info_response 19 | - set_fact: vif_id="{{lsp_info_response.json.attachment.id}}" 20 | - set_fact: 21 | #vif_id_list: "{{ vif_id_list|default([]) }} + [ '{{ vif_id }}' ]" 22 | vif_trust_list: "{{ vif_trust_list }} + [ '{{ vif_id }}' ]" 23 | - debug: var=vif_trust_list 24 | 25 | 26 | -------------------------------------------------------------------------------- /bms-ansible-nsx/win_dhcp_config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_dhcp 7 | any_errors_fatal: true 8 | become_method: runas 9 | vars: 10 | ansible_become_password: "{{ ansible_password }}" 11 | tasks: 12 | - name: config mode 13 | set_fact: 14 | config_mode: 'dhcp' 15 | - name: set os type 16 | delegate_to: localhost 17 | command: echo "Windows" 18 | register: os_type 19 | - import_tasks: windows/get_install_dir.yml 20 | - import_tasks: config/win_tn_uuid.yml 21 | - import_tasks: lsp/vif_id.yml 22 | - import_tasks: validation/vif_id_check.yml 23 | - import_tasks: config/app_intf_name.yml 24 | - import_tasks: lsp/create_lsp.yml 25 | - import_tasks: lsp/win_save_lsp_id.yml 26 | - import_tasks: vif/win_attach_vif.yml 27 | -------------------------------------------------------------------------------- /bms-ansible-nsx/win_migrate.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_migration 7 | any_errors_fatal: true 8 | become_method: runas 9 | vars: 10 | ansible_become_password: "{{ ansible_password }}" 11 | tasks: 12 | - name: config mode 13 | set_fact: 14 | config_mode: 'underlay' 15 | - name: set os type 16 | delegate_to: localhost 17 | command: echo "Windows" 18 | register: os_type 19 | - import_tasks: windows/get_install_dir.yml 20 | - import_tasks: config/win_tn_uuid.yml 21 | - import_tasks: lsp/vif_id.yml 22 | - import_tasks: validation/vif_id_check.yml 23 | - import_tasks: config/app_intf_name.yml 24 | - import_tasks: lsp/create_lsp.yml 25 | - import_tasks: lsp/win_save_lsp_id.yml 26 | - import_tasks: vif/win_attach_vif.yml 27 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/bms_migrate.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | # Check MP CONNECTION 7 | connected=$(netstat -an |grep 1234 |grep ESTABLISHED) 8 | if [ -z "$connected" ]; then 9 | echo "Cannot connect to MP, pls. check MP connection" 10 | exit 1 11 | fi 12 | echo "MP connection is ok" 13 | 14 | 15 | echo "Start to migrate..." 16 | bash /tmp/migrate.sh 17 | 18 | if [ $? -ne 0 ]; then 19 | echo "migrate failed, revert setup" 20 | bash /tmp/revert.sh 21 | exit 1 22 | fi 23 | 24 | # After migrate, Check MP CONNECTION again 25 | connected=$(netstat -an |grep 1234 |grep ESTABLISHED) 26 | if [ -z "$connected" ]; then 27 | echo "Cannot connect to MP, log debug info" 28 | bash /opt/vmware/nsx-bm/debug.sh 29 | echo "Revert migration..." 30 | bash /tmp/revert.sh 31 | exit 1 32 | fi 33 | echo "MP connection is ok after migration" 34 | 35 | echo "migrate successfully" 36 | 37 | echo "config static route:" 38 | bash /opt/vmware/nsx-bm/route.sh 39 | 40 | exit 0 41 | 42 | -------------------------------------------------------------------------------- /bms-ansible-nsx/win_hosts: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | 6 | # Create an group that contains the Bare Metal Servers 7 | [windows:children] 8 | servers_static 9 | servers_dhcp 10 | servers_migration 11 | 12 | # Set variables common for all Bare Metal Servers 13 | [windows:vars] 14 | ansible_user= 15 | ansible_password= 16 | ansible_connection= 17 | ansible_winrm_server_cert_validation=ignore 18 | 19 | 20 | # host group for servers 21 | [servers_static] 22 | 10.117.5.191 static_ip= netmask= ls_name= 23 | 24 | [servers_dhcp] 25 | #10.117.5.191 ls_name= 26 | 27 | [servers_migration] 28 | #10.117.5.191 migrate_intf= ls_name= 29 | 30 | [servers_restoration] 31 | #10.117.5.191 32 | 33 | 34 | # NSX Configuration 35 | [NSX] 36 | #============================ 37 | # NSX Manager Credential 38 | nsxmanager ip= username= password= 39 | #============================ 40 | -------------------------------------------------------------------------------- /bms-ansible-nsx/validation/vlan_0_ls_check_by_name.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get logical switch 6 | uri: 7 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-switches 8 | method: GET 9 | user: "{{ hostvars.nsxmanager.username }}" 10 | password: "{{ hostvars.nsxmanager.password }}" 11 | headers: 12 | Content-Type: "application/json" 13 | return_content: yes 14 | force_basic_auth: yes 15 | validate_certs: no 16 | status_code: 200 17 | body_format: json 18 | register: ls_response 19 | - name: check logical switch id 20 | set_fact: lsid="{{ item.id }}" 21 | with_items: "{{ls_response.json.results}}" 22 | when: item.display_name == ls_name 23 | - name: check logical switch existence 24 | fail: msg="logical switch not found" 25 | when: lsid is not defined 26 | - import_tasks: vlan_0_ls_check_by_id.yml 27 | -------------------------------------------------------------------------------- /bms-ansible-nsx/win_static_config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_static 7 | any_errors_fatal: true 8 | become_method: runas 9 | vars: 10 | ansible_become_password: "{{ ansible_password }}" 11 | tasks: 12 | - name: config mode 13 | set_fact: 14 | config_mode: 'static' 15 | - name: set os type 16 | delegate_to: localhost 17 | command: echo "Windows" 18 | register: os_type 19 | - import_tasks: windows/get_install_dir.yml 20 | - import_tasks: validation/static_input_check.yml 21 | - import_tasks: config/win_tn_uuid.yml 22 | - import_tasks: lsp/vif_id.yml 23 | - import_tasks: validation/vif_id_check.yml 24 | - import_tasks: config/app_intf_name.yml 25 | - import_tasks: lsp/create_lsp.yml 26 | - import_tasks: lsp/win_save_lsp_id.yml 27 | - import_tasks: vif/win_attach_vif.yml 28 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/create_lsp_by_name.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: get logical switch 6 | delegate_to: localhost 7 | uri: 8 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-switches 9 | method: GET 10 | user: "{{ hostvars.nsxmanager.username }}" 11 | password: "{{ hostvars.nsxmanager.password }}" 12 | headers: 13 | Content-Type: "application/json" 14 | return_content: yes 15 | force_basic_auth: yes 16 | validate_certs: no 17 | status_code: 200 18 | body_format: json 19 | register: ls_response 20 | - name: check logical switch id 21 | set_fact: ls_id="{{ item.id }}" 22 | with_items: "{{ls_response.json.results}}" 23 | when: item.display_name == ls_name 24 | - name: check logical switch existence 25 | fail: msg="logical switch not found" 26 | when: ls_id is not defined 27 | - import_tasks: create_lsp_by_id.yml 28 | -------------------------------------------------------------------------------- /bms-ansible-nsx/lsp/create_lsp_by_id.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check ls id and vif id 6 | fail: msg="ls_id or vif_id not defined" 7 | when: (ls_id is not defined) or (vif_id is not defined) 8 | - name: create Logical Switch Port 9 | delegate_to: localhost 10 | uri: 11 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports 12 | method: POST 13 | user: "{{ hostvars.nsxmanager.username }}" 14 | password: "{{ hostvars.nsxmanager.password }}" 15 | headers: 16 | Content-Type: "application/json" 17 | body: "{{ lookup('template', 'create_lsp.json.j2') }}" 18 | return_content: yes 19 | force_basic_auth: yes 20 | validate_certs: no 21 | status_code: 201 22 | body_format: json 23 | register: lp_response 24 | - name: check logical switch port id 25 | fail: msg="logical switch port id not found" 26 | when: lp_response.json.id == "" 27 | - name: get lp id 28 | set_fact: 29 | lp_id: "{{ lp_response.json.id }}" 30 | -------------------------------------------------------------------------------- /bms-ansible-nsx/vif/win_attach_vif.yml: -------------------------------------------------------------------------------- 1 | - name: attach app vif 2 | win_shell: "& '{{ InstallDir.value }}\\win-bms-install.ps1' -operation vif-install -vif_id {{ vif_id }} -ip {{ static_ip }} -netmask {{ netmask }} -gateway {{ gateway }}" 3 | become: yes 4 | become_user: Administrator 5 | register: result 6 | when: (config_mode == "static") and (gateway is defined) 7 | - name: attach app vif 8 | win_shell: "& '{{ InstallDir.value }}\\win-bms-install.ps1' -operation vif-install -vif_id {{ vif_id }} -ip {{ static_ip }} -netmask {{ netmask }}" 9 | become: yes 10 | become_user: Administrator 11 | register: result 12 | when: (config_mode == "static") and (gateway is not defined) 13 | - name: attach app vif 14 | win_shell: "& '{{InstallDir.value}}\\win-bms-install.ps1' -operation vif-install -vif_id {{ vif_id }}" 15 | become: yes 16 | become_user: Administrator 17 | register: result 18 | when: (config_mode == "dhcp") 19 | - name: attach app vif 20 | win_shell: "& '{{InstallDir.value}}\\win-bms-install.ps1' -operation vif-install -vif_id {{ vif_id }} -underlay true" 21 | become: yes 22 | become_user: Administrator 23 | async: 60 24 | poll: 10 25 | register: result 26 | when: (config_mode == "underlay") 27 | -------------------------------------------------------------------------------- /bms-ansible-nsx/debug/debug.sh: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 2 | # SPDX-License-Identifier: BSD-2-Clause 3 | 4 | echo "netstat -an |grep 1234" 5 | netstat -an |grep 1234 6 | 7 | echo "netstat -an |grep 1235" 8 | netstat -an |grep 1235 9 | 10 | echo "ifconfig" 11 | ifconfig 12 | 13 | echo "ovs-vsctl show" 14 | ovs-vsctl show 15 | 16 | echo "ovs-ofctl dump-flows nsx-managed |ovs-decode-note|grep bms_bootstrap" 17 | ovs-ofctl dump-flows nsx-managed |ovs-decode-note|grep bms_bootstrap 18 | 19 | echo "ovs-appctl -t /var/run/vmware/nsx-agent/nsxa-ctl bms/underlay-get" 20 | ovs-appctl -t /var/run/vmware/nsx-agent/nsxa-ctl bms/underlay-get 21 | 22 | echo "LogSwitchConfigMsg" 23 | /opt/vmware/nsx-nestdb/bin/nestdb-cli --json --cmd get vmware.nsx.nestdb.LogSwitchConfigMsg 24 | 25 | echo "LogSwitchPortConfigMsg" 26 | /opt/vmware/nsx-nestdb/bin/nestdb-cli --json --cmd get vmware.nsx.nestdb.LogSwitchPortConfigMsg 27 | 28 | echo "VifStateMsg" 29 | /opt/vmware/nsx-nestdb/bin/nestdb-cli --json --cmd get vmware.nsx.nestdb.VifStateMsg 30 | 31 | echo "CcpSessionMsg" 32 | /opt/vmware/nsx-nestdb/bin/nestdb-cli --json --cmd get vmware.nsx.nestdb.CcpSessionMsg 33 | 34 | echo "ControllerInfoMsg" 35 | /opt/vmware/nsx-nestdb/bin/nestdb-cli --json --cmd get vmware.nsx.nestdb.ControllerInfoMsg 36 | -------------------------------------------------------------------------------- /bms-ansible-nsx/vif/create_vif.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: check app interface name 6 | fail: msg="app interface name is not defined" 7 | when: (app_intf_name is not defined) or 8 | (app_intf_name == "") 9 | - name: delete legacy app interface 10 | command: bash -c "ip link del {{ app_intf_name }} &> /dev/null | cat" 11 | - name: create veth pair 12 | command: ip link add {{ app_intf_name }} type veth peer name {{ app_intf_name }}-peer 13 | - name: bring veth up 14 | block: 15 | - name: bring veth up 16 | command: ip link set {{ app_intf_name }} up 17 | - name: bring veth peer up 18 | command: ip link set {{ app_intf_name }}-peer up 19 | - name: get app interface MAC address 20 | block: 21 | - command: bash -c "ip link show {{ app_intf_name }} |grep ether|awk '{print $2}'" 22 | register: mac 23 | - set_fact: 24 | mac_address: "{{ mac.stdout }}" 25 | when: mac_address is not defined 26 | - name: set MAC address 27 | command: ip link set dev {{ app_intf_name }} address {{ mac_address }} 28 | -------------------------------------------------------------------------------- /bms-ansible-nsx/quarantine_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: 127.0.0.1 3 | tasks: 4 | - name: get all lsp 5 | uri: 6 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports 7 | method: GET 8 | user: "{{ hostvars.nsxmanager.username }}" 9 | password: "{{ hostvars.nsxmanager.password }}" 10 | headers: 11 | Content-Type: "application/json" 12 | return_content: yes 13 | force_basic_auth: yes 14 | validate_certs: no 15 | status_code: 200 16 | body_format: json 17 | register: lsp_response 18 | - name: get lsp list 19 | set_fact: apply_to="{{ apply_to|default([]) + [ item.id ] }}" 20 | with_items: "{{ lsp_response.json.results }}" 21 | when: item.id not in "{{ hostvars.quarantine.lsp }}" 22 | - name: print apply_to 23 | debug: var=apply_to 24 | - set_fact: vif_trust_list=[] 25 | - include_tasks: lsp/collect_trust_vifid.yml 26 | with_items: "{{ apply_to }}" 27 | - set_fact: vif_untrust_list=[] 28 | - include_tasks: lsp/collect_untrust_vifid.yml 29 | with_items: "{{ hostvars.quarantine.lsp }}" 30 | - import_tasks: policy/create_domain.yml 31 | - import_tasks: policy/create_trustvif_group.yml 32 | - import_tasks: policy/create_untrustvif_group.yml 33 | - import_tasks: policy/create_communication_map.yml 34 | 35 | -------------------------------------------------------------------------------- /bms-ansible-nsx/unprepare.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: TransportNodes 7 | tasks: 8 | - name: is ubuntu 9 | stat: 10 | path: /etc/lsb-release 11 | register: ubuntu_stat_result 12 | - name: is rhel 13 | stat: 14 | path: /etc/redhat-release 15 | register: rhel_stat_result 16 | - name: is suse 17 | stat: 18 | path: /etc/SuSE-release 19 | register: suse_stat_result 20 | - name: get miss dependency list 21 | command: cat /opt/baremetal/miss-dependency 22 | register: miss_dependency 23 | - debug: 24 | msg: "{{miss_dependency.stdout}}" 25 | - name: uninstall miss dependency 26 | package: 27 | name: "{{ item }}" 28 | state: absent 29 | with_items: "{{ miss_dependency.stdout_lines }}" 30 | when: (ubuntu_stat_result.stat.exists == True) or (rhel_stat_result.stat.exists == True) 31 | - name: uninstall suse miss dependency 32 | zypper: 33 | name: "{{ item }}" 34 | state: absent 35 | with_items: "{{ miss_dependency.stdout_lines }}" 36 | when: suse_stat_result.stat.exists == True 37 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/quarantine_rule_properties.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "display_name": "baremetal-quarantine-section", 3 | "section_type": "LAYER3", 4 | "stateful": true, 5 | "applied_tos": [ 6 | {% for item in apply_to %} 7 | { 8 | "target_type": "LogicalPort", 9 | "target_id": "{{ item }}" 10 | }, 11 | {% endfor %} 12 | ], 13 | "rules": [ 14 | { 15 | "display_name":"quarantine-rule", 16 | "destinations_excluded": false, 17 | "action":"DROP", 18 | "direction":"IN_OUT", 19 | "sources": [ 20 | {% for item in hostvars.quarantine.lsp %} 21 | { 22 | "target_type": "LogicalPort", 23 | "target_id": "{{ item }}", 24 | "is_valid": true 25 | }, 26 | {% endfor %} 27 | ] 28 | }, 29 | { 30 | "display_name":"quarantine-rule-1", 31 | "destinations_excluded": false, 32 | "action":"DROP", 33 | "direction":"IN_OUT", 34 | "destinations": [ 35 | {% for item in hostvars.quarantine.lsp %} 36 | { 37 | "target_type": "LogicalPort", 38 | "target_id": "{{ item }}", 39 | "is_valid": true 40 | }, 41 | 42 | {% endfor %} 43 | ] 44 | } 45 | ], 46 | "tags": [ 47 | { 48 | "scope": "bare-metal", 49 | "tag": "quarantine" 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /bms-ansible-nsx/quarantine.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: 127.0.0.1 3 | tasks: 4 | - name: get all lsp 5 | uri: 6 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/logical-ports 7 | method: GET 8 | user: "{{ hostvars.nsxmanager.username }}" 9 | password: "{{ hostvars.nsxmanager.password }}" 10 | headers: 11 | Content-Type: "application/json" 12 | return_content: yes 13 | force_basic_auth: yes 14 | validate_certs: no 15 | status_code: 200 16 | body_format: json 17 | register: lsp_response 18 | - name: get lsp list 19 | set_fact: apply_to="{{ apply_to|default([]) + [ item.id ] }}" 20 | with_items: "{{ lsp_response.json.results }}" 21 | when: item.id not in "{{ hostvars.quarantine.lsp }}" 22 | - name: print apply_to 23 | debug: var=apply_to 24 | - name: post rule 25 | uri: 26 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/firewall/sections?action=create_with_rules 27 | method: POST 28 | user: "{{ hostvars.nsxmanager.username }}" 29 | password: "{{ hostvars.nsxmanager.password }}" 30 | headers: 31 | Content-Type: "application/json" 32 | body: "{{ lookup('template', 'quarantine_rule_properties.json.j2') }}" 33 | return_contents: yes 34 | force_basic_auth: yes 35 | validate_certs: no 36 | status_code: 201 37 | body_format: json 38 | -------------------------------------------------------------------------------- /bms-ansible-nsx/manual/static_dhcp_manual_restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | if (($# > 1)); then 9 | echo "Too many parameters: $@" 10 | exit 11 | elif [ $# -eq 1 ]; then 12 | app_intf_name=$1 13 | else 14 | app_intf_name=nsx-eth 15 | fi 16 | 17 | get_os_type() { 18 | host_os=$(lsb_release -si) 19 | } 20 | 21 | isRhel() { 22 | if [ "$host_os" == "RedHatEnterpriseServer" ]; then 23 | return 0 24 | fi 25 | if [ "$host_os" == "RedHatEnterprise" ]; then 26 | return 0 27 | fi 28 | if [ "$host_os" == "CentOS" ]; then 29 | return 0 30 | fi 31 | if [ "$host_os" == "OracleServer" ]; then 32 | return 0 33 | fi 34 | return 1 35 | } 36 | 37 | isUbuntu() { 38 | if [ "$host_os" == "Ubuntu" ]; then 39 | return 0 40 | fi 41 | return 1 42 | } 43 | 44 | get_os_type 45 | 46 | 47 | dhclient -r $app_intf_name 48 | ovs-vsctl -- --if-exists del-port ${app_intf_name}-peer 49 | 50 | ip link del ${app_intf_name} &> /dev/null 51 | 52 | if isRhel; then 53 | chkconfig --del nsx-baremetal 54 | elif isUbuntu; then 55 | update-rc.d -f nsx-baremetal remove 56 | fi 57 | 58 | rm -rf /etc/vmware/nsx-bm 59 | rm -f /etc/init.d/nsx-baremetal 60 | 61 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/bms_static_init.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | # nsx-baremetal-server 7 | # 8 | # chkconfig: 2345 08 92 9 | # description: 10 | 11 | # 12 | ### BEGIN INIT INFO 13 | # Provides: nsx-baremetal-server 14 | # Required-Start: 15 | # Required-Stop: 16 | # Default-Start: 2 3 4 5 17 | # Default-Stop: 0 1 6 18 | # Short-Description: nsx-baremetal-server 19 | ### END INIT INFO 20 | 21 | nsx_log() { 22 | echo "${1}" 23 | logger -p daemon.info -t NSX-BMS "${1}" 24 | } 25 | 26 | start() { 27 | nsx_log "nsx-baremetal start" 28 | ip link add {{ app_intf_name }} type veth peer name {{ app_intf_name }}-peer 29 | ip link set dev {{ app_intf_name }} address {{ mac_address }} 30 | ifconfig {{ app_intf_name }} {{ static_ip }} netmask {{ netmask }} up 31 | ifconfig {{ app_intf_name }}-peer up 32 | ovs-vsctl --timeout=5 -- --if-exists del-port {{ app_intf_name }}-peer -- add-port {{ int_br_name.stdout }} {{ app_intf_name }}-peer \ 33 | -- set Interface {{ app_intf_name }}-peer external-ids:attached-mac={{ mac_address }} \ 34 | external-ids:iface-id={{ vif_id }} external-ids:iface-status=active 35 | {% if routing_table is defined %} 36 | {% for item in routing_table %} 37 | route add {{ item }} dev {{ app_intf_name }} 38 | {% endfor %} 39 | {% endif %} 40 | } 41 | 42 | case "${1}" in 43 | "start") 44 | start 45 | ;; 46 | *) 47 | exit 1 48 | ;; 49 | esac 50 | -------------------------------------------------------------------------------- /bms-ansible-nsx/restore/bms_migrate_restore.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - name: config option 6 | set_fact: 7 | FQDN: false 8 | - import_tasks: config/fqdn.yml 9 | - import_tasks: system/get_os_type.yml 10 | - import_tasks: validation/migration_input_check.yml 11 | - import_tasks: config/app_intf_name.yml 12 | - name: Create restore script file 13 | template: 14 | src: templates/bms_migrate_restore.j2 15 | dest: /tmp/bms_restore.sh 16 | owner: root 17 | group: root 18 | mode: 0755 19 | - name: Run restore script 20 | shell: /tmp/bms_restore.sh >> /var/log/restore.log 2>&1 21 | - import_tasks: lsp/get_lsp_id.yml 22 | - import_tasks: lsp/delete_lsp.yml 23 | - import_tasks: system/del_service_bootup.yml 24 | - name: delete config file 25 | file: 26 | path: /etc/vmware/nsx-bm 27 | state: absent 28 | - name: delete init script 29 | file: 30 | path: /etc/init.d/nsx-baremetal 31 | state: absent 32 | - name: delete bms config 33 | block: 34 | - name: remove bms config 35 | file: 36 | path: /etc/vmware/nsx/nsx-baremetal.xml 37 | state: absent 38 | when: not FQDN 39 | - name: restart nsx-agent 40 | command: /etc/init.d/nsx-agent restart 41 | when: not FQDN 42 | - name: delete manual script 43 | file: 44 | path: /opt/vmware/nsx-bm 45 | state: absent 46 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Ansible Playbook for Bare Metal Server Integration with NSX-T 2 | 3 | Copyright (c) 2018 VMware, Inc. All rights reserved 4 | 5 | The BSD-2 license (the “License”) set forth below applies to all parts of the Ansible Playbook for Bare Metal Server Integration with NSX-T 6 | project. You may not use this file except in compliance with the License.  7 | 8 | BSD-2 License 9 | 10 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 11 | • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 12 | • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | 15 | 16 | -------------------------------------------------------------------------------- /bms-ansible-nsx/restore/bms_static_dhcp_restore.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | - import_tasks: system/get_os_type.yml 6 | - import_tasks: config/app_intf_name.yml 7 | - name: dhcp exit 8 | command: dhclient -r {{ app_intf_name }} 9 | when: ConfigMode.stdout == "config_mode=dhcp" 10 | - name: detach vif from int-br 11 | command: ovs-vsctl -- --if-exists del-port {{ app_intf_name }}-peer 12 | - name: delete veth 13 | command: bash -c "ip link del {{ app_intf_name }} &> /dev/null" 14 | ignore_errors: yes 15 | - import_tasks: lsp/get_lsp_id.yml 16 | - import_tasks: lsp/delete_lsp.yml 17 | - import_tasks: system/del_service_bootup.yml 18 | - name: delete config file 19 | file: 20 | path: /etc/vmware/nsx-bm 21 | state: absent 22 | - name: delete init script 23 | file: 24 | path: /etc/init.d/nsx-baremetal 25 | state: absent 26 | - name: delete suse network configure file 27 | file: 28 | path: /etc/sysconfig/network/ifcfg-{{ app_intf_name }} 29 | state: absent 30 | when: os_type.stdout == "SUSE" 31 | - name: delete bms config 32 | block: 33 | - name: remove bms config 34 | file: 35 | path: /etc/vmware/nsx/nsx-baremetal.xml 36 | state: absent 37 | - name: restart nsx-agent 38 | command: /etc/init.d/nsx-agent restart 39 | - name: delete manual script 40 | file: 41 | path: /opt/vmware/nsx-bm 42 | state: absent 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # bare-metal-server-integration-with-nsxt 4 | This repository contains Ansible playbooks for supporting Bare Metal Server integration with NSX-T. 5 | Require Ansbile Playbook version equal or greater than 2.5.0 (for Windows) or 2.4.3.0 (for other platforms). 6 | 7 | Branch nsx-t-chef-xxx is Chef Cookbook for supporting Bare Metal Server integration with NSX-T. 8 | 9 | ## Documentation 10 | 11 | ## Releases & Major Branches 12 | The playbooks in master branch are used for development. 13 | 14 | Branch release-4.1.0 is compatible with NSX-T 4.1.0 15 | 16 | Branch release-4.0.0 is compatible with NSX-T 4.0.0 17 | 18 | Branch release-3.2.0 is compatible with NSX-T 3.2.0 19 | 20 | Branch release-3.1.0 is compatible with NSX-T 3.1.0 21 | 22 | Branch release-3.0.0 is compatible with NSX-T 3.0.0 23 | 24 | Branch release-2.5.0 is compatible with NSX-T 2.5.0 25 | 26 | Branch release-2.4.0 is compatible with NSX-T 2.4.0 27 | 28 | Branch release-2.3.0 is compatible with NSX-T 2.3.0 29 | 30 | Branch nsx-t-chef-3.0.2 is compatible with NSX-T 3.0.2 31 | 32 | ## Contributing 33 | 34 | The bare-metal-server-integration-with-nsxt project team welcomes contributions from the community. Before you start working with bare-metal-server-integration-with-nsxt, please read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on as an open-source patch. For more detailed information, refer to [CONTRIBUTING.md](CONTRIBUTING.md). 35 | 36 | ## License 37 | See the [License](LICENSE.txt). 38 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/bms_dhcp_init.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | # nsx-baremetal-server 7 | # 8 | # chkconfig: 2345 08 92 9 | # description: 10 | 11 | # 12 | ### BEGIN INIT INFO 13 | # Provides: nsx-baremetal-server 14 | # Required-Start: 15 | # Required-Stop: 16 | # Default-Start: 2 3 4 5 17 | # Default-Stop: 0 1 6 18 | # Short-Description: nsx-baremetal-server 19 | ### END INIT INFO 20 | 21 | 22 | nsx_log() { 23 | echo "${1}" 24 | logger -p daemon.info -t NSX-BMS "${1}" 25 | } 26 | 27 | get_os_type() { 28 | host_os=$(lsb_release -si) 29 | nsx_log "host_os: $host_os" 30 | } 31 | 32 | isSUSE() { 33 | if [ "$host_os" == "SUSE" ]; then 34 | return 0 35 | fi 36 | return 1 37 | } 38 | 39 | start() { 40 | nsx_log "nsx-baremetal start" 41 | ip link add {{ app_intf_name }} type veth peer name {{ app_intf_name }}-peer 42 | ifconfig {{ app_intf_name }} up 43 | ip link set dev {{ app_intf_name }} address {{ mac_address }} 44 | ifconfig {{ app_intf_name }}-peer up 45 | ovs-vsctl --timeout=5 -- --if-exists del-port {{ app_intf_name }}-peer -- add-port {{ int_br_name.stdout }} {{ app_intf_name }}-peer \ 46 | -- set Interface {{ app_intf_name }}-peer external-ids:attached-mac={{ mac_address }} \ 47 | external-ids:iface-id={{ vif_id }} external-ids:iface-status=active 48 | if isSUSE; then 49 | ifup {{ app_intf_name }} 50 | else 51 | dhclient -nw {{ app_intf_name }} 52 | fi 53 | {% if routing_table is defined %} 54 | {% for item in routing_table %} 55 | route add {{ item }} dev {{ app_intf_name }} 56 | {% endfor %} 57 | {% endif %} 58 | } 59 | 60 | case "${1}" in 61 | "start") 62 | start 63 | ;; 64 | *) 65 | exit 1 66 | ;; 67 | esac 68 | -------------------------------------------------------------------------------- /bms-ansible-nsx/static_config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_static 7 | any_errors_fatal: true 8 | tasks: 9 | - name: config underlay mode 10 | set_fact: 11 | config_mode: 'config_mode=static' 12 | underlay_mode: 'false' 13 | - import_tasks: auth/manager_thumbprint_validate.yml 14 | - import_tasks: system/get_os_type.yml 15 | - import_tasks: config/tn_uuid.yml 16 | - import_tasks: lsp/check_legacy_lsp.yml 17 | - import_tasks: lsp/vif_id.yml 18 | - import_tasks: vif/int_br_name.yml 19 | - import_tasks: validation/vif_id_check.yml 20 | - import_tasks: validation/static_input_check.yml 21 | - import_tasks: config/app_intf_name.yml 22 | - import_tasks: lsp/create_lsp.yml 23 | - import_tasks: lsp/save_lsp_id.yml 24 | - import_tasks: config/bms_config.yml 25 | - import_tasks: config/config.yml 26 | - import_tasks: vif/create_vif.yml 27 | - name: create bm dir 28 | file: 29 | path: /opt/vmware/nsx-bm 30 | state: directory 31 | mode: 0755 32 | - name: create manual restore script 33 | copy: 34 | src: ./manual/static_dhcp_manual_restore.sh 35 | dest: /opt/vmware/nsx-bm/static_dhcp_manual_restore.sh 36 | owner: root 37 | group: root 38 | mode: 0755 39 | - name: set IP address 40 | command: ifconfig {{ app_intf_name }} {{ static_ip }} netmask {{ netmask }} 41 | - import_tasks: vif/attach_vif.yml 42 | - import_tasks: route/route.yml 43 | when: routing_table is defined 44 | - import_tasks: config/config.yml 45 | - name: create bootup script 46 | template: 47 | src: templates/bms_static_init.j2 48 | dest: /etc/init.d/nsx-baremetal 49 | owner: root 50 | group: root 51 | mode: 0755 52 | - import_tasks: system/add_service_bootup.yml 53 | -------------------------------------------------------------------------------- /bms-ansible-nsx/unquarantine.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: 127.0.0.1 3 | tasks: 4 | - name: get quarantine section 5 | uri: 6 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/search?query=resource_type:Firewallsection%20AND%20tags.scope:bare-metal%20AND%20tags.tag:quarantine 7 | method: GET 8 | user: "{{ hostvars.nsxmanager.username }}" 9 | password: "{{ hostvars.nsxmanager.password }}" 10 | headers: 11 | Content-Type: "application/json" 12 | return_content: yes 13 | force_basic_auth: yes 14 | validate_certs: no 15 | status_code: 200 16 | body_format: json 17 | register: section_response 18 | - name: get section id 19 | set_fact: section_id="{{ item.id }}" 20 | with_items: "{{section_response.json.results}}" 21 | - name: check section id 22 | fail: msg="quarantine section id not found" 23 | when: section_id is not defined 24 | - name: get rule id 25 | uri: 26 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/firewall/sections/{{ section_id }}/rules 27 | method: GET 28 | user: "{{ hostvars.nsxmanager.username }}" 29 | password: "{{ hostvars.nsxmanager.password }}" 30 | return_contents: yes 31 | force_basic_auth: yes 32 | validate_certs: no 33 | status_code: 200 34 | body_format: json 35 | register: rules_response 36 | - name: get rule id 37 | set_fact: rule_ids="{{ rule_ids|default([]) + [ item.id ] }}" 38 | with_items: "{{rules_response.json.results}}" 39 | - name: check rule id 40 | fail: msg="rule id not found" 41 | when: rule_ids is not defined 42 | - debug: var=rule_ids 43 | - include_tasks: policy/delete_rule.yml 44 | with_items: "{{ rule_ids }}" 45 | - name: delete quarantine section 46 | uri: 47 | url: https://{{ hostvars.nsxmanager.ip }}/api/v1/firewall/sections/{{ section_id }} 48 | method: DELETE 49 | user: "{{ hostvars.nsxmanager.username }}" 50 | password: "{{ hostvars.nsxmanager.password }}" 51 | return_contents: yes 52 | force_basic_auth: yes 53 | validate_certs: no 54 | status_code: 200 55 | -------------------------------------------------------------------------------- /bms-ansible-nsx/dhcp_config.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_dhcp 7 | any_errors_fatal: true 8 | tasks: 9 | - name: config underlay mode 10 | set_fact: 11 | config_mode: 'config_mode=dhcp' 12 | underlay_mode: 'false' 13 | - import_tasks: auth/manager_thumbprint_validate.yml 14 | - import_tasks: system/get_os_type.yml 15 | - import_tasks: config/tn_uuid.yml 16 | - import_tasks: lsp/check_legacy_lsp.yml 17 | - import_tasks: lsp/vif_id.yml 18 | - import_tasks: vif/int_br_name.yml 19 | - import_tasks: validation/vif_id_check.yml 20 | - import_tasks: config/app_intf_name.yml 21 | - import_tasks: lsp/create_lsp.yml 22 | - import_tasks: lsp/save_lsp_id.yml 23 | - import_tasks: config/bms_config.yml 24 | - import_tasks: config/config.yml 25 | - import_tasks: vif/create_vif.yml 26 | - import_tasks: vif/attach_vif.yml 27 | - import_tasks: route/route.yml 28 | - name: create bm dir 29 | file: 30 | path: /opt/vmware/nsx-bm 31 | state: directory 32 | mode: 0755 33 | - name: create manual restore script 34 | copy: 35 | src: ./manual/static_dhcp_manual_restore.sh 36 | dest: /opt/vmware/nsx-bm/static_dhcp_manual_restore.sh 37 | owner: root 38 | group: root 39 | mode: 0755 40 | - name: create suse dhcp network configure file 41 | copy: 42 | src: templates/suse_dhcp_network_template.j2 43 | dest: /etc/sysconfig/network/ifcfg-{{ app_intf_name }} 44 | owner: root 45 | group: root 46 | mode: 0644 47 | when: os_type.stdout == "SUSE" 48 | - name: ifup application interface 49 | command: ifup {{ app_intf_name }} 50 | when: os_type.stdout == "SUSE" 51 | - name: config DHCP on App NIC 52 | command: dhclient -nw {{ app_intf_name }} 53 | when: os_type.stdout != "SUSE" 54 | - import_tasks: config/config.yml 55 | - name: create bootup script 56 | template: 57 | src: templates/bms_dhcp_init.j2 58 | dest: /etc/init.d/nsx-baremetal 59 | owner: root 60 | group: root 61 | mode: 0755 62 | - import_tasks: system/add_service_bootup.yml 63 | -------------------------------------------------------------------------------- /bms-ansible-nsx/hosts: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | 6 | # Create an group that contains the Bare Metal Servers 7 | [TransportNodes:children] 8 | servers_static 9 | servers_dhcp 10 | servers_migration 11 | 12 | # Set variables common for all Bare Metal Servers 13 | [TransportNodes:vars] 14 | # SSH user 15 | ansible_ssh_user= 16 | ansible_ssh_pass= 17 | 18 | rhel7_dependency=["tcpdump", "boost-filesystem", "PyYAML", "boost-iostreams", "boost-chrono", "python-mako", "python3-netaddr", "python-six", "gperftools-libs", "libunwind", "snappy", "boost-date-time", "c-ares", "redhat-lsb-core", "wget", "net-tools", "yum-utils", "lsof", "libvirt-libs", "python-gevent", "libev", "python-greenlet", "python3"] 19 | 20 | rhel8_dependency=["tcpdump", "boost-filesystem", "python3-pyyaml", "boost-iostreams", "boost-chrono", "python3-mako", "python3-netaddr", "python3-six", "snappy", "boost-date-time", "c-ares", "redhat-lsb-core", "wget", "net-tools", "yum-utils", "lsof", "libvirt-libs", "python3-gevent", "libev", "python3-greenlet", "python3", "libbpf"] 21 | 22 | ubuntu16_dependency=["libunwind8", "libgflags2v5", "libgoogle-perftools4", "traceroute", "python-mako", "python-simplejson", "python-unittest2", "python-yaml", "python-netaddr", "libboost-filesystem1.58.0", "libboost-chrono1.58.0", "libgoogle-glog0v5", "dkms", "libboost-date-time1.58.0", "python-protobuf", "python-gevent", "libsnappy1v5", "libleveldb1v5", "libboost-program-options1.58.0", "libboost-thread1.58.0", "libboost-iostreams1.58.0", "libvirt0", "libelf-dev"] 23 | 24 | ubuntu18_dependency=["traceroute", "python-mako", "python-netaddr", "python-simplejson", "python-unittest2", "python-yaml", "python-openssl", "dkms", "libvirt0", "libelf-dev"] 25 | 26 | suse12_dependency=["net-tools", "tcpdump", "python-simplejson", "python-netaddr", "python-PyYAML", "python-six", "libunwind", "wget", "libvirt-libs", "lsof", "libcap-progs"] 27 | 28 | # host group for servers 29 | [servers_static] 30 | server1 ansible_ssh_host= static_ip= netmask= ls_name= 31 | 32 | [servers_dhcp] 33 | #server6 ansible_ssh_host= ls_name= 34 | 35 | [servers_migration] 36 | #server6 ansible_ssh_host= migrate_intf= ls_name= 37 | 38 | [servers_restoration] 39 | #server6 40 | 41 | # NSX Configuration 42 | [NSX] 43 | #============================ 44 | # NSX Manager Credential 45 | nsxmanager ip= username= password= thumbprint= 46 | #============================ 47 | -------------------------------------------------------------------------------- /bms-ansible-nsx/auth/thumbprint_validate.py: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2019 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | from hashlib import sha256 6 | import importlib 7 | import ssl 8 | import sys 9 | import socket 10 | 11 | httplib_module = "http.client" if sys.version_info >= (3,) else "httplib" 12 | httplib = importlib.import_module(httplib_module) 13 | import traceback 14 | 15 | 16 | _OK = 0 17 | _ERROR_NOT_ENOUGH_ARGUMENTS_SPECIFIED = 1 18 | _ERROR_CONNECT_TO_MP_FAILURE = 2 19 | _ERROR_MP_THUMBPRINT_MISMATCH = 3 20 | _ERROR_UNABLE_TO_GET_THUMBPRINT = 4 21 | 22 | 23 | def thumbprint_validate(server, port, thumbprint): 24 | try: 25 | # Suppress default Python 2.7.9+ HTTPSConnection certificate and 26 | # hostname verification. Doing manual certificate thumbprint check 27 | # instead. 28 | if (sys.version_info >= (2, 7, 9) or 29 | "_create_unverified_context" in dir(ssl)): 30 | ctx = ssl._create_unverified_context() 31 | conn = httplib.HTTPSConnection( 32 | server, port, context=ctx, 33 | timeout=30) 34 | else: 35 | conn = httplib.HTTPSConnection( 36 | server, port, timeout=30) 37 | conn.connect() 38 | except socket.error as ex: 39 | sys.stderr.write( 40 | "ERROR: unable to connect to manager at %s:%s\n" % 41 | (server, port)) 42 | return _ERROR_CONNECT_TO_MP_FAILURE 43 | 44 | try: 45 | # Verify server thumbprint 46 | conn_thumbprint = sha256(conn.sock.getpeercert(True)).hexdigest() 47 | conn_thumbprint = conn_thumbprint.lower() 48 | if conn_thumbprint != thumbprint: 49 | sys.stderr.write("ERROR: manager thumbprint mismatch\n") 50 | return _ERROR_MP_THUMBPRINT_MISMATCH 51 | else: 52 | sys.stdout.write("OK: manager thumbprint match\n") 53 | except Exception: 54 | sys.stderr.write( 55 | "ERROR: unable to get thumbprint: %s\n" % 56 | traceback.format_exc()) 57 | return _ERROR_UNABLE_TO_GET_THUMBPRINT 58 | finally: 59 | if conn: 60 | conn.close() 61 | return _OK 62 | 63 | 64 | def main(argv): 65 | if len(argv) < 4: 66 | sys.stderr.write("ERROR: not enough arguments specified\n") 67 | return _ERROR_NOT_ENOUGH_ARGUMENTS_SPECIFIED 68 | 69 | server = argv[1] 70 | port = argv[2] 71 | thumbprint = argv[3] 72 | 73 | return thumbprint_validate(server, port, thumbprint) 74 | 75 | 76 | if __name__ == "__main__": 77 | sys.exit(main(sys.argv)) 78 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributing to bare-metal-server-integration-with-nsxt 4 | 5 | The bare-metal-server-integration-with-nsxt project team welcomes contributions from the community. Before you start working with bare-metal-server-integration-with-nsxt, please read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on as an open-source patch. 6 | 7 | ## Contribution Flow 8 | 9 | This is a rough outline of what a contributor's workflow looks like: 10 | 11 | - Create a topic branch from where you want to base your work 12 | - Make commits of logical units 13 | - Make sure your commit messages are in the proper format (see below) 14 | - Push your changes to a topic branch in your fork of the repository 15 | - Submit a pull request 16 | 17 | Example: 18 | 19 | ``` shell 20 | git remote add upstream https://github.com/vmware/bare-metal-server-integration-with-nsxt.git 21 | git checkout -b my-new-feature master 22 | git commit -a 23 | git push origin my-new-feature 24 | ``` 25 | 26 | ### Staying In Sync With Upstream 27 | 28 | When your branch gets out of sync with the vmware/master branch, use the following to update: 29 | 30 | ``` shell 31 | git checkout my-new-feature 32 | git fetch -a 33 | git pull --rebase upstream master 34 | git push --force-with-lease origin my-new-feature 35 | ``` 36 | 37 | ### Updating pull requests 38 | 39 | If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into 40 | existing commits. 41 | 42 | If your pull request contains a single commit or your changes are related to the most recent commit, you can simply 43 | amend the commit. 44 | 45 | ``` shell 46 | git add . 47 | git commit --amend 48 | git push --force-with-lease origin my-new-feature 49 | ``` 50 | 51 | If you need to squash changes into an earlier commit, you can use: 52 | 53 | ``` shell 54 | git add . 55 | git commit --fixup 56 | git rebase -i --autosquash master 57 | git push --force-with-lease origin my-new-feature 58 | ``` 59 | 60 | Be sure to add a comment to the PR indicating your new changes are ready to review, as GitHub does not generate a 61 | notification when you git push. 62 | 63 | ### Formatting Commit Messages 64 | 65 | We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/). 66 | 67 | Be sure to include any related GitHub issue references in the commit message. See 68 | [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) for referencing issues 69 | and commits. 70 | 71 | ## Reporting Bugs and Creating Issues 72 | 73 | When opening a new issue, try to roughly follow the commit message format conventions above. 74 | -------------------------------------------------------------------------------- /bms-ansible-nsx/migrate.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: servers_migration 7 | any_errors_fatal: true 8 | tasks: 9 | - name: config underlay mode 10 | set_fact: 11 | underlay_mode: 'true' 12 | FQDN: false 13 | - import_tasks: auth/manager_thumbprint_validate.yml 14 | - import_tasks: system/get_os_type.yml 15 | - import_tasks: config/tn_uuid.yml 16 | - import_tasks: config/fqdn.yml 17 | - import_tasks: lsp/check_legacy_lsp.yml 18 | - import_tasks: lsp/vif_id.yml 19 | - import_tasks: validation/vlan_0_ls_check.yml 20 | - import_tasks: vif/int_br_name.yml 21 | - import_tasks: validation/vif_id_check.yml 22 | - import_tasks: validation/migration_input_check.yml 23 | - import_tasks: config/app_intf_name.yml 24 | - import_tasks: lsp/create_lsp.yml 25 | - import_tasks: lsp/save_lsp_id.yml 26 | - import_tasks: config/bms_config.yml 27 | when: not FQDN 28 | - name: generate config file 29 | block: 30 | - name: remove old config file 31 | file: 32 | path: /etc/vmware/nsx-bm/bms.conf 33 | state: absent 34 | - name: create directory 35 | file: 36 | path: /etc/vmware/nsx-bm 37 | state: directory 38 | mode: 0755 39 | - name: create bm dir 40 | file: 41 | path: /opt/vmware/nsx-bm 42 | state: directory 43 | mode: 0755 44 | - name: create debug script 45 | copy: 46 | src: ./debug/debug.sh 47 | dest: /opt/vmware/nsx-bm/debug.sh 48 | owner: root 49 | group: root 50 | mode: 0755 51 | - name: create manual restore script 52 | copy: 53 | src: ./manual/migration_manual_restore.sh 54 | dest: /opt/vmware/nsx-bm/migration_manual_restore.sh 55 | owner: root 56 | group: root 57 | mode: 0755 58 | - name: create route script 59 | template: 60 | src: route/route.j2 61 | dest: /opt/vmware/nsx-bm/route.sh 62 | owner: root 63 | group: root 64 | mode: 0755 65 | - name: create migrate script part 1 66 | template: 67 | src: templates/bms_migrate.j2 68 | dest: /tmp/bms_migrate.sh 69 | owner: root 70 | group: root 71 | mode: 0755 72 | - name: create migrate script part 2 73 | template: 74 | src: templates/migrate.j2 75 | dest: /tmp/migrate.sh 76 | owner: root 77 | group: root 78 | mode: 0755 79 | - name: create revert script 80 | template: 81 | src: templates/revert.j2 82 | dest: /tmp/revert.sh 83 | owner: root 84 | group: root 85 | mode: 0755 86 | - name: create bootup script 87 | template: 88 | src: templates/bms_migrate_init.j2 89 | dest: /etc/init.d/nsx-baremetal 90 | owner: root 91 | group: root 92 | mode: 0755 93 | - import_tasks: system/add_service_bootup.yml 94 | - name: Run migrate script 95 | shell: /tmp/bms_migrate.sh >> /var/log/migrate.log 2>&1 96 | register: migrate_result 97 | ignore_errors: yes 98 | - debug: msg="{{migrate_result.rc}}" 99 | - debug: msg="maigrate failed, pls. check /var/log/migrate.log" 100 | when: migrate_result.rc != 0 101 | - name: show log 102 | shell: cat /var/log/migrate.log 103 | register: migrate_log_output 104 | - debug: msg="{{migrate_log_output.stdout}}" 105 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/revert.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | BMS_CMT_PREFIX="##BMS " 7 | NSX_ETH={{ app_intf_name }} 8 | NSX_ETH_PEER=$NSX_ETH"-peer" 9 | BMS_CONFIG_FILE="/etc/vmware/nsx-bm/bms.conf" 10 | 11 | 12 | ip_address= 13 | netmask= 14 | gateway= 15 | migrate_mac= 16 | defaultGatewayIp= 17 | defaultGatewayDev= 18 | config_mode= 19 | migrate_interface= 20 | isStatic= 21 | 22 | nsx_bm_log() { 23 | echo "${1}" 24 | logger -p daemon.info -t NSX-BMS "${1}" 25 | } 26 | 27 | get_os_type() { 28 | host_os=$(lsb_release -si) 29 | nsx_bm_log "host_os: $host_os" 30 | if isRhel; then 31 | nsx_bm_log "RHEL OS" 32 | elif isUbuntu; then 33 | nsx_bm_log "UBUNTU OS" 34 | elif isSUSE; then 35 | nsx_bm_log "SUSE OS" 36 | else 37 | nsx_bm_log "unkown OS, abort" 38 | exit 1 39 | fi 40 | } 41 | 42 | isSUSE() { 43 | if [ "$host_os" == "SUSE" ]; then 44 | return 0 45 | fi 46 | return 1 47 | } 48 | 49 | isRhel() { 50 | if [ "$host_os" == "RedHatEnterpriseServer" ]; then 51 | return 0 52 | fi 53 | if [ "$host_os" == "RedHatEnterprise" ]; then 54 | return 0 55 | fi 56 | if [ "$host_os" == "CentOS" ]; then 57 | return 0 58 | fi 59 | if [ "$host_os" == "OracleServer" ]; then 60 | return 0 61 | fi 62 | return 1 63 | } 64 | 65 | isUbuntu() { 66 | if [ "$host_os" == "Ubuntu" ]; then 67 | return 0 68 | fi 69 | return 1 70 | } 71 | 72 | restore_ifcfg_file() { 73 | local intf_name=$1 74 | if isRhel; then 75 | ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-"$intf_name 76 | elif isUbuntu; then 77 | ifcfg_file="/etc/network/interfaces" 78 | elif isSUSE; then 79 | ifcfg_file="/etc/sysconfig/network/ifcfg-"$intf_name 80 | nsx-eth-ifcfg_file="/etc/sysconfig/network/ifcfg-"$NSX_ETH 81 | rm $nsx-eth-ifcfg_file 82 | else 83 | nsx_bm_log "unkown OS, abort" 84 | exit 1 85 | fi 86 | 87 | nsx_bm_log "ifcfg_file: $ifcfg_file" 88 | 89 | sed -i "s/^$BMS_CMT_PREFIX//g" $ifcfg_file 90 | } 91 | 92 | 93 | parse_bms_config() { 94 | if [ ! -f $BMS_CONFIG_FILE ]; then 95 | nsx_bm_log "ERROR: BMS config file not found" 96 | exit 1 97 | fi 98 | 99 | while read line 100 | do 101 | output=($(echo $line | awk -F'=' '{print $1,$2}')) 102 | key="${output[0]}" 103 | value="${output[1]}" 104 | if [ "$key" == "config_mode" ]; then 105 | config_mode=$value 106 | elif [ "$key" == "migrate_interface" ]; then 107 | migrate_interface=$value 108 | elif [ "$key" == "isStatic" ]; then 109 | isStatic=$value 110 | elif [ "$key" == "defaultGatewayIp" ]; then 111 | defaultGatewayIp=$value 112 | elif [ "$key" == "defaultGatewayDev" ]; then 113 | defaultGatewayDev=$value 114 | fi 115 | done < $BMS_CONFIG_FILE 116 | } 117 | 118 | delete_nsx_bms_config() { 119 | rm -rf $BMS_CONFIG_DIR 120 | } 121 | 122 | echo "=============================" 123 | echo "revert start...." 124 | date 125 | get_os_type 126 | parse_bms_config 127 | nsx_bm_log "config_mode: $config_mode" 128 | nsx_bm_log "migrate_interface: $migrate_interface" 129 | nsx_bm_log "isStatic: $isStatic" 130 | 131 | if [ "$config_mode" != "migrate" ]; then 132 | nsx_bm_log "config mode is not migration, exit" 133 | exit 134 | fi 135 | 136 | ifdown $NSX_ETH 137 | ovs-vsctl del-port $NSX_ETH_PEER 138 | 139 | restore_ifcfg_file $migrate_interface 140 | 141 | if [ "$isStatic" = false ]; then 142 | dhclient -r $NSX_ETH 143 | fi 144 | 145 | ip link delete $NSX_ETH 146 | ifup $migrate_interface 147 | 148 | if [ "$migrate_interface" == "$defaultGatewayDev" ]; then 149 | route add default gw $defaultGatewayIp 150 | fi 151 | 152 | delete_nsx_bms_config 153 | echo "revert done" 154 | 155 | -------------------------------------------------------------------------------- /bms-ansible-nsx/manual/migration_manual_restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | if (($# > 1)); then 9 | echo "Too many parameters: $@" 10 | exit 11 | elif [ $# -eq 1 ]; then 12 | app_intf_name=$1 13 | else 14 | app_intf_name=nsx-eth 15 | fi 16 | 17 | BMS_CMT_PREFIX="##BMS " 18 | NSX_ETH=$app_intf_name 19 | NSX_ETH_PEER=$NSX_ETH"-peer" 20 | BMS_CONFIG_FILE="/etc/vmware/nsx-bm/bms.conf" 21 | 22 | 23 | ip_address= 24 | netmask= 25 | gateway= 26 | migrate_mac= 27 | defaultGatewayIp= 28 | defaultGatewayDev= 29 | config_mode= 30 | migrate_interface= 31 | isStatic= 32 | 33 | nsx_bm_log() { 34 | echo "${1}" 35 | logger -p daemon.info -t NSX-BMS "${1}" 36 | } 37 | 38 | get_os_type() { 39 | host_os=$(lsb_release -si) 40 | nsx_bm_log "host_os: $host_os" 41 | if isRhel; then 42 | nsx_bm_log "RHEL OS" 43 | elif isUbuntu; then 44 | nsx_bm_log "UBUNTU OS" 45 | else 46 | nsx_bm_log "unkown OS, abort" 47 | exit 1 48 | fi 49 | } 50 | 51 | isRhel() { 52 | if [ "$host_os" == "RedHatEnterpriseServer" ]; then 53 | return 0 54 | fi 55 | if [ "$host_os" == "RedHatEnterprise" ]; then 56 | return 0 57 | fi 58 | if [ "$host_os" == "CentOS" ]; then 59 | return 0 60 | fi 61 | if [ "$host_os" == "OracleServer" ]; then 62 | return 0 63 | fi 64 | return 1 65 | } 66 | 67 | isUbuntu() { 68 | if [ "$host_os" == "Ubuntu" ]; then 69 | return 0 70 | fi 71 | return 1 72 | } 73 | 74 | restore_ifcfg_file() { 75 | local intf_name=$1 76 | if isRhel; then 77 | ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-"$intf_name 78 | elif isUbuntu; then 79 | ifcfg_file="/etc/network/interfaces" 80 | else 81 | nsx_bm_log "unkown OS, abort" 82 | exit 1 83 | fi 84 | 85 | nsx_bm_log "ifcfg_file: $ifcfg_file" 86 | 87 | sed -i "s/^$BMS_CMT_PREFIX//g" $ifcfg_file 88 | } 89 | 90 | 91 | parse_bms_config() { 92 | if [ ! -f $BMS_CONFIG_FILE ]; then 93 | nsx_bm_log "ERROR: BMS config file not found" 94 | exit 1 95 | fi 96 | 97 | while read line 98 | do 99 | output=($(echo $line | awk -F'=' '{print $1,$2}')) 100 | key="${output[0]}" 101 | value="${output[1]}" 102 | if [ "$key" == "config_mode" ]; then 103 | config_mode=$value 104 | elif [ "$key" == "migrate_interface" ]; then 105 | migrate_interface=$value 106 | elif [ "$key" == "isStatic" ]; then 107 | isStatic=$value 108 | elif [ "$key" == "defaultGatewayIp" ]; then 109 | defaultGatewayIp=$value 110 | elif [ "$key" == "defaultGatewayDev" ]; then 111 | defaultGatewayDev=$value 112 | fi 113 | done < $BMS_CONFIG_FILE 114 | } 115 | 116 | delete_nsx_bms_config() { 117 | rm -rf $BMS_CONFIG_DIR 118 | } 119 | 120 | get_os_type 121 | parse_bms_config 122 | nsx_bm_log "config_mode: $config_mode" 123 | nsx_bm_log "migrate_interface: $migrate_interface" 124 | nsx_bm_log "isStatic: $isStatic" 125 | 126 | if [ "$config_mode" != "migrate" ]; then 127 | nsx_bm_log "config mode is not migration, exit" 128 | exit 129 | fi 130 | 131 | ovs-vsctl del-port $NSX_ETH_PEER 132 | 133 | restore_ifcfg_file $migrate_interface 134 | 135 | if [ "$isStatic" = false ]; then 136 | dhclient -r $NSX_ETH 137 | fi 138 | 139 | ip link delete $NSX_ETH 140 | ifup $migrate_interface 141 | 142 | if [ "$migrate_interface" == "$defaultGatewayDev" ]; then 143 | route add default gw $defaultGatewayIp 144 | fi 145 | 146 | if isRhel; then 147 | chkconfig --del nsx-baremetal 148 | elif isUbuntu; then 149 | update-rc.d -f nsx-baremetal remove 150 | fi 151 | 152 | 153 | delete_nsx_bms_config 154 | 155 | rm -f /etc/init.d/nsx-baremetal 156 | rm -f /etc/vmware/nsx/nsx-baremetal.xml 157 | /etc/init.d/nsx-agent restart 158 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/bms_migrate_restore.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | BMS_CMT_PREFIX="##BMS " 7 | NSX_ETH={{ app_intf_name }} 8 | NSX_ETH_PEER=$NSX_ETH"-peer" 9 | BMS_CONFIG_FILE="/etc/vmware/nsx-bm/bms.conf" 10 | 11 | 12 | ip_address= 13 | netmask= 14 | gateway= 15 | migrate_mac= 16 | defaultGatewayIp= 17 | defaultGatewayDev= 18 | config_mode= 19 | migrate_interface= 20 | isStatic= 21 | 22 | nsx_bm_log() { 23 | echo "${1}" 24 | logger -p daemon.info -t NSX-BMS "${1}" 25 | } 26 | 27 | get_os_type() { 28 | host_os=$(lsb_release -si) 29 | nsx_bm_log "host_os: $host_os" 30 | if isRhel; then 31 | nsx_bm_log "RHEL OS" 32 | elif isUbuntu; then 33 | nsx_bm_log "UBUNTU OS" 34 | elif isSUSE; then 35 | nsx_bm_log "SUSE OS" 36 | else 37 | nsx_bm_log "unkown OS, abort" 38 | exit 1 39 | fi 40 | } 41 | 42 | isSUSE() { 43 | if [ "$host_os" == "SUSE" ]; then 44 | return 0 45 | fi 46 | return 1 47 | } 48 | 49 | isRhel() { 50 | if [ "$host_os" == "RedHatEnterpriseServer" ]; then 51 | return 0 52 | fi 53 | if [ "$host_os" == "RedHatEnterprise" ]; then 54 | return 0 55 | fi 56 | if [ "$host_os" == "CentOS" ]; then 57 | return 0 58 | fi 59 | if [ "$host_os" == "OracleServer" ]; then 60 | return 0 61 | fi 62 | return 1 63 | } 64 | 65 | isUbuntu() { 66 | if [ "$host_os" == "Ubuntu" ]; then 67 | return 0 68 | fi 69 | return 1 70 | } 71 | 72 | restore_ifcfg_file() { 73 | local intf_name=$1 74 | if isRhel; then 75 | ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-"$intf_name 76 | rm -f /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 77 | elif isUbuntu; then 78 | ifcfg_file="/etc/network/interfaces" 79 | elif isSUSE; then 80 | ifcfg_file="/etc/sysconfig/network/ifcfg-"$intf_name 81 | nsx-eth-ifcfg_file="/etc/sysconfig/network/ifcfg-"$NSX_ETH 82 | rm $nsx-eth-ifcfg_file 83 | else 84 | nsx_bm_log "unkown OS, abort" 85 | exit 1 86 | fi 87 | 88 | nsx_bm_log "ifcfg_file: $ifcfg_file" 89 | 90 | if isUbuntu; then 91 | sed -i "/$NSX_ETH/d" $ifcfg_file 92 | fi 93 | sed -i "s/^$BMS_CMT_PREFIX//g" $ifcfg_file 94 | } 95 | 96 | 97 | parse_bms_config() { 98 | if [ ! -f $BMS_CONFIG_FILE ]; then 99 | nsx_bm_log "ERROR: BMS config file not found" 100 | exit 1 101 | fi 102 | 103 | while read line 104 | do 105 | output=($(echo $line | awk -F'=' '{print $1,$2}')) 106 | key="${output[0]}" 107 | value="${output[1]}" 108 | if [ "$key" == "config_mode" ]; then 109 | config_mode=$value 110 | elif [ "$key" == "migrate_interface" ]; then 111 | migrate_interface=$value 112 | elif [ "$key" == "isStatic" ]; then 113 | isStatic=$value 114 | elif [ "$key" == "defaultGatewayIp" ]; then 115 | defaultGatewayIp=$value 116 | elif [ "$key" == "defaultGatewayDev" ]; then 117 | defaultGatewayDev=$value 118 | fi 119 | done < $BMS_CONFIG_FILE 120 | } 121 | 122 | delete_nsx_bms_config() { 123 | rm -rf $BMS_CONFIG_DIR 124 | } 125 | 126 | echo "=============================" 127 | date 128 | ifconfig 129 | get_os_type 130 | parse_bms_config 131 | nsx_bm_log "config_mode: $config_mode" 132 | nsx_bm_log "migrate_interface: $migrate_interface" 133 | nsx_bm_log "isStatic: $isStatic" 134 | 135 | if [ "$config_mode" != "migrate" ]; then 136 | nsx_bm_log "config mode is not migration, exit" 137 | exit 138 | fi 139 | 140 | ifdown $NSX_ETH 141 | ovs-vsctl del-port $NSX_ETH_PEER 142 | 143 | restore_ifcfg_file $migrate_interface 144 | 145 | if [ "$isStatic" = false ]; then 146 | dhclient -r $NSX_ETH 147 | fi 148 | 149 | ip link delete $NSX_ETH 150 | ifup $migrate_interface 151 | 152 | if [ "$migrate_interface" == "$defaultGatewayDev" ]; then 153 | route add default gw $defaultGatewayIp 154 | fi 155 | 156 | delete_nsx_bms_config 157 | ifconfig 158 | 159 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/bms_migrate_init.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | # 6 | # nsx-baremetal-server 7 | # 8 | # chkconfig: 2345 08 92 9 | # description: 10 | 11 | # 12 | ### BEGIN INIT INFO 13 | # Provides: nsx-baremetal-server 14 | # Required-Start: 15 | # Required-Stop: 16 | # Default-Start: 2 3 4 5 17 | # Default-Stop: 0 1 6 18 | # Short-Description: nsx-baremetal-server 19 | ### END INIT INFO 20 | 21 | 22 | BMS_CONFIG_FILE="/etc/vmware/nsx-bm/bms.conf" 23 | 24 | config_mode= 25 | migrate_interface= 26 | isStatic= 27 | ip_address= 28 | netmask= 29 | prefix= 30 | gateway= 31 | migrate_mac= 32 | defaultGatewayIp= 33 | defaultGatewayDev= 34 | 35 | 36 | nsx_bm_log() { 37 | echo "${1}" 38 | logger -p daemon.info -t NSX-BMS "${1}" 39 | } 40 | 41 | get_os_type() { 42 | host_os=$(lsb_release -si) 43 | nsx_log "host_os: $host_os" 44 | } 45 | 46 | isSUSE() { 47 | if [ "$host_os" == "SUSE" ]; then 48 | return 0 49 | fi 50 | return 1 51 | } 52 | 53 | parse_bms_config() { 54 | if [ ! -f $BMS_CONFIG_FILE ]; then 55 | nsx_bm_log "ERROR: BMS config file not found" 56 | exit 1 57 | fi 58 | 59 | while read line 60 | do 61 | output=($(echo $line | awk -F'=' '{print $1,$2}')) 62 | key="${output[0]}" 63 | value="${output[1]}" 64 | if [ "$key" == "config_mode" ]; then 65 | config_mode=$value 66 | elif [ "$key" == "migrate_interface" ]; then 67 | migrate_interface=$value 68 | elif [ "$key" == "isStatic" ]; then 69 | isStatic=$value 70 | elif [ "$key" == "ip_address" ]; then 71 | ip_address=$value 72 | elif [ "$key" == "netmask" ]; then 73 | netmask=$value 74 | elif [ "$key" == "prefix" ]; then 75 | prefix=$value 76 | elif [ "$key" == "gateway" ]; then 77 | gateway=$value 78 | elif [ "$key" == "migrate_mac" ]; then 79 | migrate_mac=$value 80 | elif [ "$key" == "defaultGatewayIp" ]; then 81 | defaultGatewayIp=$value 82 | elif [ "$key" == "defaultGatewayDev" ]; then 83 | defaultGatewayDev=$value 84 | fi 85 | done < $BMS_CONFIG_FILE 86 | 87 | nsx_bm_log "config_mode: $config_mode" 88 | nsx_bm_log "migrate_interface: $migrate_interface" 89 | nsx_bm_log "isStatic: $isStatic" 90 | nsx_bm_log "ip_address: $ip_address" 91 | nsx_bm_log "netmask: $netmask" 92 | nsx_bm_log "prefix: $prefix" 93 | nsx_bm_log "gateway: $gateway" 94 | nsx_bm_log "migrate_mac: $migrate_mac" 95 | nsx_bm_log "defaultGatewayIp: $defaultGatewayIp" 96 | nsx_bm_log "defaultGatewayDev: $defaultGatewayDev" 97 | } 98 | 99 | start() { 100 | nsx_bm_log "nsx bare metal start" 101 | parse_bms_config 102 | 103 | ip link add {{ app_intf_name }} type veth peer name {{ app_intf_name }}-peer 104 | ip link set dev {{ app_intf_name }} address $migrate_mac 105 | ifconfig {{ app_intf_name }} up 106 | ifconfig {{ app_intf_name }}-peer up 107 | 108 | ovs-vsctl --timeout=5 -- --if-exists del-port {{ app_intf_name }}-peer -- add-port nsx-managed {{ app_intf_name }}-peer \ 109 | -- set Interface {{ app_intf_name }}-peer external-ids:attached-mac=$migrate_mac \ 110 | external-ids:iface-id={{ vif_id }} external-ids:iface-status=active 111 | 112 | if [ "$isStatic" = true ]; then 113 | if [ ! -z "$netmask" ]; then 114 | ifconfig {{ app_intf_name }} $ip_address netmask $netmask up 115 | elif [ ! -z "$prefix" ]; then 116 | ifconfig {{ app_intf_name }} $ip_address/$prefix 117 | else 118 | ifconfig {{ app_intf_name }} $ip_address 119 | fi 120 | if [ ! -z "$gateway" ]; then 121 | ip route add default via $gateway dev {{ app_intf_name }} 122 | fi 123 | if [ "$migrate_interface" == "$defaultGatewayDev" ]; then 124 | route add default gw $defaultGatewayIp 125 | fi 126 | else 127 | if isSUSE; then 128 | ifup {{ app_intf_name }} 129 | else 130 | dhclient -nw {{ app_intf_name }} 131 | fi 132 | fi 133 | bash /opt/vmware/nsx-bm/route.sh 134 | } 135 | 136 | case "${1}" in 137 | "start") 138 | start 139 | ;; 140 | *) 141 | exit 1 142 | ;; 143 | esac 144 | -------------------------------------------------------------------------------- /bms-ansible-nsx/README.md: -------------------------------------------------------------------------------- 1 | # Ansbile for Bare Metal Server 2 | Ansible for Bare Metal Server is a set of automated scripts to setup Application 3 | Interface for Bare Metal Server; 4 | 5 | # Support Modes 6 | 1. Static 7 | Enable static configuration on Application Interface; 8 | 9 | 2. Dhcp 10 | Enable dhcp configuration on Application Interface; 11 | 12 | 3. Migration 13 | This mode supports Management and Application sharing the same IP; 14 | Enable migration mode on Application Interface; Also named as “underlay mode” or 15 | "VLAN-0 mode"; 16 | 17 | # WARNING 18 | For this configure script, it will call NSX Manager REST APIs; To authenticate a request using HTTP Basic authentication, 19 | user need to provider username and password in Ansible Inventory file(hosts) for authentication; 20 | 21 | From security perspective, PLS. NOTE this action and protect username and password by themselves; 22 | 23 | # Usage 24 | 25 | ### 1. Static 26 | #### Host group name: servers_static 27 | 28 | #### Configuration Parameters 29 | 30 | Parameter | requirement | description | example 31 | ---|---|---|--- 32 | static_ip | required | static ip address of app | static_ip=192.1.1.21 33 | netmask | required | netmask | netmask=255.255.255.0 34 | ls_id or ls_name | required | logical switch id or name | ls_id=dc97de40-b476-4698-a590-0a8c60100ac5 or ls_name=vlan_ls 35 | mac_address | optional | mac address of app's interface, random by default | mac_address=11:22:33:44:55:66 36 | app_intf_name | optional | app interface name, "nsx-eth" by default | app_intf_name="nsx-eth" 37 | routing_table | optional | routing table; | routing_table='["-net 101.20.0.0/16", "-net 100.20.20.0/24"]' 38 | 39 | #### Command 40 | ```bash 41 | $ansible-playbook -i hosts static_config.yml 42 | ``` 43 | 44 | #### routing table syntax 45 | Iface of each entry in routing table is app_intf_name. 46 | ```bash 47 | [-net|-host] target [netmask Nm] [gw Gw] [metric N] i [mss M] [window W] [irtt m] [reject] [mod] [dyn] [reinstate] 48 | ``` 49 | 50 | ### 2. DHCP 51 | #### Host group name: servers_dhcp 52 | 53 | #### Configuration Parameters 54 | 55 | |Parameter | requirement | description| example | 56 | |---|---|---|---| 57 | |ls_id or ls_name | required | logical switch id or name | ls_id=dc97de40-b476-4698-a590-0a8c60100ac5 or ls_name=vlan_ls | 58 | |mac_address | optional | mac address of app's interface, random by default| mac_address="11:22:33:44:55:66 | 59 | |app_intf_name | optional | app interface name, "nsx-eth" by default| app_intf_name="nsx-eth" | 60 | |routing_table | optional | routing table | routing_table='["-net 101.20.0.0/16", "-net 100.20.20.0/24"]' | 61 | 62 | #### Command 63 | ```bash 64 | $ansible-playbook -i hosts dhcp_config.yml 65 | ``` 66 | 67 | ### 3. Migration 68 | #### Host group name: servers_migration 69 | 70 | #### Configuration Parameters 71 | 72 | Parameter | requirement | description | example 73 | ---|---|---|--- 74 | ls_id or ls_name | required | logical switch id or name | ls_id=dc97de40-b476-4698-a590-0a8c60100ac5 or ls_name=vlan_ls 75 | migrate_intf | required | interface name needs to be migrated | migrate_intf="eth0" 76 | app_intf_name | optional | app interface name, "nsx-eth" by default | app_intf_name="nsx-eth" 77 | 78 | #### Command 79 | ```bash 80 | $ansible-playbook -i hosts migrate.yml 81 | ``` 82 | 83 | ### 4. Restoration 84 | ```bash 85 | $ansible-playbook -i hosts restore.yml 86 | ``` 87 | 88 | ### 5. Bootstrap flow in underlay mode 89 | In underlay mode, since management and application traffic share a single IP, we need a way to differentiate the forwarding of the types of traffic, and the management traffic should bypass NSX logical pipeline, otherwise any misconfiguration of NSX networking and policies will cause connectivity loss of the Bare Metal server and could not be recovered. 90 | So here we add high priority flows(classified by remote IP, proto, local/remote ports) for the management traffic when setup application interface, we call high priority flow as bootstrap flow; 91 | NSX Manager and Controller endpoints will be loaded in bootstrap flow by default; 92 | If Manager/Controller endpoint is FQDN, that won't support bootstrap flow. 93 | 94 | If User want to add/delete/update bootstrap flow, pls. follow below steps: 95 | ```bash 96 | 1. update "templates/nsx-baremetal.j2"; 97 | 2. $ansible-playbook -i hosts config/bms_update.yml 98 | ``` 99 | 100 | 101 | ### 6. Prepare host with dependency package 102 | ```bash 103 | $ansible-playbook -i hosts prepare.yml 104 | ``` 105 | ### 7. Remove dependency which are installed during prepare phase 106 | ```bash 107 | $ansible-playbook -i hosts unprepare.yml 108 | ``` 109 | 110 | ### 8. Troubleshooting 111 | 1. Ansible depends on python-selinux on SE enabled Linux hosts. On some platforms ansible might report the error: Aborting, target uses selinux but python bindings (libselinux-python) aren't installed! 112 | There are two ways to fix the error: 113 | a. Disable SELinux on the Linux hosts. 114 | b. If python-selinux was installed on the host and ansible still reports this error, it might be caused by python version incompitable. Following the KB to fix the python version issue: https://access.redhat.com/solutions/5674911. 115 | -------------------------------------------------------------------------------- /bms-ansible-nsx/prepare.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ### Copyright (C) 2018 VMware, Inc. All rights reserved. 3 | ### SPDX-License-Identifier: BSD-2-Clause 4 | ################################################################################ 5 | --- 6 | - hosts: TransportNodes 7 | tasks: 8 | - name: is ubuntu 9 | stat: 10 | path: /etc/lsb-release 11 | register: ubuntu_stat_result 12 | - name: is rhel 13 | stat: 14 | path: /etc/redhat-release 15 | register: rhel_stat_result 16 | - name: is suse 17 | stat: 18 | path: /etc/SuSE-release 19 | register: suse_stat_result 20 | - name: get lsb-release 21 | command: cat /etc/lsb-release 22 | register: ubuntu_version 23 | when: ubuntu_stat_result.stat.exists == True 24 | - name: get redhat release 25 | command: cat /etc/redhat-release 26 | register: redhat_version 27 | when: rhel_stat_result.stat.exists == True 28 | - name: create check rhel7 dependency script 29 | template: 30 | src: templates/check_rhel7_dependency.j2 31 | dest: /tmp/check_rhel7_dependency.sh 32 | owner: root 33 | group: root 34 | mode: 0755 35 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 7") != -1) 36 | - name: create check rhel8 dependency script 37 | template: 38 | src: templates/check_rhel8_dependency.j2 39 | dest: /tmp/check_rhel8_dependency.sh 40 | owner: root 41 | group: root 42 | mode: 0755 43 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 8") != -1) 44 | - name: create check suse dependency script 45 | template: 46 | src: templates/check_suse_dependency.j2 47 | dest: /tmp/check_suse_dependency.sh 48 | owner: root 49 | group: root 50 | mode: 0755 51 | when: suse_stat_result.stat.exists == True 52 | - name: create check ubuntu16 dependency script 53 | template: 54 | src: templates/check_ubuntu16_dependency.j2 55 | dest: /tmp/check_ubuntu16_dependency.sh 56 | owner: root 57 | group: root 58 | mode: 0755 59 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=16") != -1) 60 | - name: create check ubuntu18 dependency script 61 | template: 62 | src: templates/check_ubuntu18_dependency.j2 63 | dest: /tmp/check_ubuntu18_dependency.sh 64 | owner: root 65 | group: root 66 | mode: 0755 67 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=18") != -1) 68 | - name: run check rhel7 dependency script 69 | command: bash /tmp/check_rhel7_dependency.sh 70 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 7") != -1) 71 | - name: run check rhel8 dependency script 72 | command: bash /tmp/check_rhel8_dependency.sh 73 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 8") != -1) 74 | - name: run check suse dependency script 75 | command: bash /tmp/check_suse_dependency.sh 76 | when: suse_stat_result.stat.exists == True 77 | - name: run check ubuntu16 dependency script 78 | command: bash /tmp/check_ubuntu16_dependency.sh 79 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=16") != -1) 80 | - name: run check ubuntu18 dependency script 81 | command: bash /tmp/check_ubuntu18_dependency.sh 82 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=18") != -1) 83 | - name: set rhel7 dependency 84 | set_fact: 85 | dependency: "{{ rhel7_dependency }}" 86 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 7") != -1) 87 | - name: set rhel8 dependency 88 | set_fact: 89 | dependency: "{{ rhel8_dependency }}" 90 | when: (rhel_stat_result.stat.exists == True) and (redhat_version.stdout.find("release 8") != -1) 91 | - name: set ubuntu16 dependency 92 | set_fact: 93 | dependency: "{{ ubuntu16_dependency }}" 94 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=16") != -1) 95 | - name: set ubuntu18 dependency 96 | set_fact: 97 | dependency: "{{ ubuntu18_dependency }}" 98 | when: (ubuntu_stat_result.stat.exists == True) and (ubuntu_version.stdout.find("=18") != -1) 99 | - name: set suse dependency 100 | set_fact: 101 | dependency: "{{ suse12_dependency }}" 102 | when: (suse_stat_result.stat.exists == True) 103 | - name: install rhel or debian dependency 104 | package: 105 | name: "{{ item }}" 106 | state: present 107 | with_items: "{{ dependency }}" 108 | when: (ubuntu_stat_result.stat.exists == True) or (rhel_stat_result.stat.exists == True) 109 | - name: install suse dependency 110 | zypper: 111 | name: "{{ dependency }}" 112 | state: present 113 | when: (suse_stat_result.stat.exists == True) 114 | -------------------------------------------------------------------------------- /bms-ansible-nsx/templates/migrate.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (C) 2018 VMware, Inc. All rights reserved. 4 | # SPDX-License-Identifier: BSD-2-Clause 5 | 6 | NSX_ETH={{ app_intf_name }} 7 | APP_VIF_ID={{ vif_id }} 8 | MigratePnicName={{ migrate_intf }} 9 | 10 | STOP_DHCLIENT_SCRIPT="/etc/vmware/nsx-opsagent/dhclient-stop " 11 | IFCFG_FILE_UBUNTU="/etc/network/interfaces" 12 | BMS_CONFIG_DIR="/etc/vmware/nsx-bm" 13 | BMS_CONFIG_FILE="/etc/vmware/nsx-bm/bms.conf" 14 | BMS_CMT_PREFIX="##BMS " 15 | 16 | NSX_ETH_PEER=$NSX_ETH"-peer" 17 | 18 | # ConfigMode: "dhcp" "static" "migrate" 19 | ConfigMode="migrate" 20 | BridgeIntfPrefix="~" 21 | SUSEBridgeIntfPrefix="nsx_" 22 | MigrateBridgeIntfName= 23 | isStatic=true 24 | isIpConfigured=false 25 | interfaceStatus= 26 | ip_address= 27 | netmask= 28 | prefix= 29 | gateway= 30 | migrate_mac= 31 | defaultGatewayIp= 32 | defaultGatewayDev= 33 | host_os= 34 | 35 | nsx_bm_log() { 36 | echo "${1}" 37 | logger -p daemon.info -t NSX-BMS "${1}" 38 | } 39 | 40 | get_os_type() { 41 | host_os=$(lsb_release -si) 42 | nsx_bm_log "host_os: $host_os" 43 | } 44 | 45 | isRhel() { 46 | if [ "$host_os" == "RedHatEnterpriseServer" ]; then 47 | return 0 48 | fi 49 | if [ "$host_os" == "RedHatEnterprise" ]; then 50 | return 0 51 | fi 52 | if [ "$host_os" == "CentOS" ]; then 53 | return 0 54 | fi 55 | if [ "$host_os" == "OracleServer" ]; then 56 | return 0 57 | fi 58 | return 1 59 | } 60 | 61 | isUbuntu() { 62 | if [ "$host_os" == "Ubuntu" ]; then 63 | return 0 64 | fi 65 | return 1 66 | } 67 | 68 | isSUSE() { 69 | if [ "$host_os" == "SUSE" ]; then 70 | return 0 71 | fi 72 | return 1 73 | } 74 | 75 | get_migrate_bridge_intf_name() { 76 | if isSUSE; then 77 | MigrateBridgeIntfName=$SUSEBridgeIntfPrefix$MigratePnicName 78 | else 79 | MigrateBridgeIntfName=$BridgeIntfPrefix$MigratePnicName 80 | fi 81 | } 82 | 83 | GetDefaultRoute() { 84 | output=($(route -n | grep "^0.0.0.0" | awk {'print $8, $2'})) 85 | defaultGatewayDev="${output[0]}" 86 | defaultGatewayIp="${output[1]}" 87 | nsx_bm_log "defaultGatewayIp: $defaultGatewayIp" 88 | nsx_bm_log "defaultGatewayDev: $defaultGatewayDev" 89 | } 90 | 91 | get_interface_status() { 92 | #$1: nic name 93 | local intf_name=$1 94 | nsx_bm_log "get interface $intf_name's status" 95 | ret=$(ls /sys/class/net/$intf_name 2>&1) 96 | match=$(echo $ret | grep "No such file") 97 | if [ ! -z "$match" ]; then 98 | nsx_bm_log "interface $intf_name not exist" 99 | interfaceStatus="not-found" 100 | exit 1 101 | fi 102 | 103 | up=$(ifconfig $intf_name |grep "UP") 104 | if [ -z "$up" ]; then 105 | interfaceStatus="down" 106 | return 107 | fi 108 | 109 | ip=$(ifconfig $intf_name |grep inet |grep -v inet6|awk '{print $2}'|tr -d "addr:") 110 | nsx_bm_log "ip: $ip" 111 | if [ ! -z "$ip" ]; then 112 | interfaceStatus="l3up" 113 | else 114 | interfaceStatus="l2up" 115 | fi 116 | } 117 | 118 | 119 | get_nic_ip_config_spec() { 120 | if isRhel || isSUSE; then 121 | get_rhel_nic_ip_config_spec $1 122 | elif isUbuntu; then 123 | get_ubuntu_nic_ip_config_spec $1 124 | else 125 | nsx_bm_log "unkown OS, abort" 126 | exit 1 127 | fi 128 | if [ "$isStatic" = true ] && [ ! -z "$ip_address" ]; then 129 | isIpConfigured=true 130 | elif [ "$isStatic" = false ]; then 131 | isIpConfigured=true 132 | fi 133 | 134 | nsx_bm_log "isStatic: $isStatic" 135 | nsx_bm_log "ip_address: $ip_address" 136 | nsx_bm_log "netmask: $netmask" 137 | nsx_bm_log "prefix: $prefix" 138 | nsx_bm_log "gateway: $gateway" 139 | nsx_bm_log "isIpConfigured: $isIpConfigured" 140 | } 141 | 142 | get_rhel_nic_ip_config_spec() { 143 | local intf_name=$1 144 | if isRhel; then 145 | local configFile="/etc/sysconfig/network-scripts/ifcfg-"$1 146 | elif isSUSE; then 147 | local configFile="/etc/sysconfig/network/ifcfg-"$1 148 | fi 149 | 150 | nsx_bm_log "configFile: $configFile" 151 | 152 | while read line 153 | do 154 | output=($(echo $line | awk -F'=' '{print $1,$2}')) 155 | key="${output[0]}" 156 | value="${output[1]}" 157 | if [ "$key" == "BOOTPROTO" ]; then 158 | if [ "$value" == "dhcp" ] || [ "$value" == "\"dhcp\"" ] || [ "$value" == "'dhcp'" ]; then 159 | isStatic=false 160 | fi 161 | elif [ "$key" == "IPADDR" ]; then 162 | ip_address=$value 163 | ip_address="${ip_address%\"}" 164 | ip_address="${ip_address#\"}" 165 | elif [ "$key" == "NETMASK" ]; then 166 | netmask=$value 167 | netmask="${netmask%\"}" 168 | netmask="${netmask#\"}" 169 | elif [ "$key" == "PREFIX" ]; then 170 | prefix=$value 171 | prefix="${prefix%\"}" 172 | prefix="${prefix#\"}" 173 | elif [ "$key" == "GATEWAY" ]; then 174 | gateway=$value 175 | gateway="${gateway%\"}" 176 | gateway="${gateway#\"}" 177 | fi 178 | done < $configFile 179 | } 180 | 181 | {% raw %} 182 | get_ubuntu_nic_ip_config_spec() { 183 | #$1: nic name 184 | nsx_bm_log "get nic ip config spec..." 185 | local intf_name=$1 186 | nsx_bm_log "interface: $intf_name" 187 | local isTargetInterface=false 188 | while read line 189 | do 190 | vars=($line) 191 | if [ "${vars[0]}" == "iface" ]; then 192 | if [ "${#vars[@]}" -eq 4 ]; then 193 | if [ "${vars[1]}" == "$intf_name" ]; then 194 | if [ "${vars[3]}" == "dhcp" ]; then 195 | isStatic=false 196 | else 197 | isStatic=true 198 | fi 199 | isTargetInterface=true 200 | continue 201 | else 202 | isTargetInterface=false 203 | fi 204 | fi 205 | fi 206 | if [ "$isTargetInterface" = true ]; then 207 | if [ "${#vars[@]}" -eq 2 ]; then 208 | if [ "${vars[0]}" == "address" ]; then 209 | ip_address=${vars[1]} 210 | elif [ "${vars[0]}" == "netmask" ]; then 211 | netmask=${vars[1]} 212 | elif [ "${vars[0]}" == "gateway" ]; then 213 | gateway=${vars[1]} 214 | fi 215 | fi 216 | fi 217 | done < $IFCFG_FILE_UBUNTU 218 | } 219 | 220 | 221 | # save the pnic mac for migrating to application port 222 | # IN: $1= (e.g. eth1) 223 | get_interface_mac() { 224 | #$1: nic name 225 | local mac=$(cat /sys/class/net/$1/address) 226 | nsx_bm_log $mac 227 | } 228 | 229 | 230 | StopDhclient() { 231 | #$1: nic name 232 | $STOP_DHCLIENT_SCRIPT $1 233 | } 234 | 235 | 236 | StartIntf() { 237 | ifup $1 238 | } 239 | 240 | 241 | StopIntf() { 242 | StopDhclient $1 243 | ifdown $1 244 | } 245 | 246 | 247 | RestartInterface() { 248 | StopIntf $1 249 | StartIntf $1 250 | } 251 | 252 | 253 | IFUP_L2_ONLY() { 254 | ifconfig $1 0.0.0.0 up 2>&1 255 | } 256 | 257 | start_app_intf_forSUSE() { 258 | nsx_bm_log "start_app_intf_forSUSE" 259 | local old="/etc/sysconfig/network/ifcfg-"$MigrateBridgeIntfName 260 | local new="/etc/sysconfig/network/ifcfg-"$1 261 | cp $old $new 262 | sed -i "/DEVICE/s/^/$BMS_CMT_PREFIX/" $new 263 | sed -i "/NAME/s/^/$BMS_CMT_PREFIX/" $new 264 | ifdown $1 265 | ifup $1 266 | } 267 | 268 | 269 | # IN: $1= (e.g. eth1) 270 | start_app_intf() { 271 | nsx_bm_log "start app interface" 272 | ip link set $NSX_ETH up 273 | 274 | if isSUSE; then 275 | start_app_intf_forSUSE $1 276 | return 277 | else 278 | if [ "$isStatic" = false ]; then 279 | nsx_bm_log "start app interface dhcp" 280 | dhclient -nw $1 281 | fi 282 | fi 283 | } 284 | 285 | # IN: $1= (e.g. eth1) 286 | stop_app_intf_dhcp() { 287 | dhclient -r $1 288 | } 289 | 290 | update_ifcfg_file() { 291 | if isRhel || isSUSE; then 292 | update_rhel_ifcfg_file $1 293 | fi 294 | if isUbuntu; then 295 | update_ubuntu_ifcfg_file $1 296 | fi 297 | } 298 | 299 | update_ubuntu_ifcfg_file() { 300 | local intf_name=$1 301 | nsx_bm_log "update_ifcfg_file" 302 | if [ "$isStatic" = false ]; then 303 | sed -i "/auto $intf_name/s/^/$BMS_CMT_PREFIX/" $IFCFG_FILE_UBUNTU 304 | sed -i "/iface $intf_name inet dhcp/s/^/$BMS_CMT_PREFIX/" $IFCFG_FILE_UBUNTU 305 | else 306 | nsx_bm_log "update static config" 307 | line=$(sed -n "/auto $intf_name/=" $IFCFG_FILE_UBUNTU) 308 | sed -i "$line aauto $NSX_ETH" $IFCFG_FILE_UBUNTU 309 | sed -i "/auto $intf_name/s/^/$BMS_CMT_PREFIX/" $IFCFG_FILE_UBUNTU 310 | 311 | #line=$(sed -n "/iface $intf_name inet static/=" $IFCFG_FILE_UBUNTU) 312 | 313 | #total_linenum=$(cat $IFCFG_FILE_UBUNTU |wc -l) 314 | #(( line++ )) 315 | #while [ $line -le $total_linenum ] 316 | #do 317 | # key=$(sed -n "$line"p $IFCFG_FILE_UBUNTU | awk {'print $1'}) 318 | # if [ "$key" == "auto" ] || [ "$key" == "iface" ]; then 319 | # break 320 | # fi 321 | # sed -i "$line{s/^/$BMS_CMT_PREFIX/}" $IFCFG_FILE_UBUNTU 322 | # (( line++ )) 323 | #done 324 | 325 | line=$(sed -n "/iface $intf_name inet static/=" $IFCFG_FILE_UBUNTU) 326 | sed -i "$line aiface $NSX_ETH inet static" $IFCFG_FILE_UBUNTU 327 | sed -i "/iface $intf_name inet static/s/^/$BMS_CMT_PREFIX/" $IFCFG_FILE_UBUNTU 328 | fi 329 | } 330 | 331 | update_rhel_ifcfg_file() { 332 | local intf_name=$1 333 | if isRhel; then 334 | local configFile="/etc/sysconfig/network-scripts/ifcfg-"$1 335 | elif isSUSE; then 336 | local configFile="/etc/sysconfig/network/ifcfg-"$1 337 | fi 338 | 339 | 340 | if [ "$isStatic" = true ]; then 341 | sed -i "/IPADDR/s/^/$BMS_CMT_PREFIX/" $configFile 342 | sed -i "/NETMASK/s/^/$BMS_CMT_PREFIX/" $configFile 343 | sed -i "/GATEWAY/s/^/$BMS_CMT_PREFIX/" $configFile 344 | if isRhel; then 345 | cp /etc/sysconfig/network-scripts/ifcfg-$MigrateBridgeIntfName /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 346 | sed -i "s/^$BMS_CMT_PREFIX//g" /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 347 | sed -i "s/$MigrateBridgeIntfName/$NSX_ETH/" /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 348 | sed -i "/OVS/"d /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 349 | sed -i "/ovs/"d /etc/sysconfig/network-scripts/ifcfg-$NSX_ETH 350 | fi 351 | else 352 | sed -i "/BOOTPROTO/s/^/$BMS_CMT_PREFIX/" $configFile 353 | fi 354 | } 355 | 356 | pre_migrate_to_app() { 357 | local intf_name=$1 358 | # save the pnic mac for migrating to app port 359 | migrate_mac=$(get_interface_mac $intf_name) 360 | nsx_bm_log "migrate mac: $migrate_mac" 361 | } 362 | 363 | attach_ovs_port() { 364 | nsx_bm_log "attach ovs port..." 365 | ovs-vsctl --timeout=5 -- --if-exists del-port $NSX_ETH_PEER -- add-port nsx-managed $NSX_ETH_PEER -- set Interface $NSX_ETH_PEER external-ids:attached-mac=$migrate_mac external-ids:iface-id=$APP_VIF_ID external-ids:iface-status=active 366 | } 367 | 368 | 369 | update_route() { 370 | if [ ! -z "$gateway" ]; then 371 | ip route add default via $gateway dev $NSX_ETH 372 | fi 373 | # resotre default route (if the pnic is on static IP) 374 | if [ "$isStatic" = true ]; then 375 | if [ "$intf_name" == "$defaultGatewayDev" ]; then 376 | nsx_bm_log "add default route" 377 | route add default gw $defaultGatewayIp 378 | fi 379 | fi 380 | } 381 | 382 | create_app_intf() { 383 | nsx_bm_log "create app interface" 384 | 385 | ip link del $NSX_ETH &> /dev/null 386 | 387 | ip link add $NSX_ETH type veth peer name $NSX_ETH_PEER 388 | # migrate mac address 389 | ip link set $NSX_ETH address $migrate_mac 390 | ip link set $NSX_ETH_PEER up 391 | 392 | if [ "$isStatic" = true ]; then 393 | nsx_bm_log "config ipaddress" 394 | if [ ! -z "$ip_address" ]; then 395 | if [ ! -z "$netmask" ]; then 396 | ifconfig $NSX_ETH $ip_address netmask $netmask 397 | elif [ ! -z "$prefix" ]; then 398 | ifconfig $NSX_ETH $ip_address/$prefix 399 | else 400 | ifconfig $NSX_ETH $ip_address 401 | fi 402 | fi 403 | fi 404 | 405 | attach_ovs_port 406 | } 407 | 408 | 409 | post_migrate_to_app() { 410 | local intf_name=$1 411 | 412 | # ifdown migrated port 413 | StopIntf $intf_name 414 | 415 | start_app_intf $NSX_ETH 416 | 417 | update_route 418 | 419 | update_ifcfg_file $intf_name 420 | } 421 | 422 | 423 | delete_nsx_bms_config() { 424 | rm -rf $BMS_CONFIG_FILE 425 | } 426 | 427 | 428 | generate_config_file() { 429 | delete_nsx_bms_config 430 | 431 | mkdir -p $BMS_CONFIG_DIR 432 | 433 | nsx_bm_log "config_mode=$ConfigMode" >> $BMS_CONFIG_FILE 434 | nsx_bm_log "migrate_interface=$MigrateBridgeIntfName" >> $BMS_CONFIG_FILE 435 | nsx_bm_log "isStatic=$isStatic" >> $BMS_CONFIG_FILE 436 | nsx_bm_log "migrate_mac=$migrate_mac" >> $BMS_CONFIG_FILE 437 | nsx_bm_log "ip_address=$ip_address" >> $BMS_CONFIG_FILE 438 | nsx_bm_log "netmask=$netmask" >> $BMS_CONFIG_FILE 439 | nsx_bm_log "prefix=$prefix" >> $BMS_CONFIG_FILE 440 | nsx_bm_log "gateway=$gateway" >> $BMS_CONFIG_FILE 441 | nsx_bm_log "defaultGatewayIp=$defaultGatewayIp" >> $BMS_CONFIG_FILE 442 | nsx_bm_log "defaultGatewayDev=$defaultGatewayDev" >> $BMS_CONFIG_FILE 443 | } 444 | 445 | migrate_ip_to_app() { 446 | nsx_bm_log "migrage bridge ip to app" 447 | get_os_type 448 | 449 | get_migrate_bridge_intf_name 450 | nsx_bm_log "migrate bridge interface name $MigrateBridgeIntfName" 451 | 452 | get_interface_status $MigrateBridgeIntfName 453 | if [ "$interfaceStatus" != "l3up" ]; then 454 | nsx_bm_log "not l3up, no suitable interface to be migrated" 455 | return 456 | fi 457 | 458 | GetDefaultRoute 459 | get_nic_ip_config_spec $MigrateBridgeIntfName 460 | if [ "$isIpConfigured" = false ]; then 461 | nsx_bm_log "nic $MigrateBridgeIntfName has no IP configured, skip migration" 462 | return 463 | fi 464 | 465 | pre_migrate_to_app $MigrateBridgeIntfName 466 | generate_config_file 467 | create_app_intf 468 | post_migrate_to_app $MigrateBridgeIntfName 469 | } 470 | 471 | echo "==========================" 472 | date 473 | nsx_bm_log "nsx baremetal migrate ip to application" 474 | nsx_bm_log "NSX_ETH: $NSX_ETH, APP_VIF_ID: $APP_VIF_ID, MigratePnicName: $MigratePnicName" 475 | migrate_ip_to_app 476 | 477 | {% endraw %} 478 | 479 | -------------------------------------------------------------------------------- /bms-ansible-nsx/windows/ConfigureWinRMService.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3.0 2 | 3 | # Configure a Windows host for remote management 4 | # ----------------------------------------------------------- 5 | # 6 | # This script checks the current WinRM configuration and makes 7 | # the necessary changes to allow Client to connect, authenticate and 8 | # execute PowerShell commands. 9 | # 10 | # All events are logged to the Windows EventLog, useful for unattended runs. 11 | # 12 | # Use option -Verbose in order to see the verbose output messages. 13 | # 14 | # Use option -CertValidityDays to specify how long this certificate is valid 15 | # starting from today. So you would specify -CertValidityDays 3650 to get 16 | # a 10-year valid certificate. 17 | # 18 | # Use option -ForceNewSSLCert if the system has been SysPreped and a new 19 | # SSL Certificate must be forced on the WinRM Listener when re-running this 20 | # script. This is necessary when a new SID and CN name is created. 21 | # 22 | # Use option -EnableCredSSP to enable CredSSP as an authentication option. 23 | # 24 | # Use option -DisableBasicAuth to disable basic authentication. 25 | # 26 | # Use option -SkipNetworkProfileCheck to skip the network profile check. 27 | # Without specifying this the script will only run if the device's interfaces 28 | # are in DOMAIN or PRIVATE zones. Provide this switch if you want to enable 29 | # WinRM on a device with an interface in PUBLIC zone. 30 | # 31 | # Use option -SubjectName to specify the CN name of the certificate. This 32 | # defaults to the system's hostname and generally should not be specified. 33 | 34 | # Support -Verbose option 35 | [CmdletBinding()] 36 | 37 | Param ( 38 | [string]$SubjectName = $env:COMPUTERNAME, 39 | [int]$CertValidityDays = 1095, 40 | [switch]$SkipNetworkProfileCheck, 41 | $CreateSelfSignedCert = $true, 42 | [switch]$ForceNewSSLCert, 43 | [switch]$GlobalHttpFirewallAccess, 44 | [switch]$DisableBasicAuth = $false, 45 | [switch]$EnableCredSSP 46 | ) 47 | 48 | Function Write-Log 49 | { 50 | $Message = $args[0] 51 | Write-EventLog -LogName Application -Source $EventSource -EntryType Information -EventId 1 -Message $Message 52 | } 53 | 54 | Function Write-VerboseLog 55 | { 56 | $Message = $args[0] 57 | Write-Verbose $Message 58 | Write-Log $Message 59 | } 60 | 61 | Function Write-HostLog 62 | { 63 | $Message = $args[0] 64 | Write-Output $Message 65 | Write-Log $Message 66 | } 67 | 68 | Function New-LegacySelfSignedCert 69 | { 70 | Param ( 71 | [string]$SubjectName, 72 | [int]$ValidDays = 1095 73 | ) 74 | 75 | $hostnonFQDN = $env:computerName 76 | $hostFQDN = [System.Net.Dns]::GetHostByName(($env:computerName)).Hostname 77 | $SignatureAlgorithm = "SHA256" 78 | 79 | $name = New-Object -COM "X509Enrollment.CX500DistinguishedName.1" 80 | $name.Encode("CN=$SubjectName", 0) 81 | 82 | $key = New-Object -COM "X509Enrollment.CX509PrivateKey.1" 83 | $key.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider" 84 | $key.KeySpec = 1 85 | $key.Length = 4096 86 | $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)" 87 | $key.MachineContext = 1 88 | $key.Create() 89 | 90 | $serverauthoid = New-Object -COM "X509Enrollment.CObjectId.1" 91 | $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1") 92 | $ekuoids = New-Object -COM "X509Enrollment.CObjectIds.1" 93 | $ekuoids.Add($serverauthoid) 94 | $ekuext = New-Object -COM "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1" 95 | $ekuext.InitializeEncode($ekuoids) 96 | 97 | $cert = New-Object -COM "X509Enrollment.CX509CertificateRequestCertificate.1" 98 | $cert.InitializeFromPrivateKey(2, $key, "") 99 | $cert.Subject = $name 100 | $cert.Issuer = $cert.Subject 101 | $cert.NotBefore = (Get-Date).AddDays(-1) 102 | $cert.NotAfter = $cert.NotBefore.AddDays($ValidDays) 103 | 104 | $SigOID = New-Object -ComObject X509Enrollment.CObjectId 105 | $SigOID.InitializeFromValue(([Security.Cryptography.Oid]$SignatureAlgorithm).Value) 106 | 107 | [string[]] $AlternativeName += $hostnonFQDN 108 | $AlternativeName += $hostFQDN 109 | $IAlternativeNames = New-Object -ComObject X509Enrollment.CAlternativeNames 110 | 111 | foreach ($AN in $AlternativeName) 112 | { 113 | $AltName = New-Object -ComObject X509Enrollment.CAlternativeName 114 | $AltName.InitializeFromString(0x3,$AN) 115 | $IAlternativeNames.Add($AltName) 116 | } 117 | 118 | $SubjectAlternativeName = New-Object -ComObject X509Enrollment.CX509ExtensionAlternativeNames 119 | $SubjectAlternativeName.InitializeEncode($IAlternativeNames) 120 | 121 | [String[]]$KeyUsage = ("DigitalSignature", "KeyEncipherment") 122 | $KeyUsageObj = New-Object -ComObject X509Enrollment.CX509ExtensionKeyUsage 123 | $KeyUsageObj.InitializeEncode([int][Security.Cryptography.X509Certificates.X509KeyUsageFlags]($KeyUsage)) 124 | $KeyUsageObj.Critical = $true 125 | 126 | $cert.X509Extensions.Add($KeyUsageObj) 127 | $cert.X509Extensions.Add($ekuext) 128 | $cert.SignatureInformation.HashAlgorithm = $SigOID 129 | $CERT.X509Extensions.Add($SubjectAlternativeName) 130 | $cert.Encode() 131 | 132 | $enrollment = New-Object -COM "X509Enrollment.CX509Enrollment.1" 133 | $enrollment.InitializeFromRequest($cert) 134 | $certdata = $enrollment.CreateRequest(0) 135 | $enrollment.InstallResponse(2, $certdata, 0, "") 136 | 137 | # extract/return the thumbprint from the generated cert 138 | $parsed_cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 139 | $parsed_cert.Import([System.Text.Encoding]::UTF8.GetBytes($certdata)) 140 | 141 | return $parsed_cert.Thumbprint 142 | } 143 | 144 | Function Enable-GlobalHttpFirewallAccess 145 | { 146 | Write-Verbose "Forcing global HTTP firewall access" 147 | # this is a fairly naive implementation; could be more sophisticated about rule matching/collapsing 148 | $fw = New-Object -ComObject HNetCfg.FWPolicy2 149 | 150 | # try to find/enable the default rule first 151 | $add_rule = $false 152 | $matching_rules = $fw.Rules | Where-Object { $_.Name -eq "Windows Remote Management (HTTP-In)" } 153 | $rule = $null 154 | If ($matching_rules) { 155 | If ($matching_rules -isnot [Array]) { 156 | Write-Verbose "Editing existing single HTTP firewall rule" 157 | $rule = $matching_rules 158 | } 159 | Else { 160 | # try to find one with the All or Public profile first 161 | Write-Verbose "Found multiple existing HTTP firewall rules..." 162 | $rule = $matching_rules | ForEach-Object { $_.Profiles -band 4 }[0] 163 | 164 | If (-not $rule -or $rule -is [Array]) { 165 | Write-Verbose "Editing an arbitrary single HTTP firewall rule (multiple existed)" 166 | # oh well, just pick the first one 167 | $rule = $matching_rules[0] 168 | } 169 | } 170 | } 171 | 172 | If (-not $rule) { 173 | Write-Verbose "Creating a new HTTP firewall rule" 174 | $rule = New-Object -ComObject HNetCfg.FWRule 175 | $rule.Name = "Windows Remote Management (HTTP-In)" 176 | $rule.Description = "Inbound rule for Windows Remote Management via WS-Management. [TCP 5985]" 177 | $add_rule = $true 178 | } 179 | 180 | $rule.Profiles = 0x7FFFFFFF 181 | $rule.Protocol = 6 182 | $rule.LocalPorts = 5985 183 | $rule.RemotePorts = "*" 184 | $rule.LocalAddresses = "*" 185 | $rule.RemoteAddresses = "*" 186 | $rule.Enabled = $true 187 | $rule.Direction = 1 188 | $rule.Action = 1 189 | $rule.Grouping = "Windows Remote Management" 190 | 191 | If ($add_rule) { 192 | $fw.Rules.Add($rule) 193 | } 194 | 195 | Write-Verbose "HTTP firewall rule $($rule.Name) updated" 196 | } 197 | 198 | # Setup error handling. 199 | Trap 200 | { 201 | $_ 202 | Exit 1 203 | } 204 | $ErrorActionPreference = "Stop" 205 | 206 | # Get the ID and security principal of the current user account 207 | $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent() 208 | $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID) 209 | 210 | # Get the security principal for the Administrator role 211 | $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator 212 | 213 | # Check to see if we are currently running "as Administrator" 214 | if (-Not $myWindowsPrincipal.IsInRole($adminRole)) 215 | { 216 | Write-Output "ERROR: You need elevated Administrator privileges in order to run this script." 217 | Write-Output " Start Windows PowerShell by using the Run as Administrator option." 218 | Exit 2 219 | } 220 | 221 | $EventSource = $MyInvocation.MyCommand.Name 222 | If (-Not $EventSource) 223 | { 224 | $EventSource = "Powershell CLI" 225 | } 226 | 227 | If ([System.Diagnostics.EventLog]::Exists('Application') -eq $False -or [System.Diagnostics.EventLog]::SourceExists($EventSource) -eq $False) 228 | { 229 | New-EventLog -LogName Application -Source $EventSource 230 | } 231 | 232 | # Detect PowerShell version. 233 | If ($PSVersionTable.PSVersion.Major -lt 3) 234 | { 235 | Write-Log "PowerShell version 3 or higher is required." 236 | Throw "PowerShell version 3 or higher is required." 237 | } 238 | 239 | # Find and start the WinRM service. 240 | Write-Verbose "Verifying WinRM service." 241 | If (!(Get-Service "WinRM")) 242 | { 243 | Write-Log "Unable to find the WinRM service." 244 | Throw "Unable to find the WinRM service." 245 | } 246 | ElseIf ((Get-Service "WinRM").Status -ne "Running") 247 | { 248 | Write-Verbose "Setting WinRM service to start automatically on boot." 249 | Set-Service -Name "WinRM" -StartupType Automatic 250 | Write-Log "Set WinRM service to start automatically on boot." 251 | Write-Verbose "Starting WinRM service." 252 | Start-Service -Name "WinRM" -ErrorAction Stop 253 | Write-Log "Started WinRM service." 254 | 255 | } 256 | 257 | # WinRM should be running; check that we have a PS session config. 258 | If (!(Get-PSSessionConfiguration -Verbose:$false) -or (!(Get-ChildItem WSMan:\localhost\Listener))) 259 | { 260 | If ($SkipNetworkProfileCheck) { 261 | Write-Verbose "Enabling PS Remoting without checking Network profile." 262 | Enable-PSRemoting -SkipNetworkProfileCheck -Force -ErrorAction Stop 263 | Write-Log "Enabled PS Remoting without checking Network profile." 264 | } 265 | Else { 266 | Write-Verbose "Enabling PS Remoting." 267 | Enable-PSRemoting -Force -ErrorAction Stop 268 | Write-Log "Enabled PS Remoting." 269 | } 270 | } 271 | Else 272 | { 273 | Write-Verbose "PS Remoting is already enabled." 274 | } 275 | 276 | $token_path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" 277 | $token_prop_name = "LocalAccountTokenFilterPolicy" 278 | $token_key = Get-Item -Path $token_path 279 | $token_value = $token_key.GetValue($token_prop_name, $null) 280 | if ($token_value -ne 1) { 281 | Write-Verbose "Setting LocalAccountTOkenFilterPolicy to 1" 282 | if ($null -ne $token_value) { 283 | Remove-ItemProperty -Path $token_path -Name $token_prop_name 284 | } 285 | New-ItemProperty -Path $token_path -Name $token_prop_name -Value 1 -PropertyType DWORD > $null 286 | } 287 | 288 | # Make sure there is a SSL listener. 289 | $listeners = Get-ChildItem WSMan:\localhost\Listener 290 | If (!($listeners | Where-Object {$_.Keys -like "TRANSPORT=HTTPS"})) 291 | { 292 | # We cannot use New-SelfSignedCertificate on 2012R2 and earlier 293 | $thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName -ValidDays $CertValidityDays 294 | Write-HostLog "Self-signed SSL certificate generated; thumbprint: $thumbprint" 295 | 296 | # Create the hashtables of settings to be used. 297 | $valueset = @{ 298 | Hostname = $SubjectName 299 | CertificateThumbprint = $thumbprint 300 | } 301 | 302 | $selectorset = @{ 303 | Transport = "HTTPS" 304 | Address = "*" 305 | } 306 | 307 | Write-Verbose "Enabling SSL listener." 308 | New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset 309 | Write-Log "Enabled SSL listener." 310 | } 311 | Else 312 | { 313 | Write-Verbose "SSL listener is already active." 314 | 315 | # Force a new SSL cert on Listener if the $ForceNewSSLCert 316 | If ($ForceNewSSLCert) 317 | { 318 | 319 | # We cannot use New-SelfSignedCertificate on 2012R2 and earlier 320 | $thumbprint = New-LegacySelfSignedCert -SubjectName $SubjectName -ValidDays $CertValidityDays 321 | Write-HostLog "Self-signed SSL certificate generated; thumbprint: $thumbprint" 322 | 323 | $valueset = @{ 324 | CertificateThumbprint = $thumbprint 325 | Hostname = $SubjectName 326 | } 327 | 328 | # Delete the listener for SSL 329 | $selectorset = @{ 330 | Address = "*" 331 | Transport = "HTTPS" 332 | } 333 | Remove-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset 334 | 335 | # Add new Listener with new SSL cert 336 | New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset 337 | } 338 | } 339 | 340 | # Check for basic authentication. 341 | $basicAuthSetting = Get-ChildItem WSMan:\localhost\Service\Auth | Where-Object {$_.Name -eq "Basic"} 342 | 343 | If ($DisableBasicAuth) 344 | { 345 | If (($basicAuthSetting.Value) -eq $true) 346 | { 347 | Write-Verbose "Disabling basic auth support." 348 | Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $false 349 | Write-Log "Disabled basic auth support." 350 | } 351 | Else 352 | { 353 | Write-Verbose "Basic auth is already disabled." 354 | } 355 | } 356 | Else 357 | { 358 | If (($basicAuthSetting.Value) -eq $false) 359 | { 360 | Write-Verbose "Enabling basic auth support." 361 | Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $true 362 | Write-Log "Enabled basic auth support." 363 | } 364 | Else 365 | { 366 | Write-Verbose "Basic auth is already enabled." 367 | } 368 | } 369 | 370 | # If EnableCredSSP if set to true 371 | If ($EnableCredSSP) 372 | { 373 | # Check for CredSSP authentication 374 | $credsspAuthSetting = Get-ChildItem WSMan:\localhost\Service\Auth | Where-Object {$_.Name -eq "CredSSP"} 375 | If (($credsspAuthSetting.Value) -eq $false) 376 | { 377 | Write-Verbose "Enabling CredSSP auth support." 378 | Enable-WSManCredSSP -role server -Force 379 | Write-Log "Enabled CredSSP auth support." 380 | } 381 | } 382 | 383 | If ($GlobalHttpFirewallAccess) { 384 | Enable-GlobalHttpFirewallAccess 385 | } 386 | 387 | # Configure firewall to allow WinRM HTTPS connections. 388 | $fwtest1 = netsh advfirewall firewall show rule name="Allow WinRM HTTPS" 389 | $fwtest2 = netsh advfirewall firewall show rule name="Allow WinRM HTTPS" profile=any 390 | If ($fwtest1.count -lt 5) 391 | { 392 | Write-Verbose "Adding firewall rule to allow WinRM HTTPS." 393 | netsh advfirewall firewall add rule profile=any name="Allow WinRM HTTPS" dir=in localport=5986 protocol=TCP action=allow 394 | Write-Log "Added firewall rule to allow WinRM HTTPS." 395 | } 396 | ElseIf (($fwtest1.count -ge 5) -and ($fwtest2.count -lt 5)) 397 | { 398 | Write-Verbose "Updating firewall rule to allow WinRM HTTPS for any profile." 399 | netsh advfirewall firewall set rule name="Allow WinRM HTTPS" new profile=any 400 | Write-Log "Updated firewall rule to allow WinRM HTTPS for any profile." 401 | } 402 | Else 403 | { 404 | Write-Verbose "Firewall rule already exists to allow WinRM HTTPS." 405 | } 406 | 407 | # Test a remoting connection to localhost, which should work. 408 | $httpResult = Invoke-Command -ComputerName "localhost" -ScriptBlock {$env:COMPUTERNAME} -ErrorVariable httpError -ErrorAction SilentlyContinue 409 | $httpsOptions = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck 410 | 411 | $httpsResult = New-PSSession -UseSSL -ComputerName "localhost" -SessionOption $httpsOptions -ErrorVariable httpsError -ErrorAction SilentlyContinue 412 | 413 | If ($httpResult -and $httpsResult) 414 | { 415 | Write-Verbose "HTTP: Enabled | HTTPS: Enabled" 416 | } 417 | ElseIf ($httpsResult -and !$httpResult) 418 | { 419 | Write-Verbose "HTTP: Disabled | HTTPS: Enabled" 420 | } 421 | ElseIf ($httpResult -and !$httpsResult) 422 | { 423 | Write-Verbose "HTTP: Enabled | HTTPS: Disabled" 424 | } 425 | Else 426 | { 427 | Write-Log "Unable to establish an HTTP or HTTPS remoting session." 428 | Throw "Unable to establish an HTTP or HTTPS remoting session." 429 | } 430 | Write-VerboseLog "WinRM Service has been successfully configured." 431 | --------------------------------------------------------------------------------