summaryrefslogtreecommitdiffstats
path: root/network/storage_mgmt_v6.yaml
blob: 2b065195930af34abdbe54661b920d153dffb103 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
heat_template_version: ocata

description: >
  Storage management network. Storage replication, etc.

parameters:
  # the defaults here work for static IP assignment (IPAM) only
  StorageMgmtNetCidr:
    # OpenStack uses the EUI-64 address format, which requires a /64 prefix
    default: 'fd00:fd00:fd00:4000::/64'
    description: Cidr for the storage management network.
    type: string
  StorageMgmtNetValueSpecs:
    default: {'provider:physical_network': 'storage_mgmt', 'provider:network_type': 'flat'}
    description: Value specs for the storage_mgmt network.
    type: json
  StorageMgmtNetAdminStateUp:
    default: false
    description: This admin state of of the network.
    type: boolean
  StorageMgmtNetShared:
    default: false
    description: Whether this network is shared across all tenants.
    type: boolean
  StorageMgmtNetName:
    default: storage_mgmt
    description: The name of the Storage management network.
    type: string
  StorageMgmtSubnetName:
    default: storage_mgmt_subnet
    description: The name of the Storage management subnet in Neutron.
    type: string
  StorageMgmtAllocationPools:
    default: [{'start': 'fd00:fd00:fd00:4000::10', 'end': 'fd00:fd00:fd00:4000:ffff:ffff:ffff:fffe'}]
    description: Ip allocation pool range for the storage mgmt network.
    type: json
  IPv6AddressMode:
    default: dhcpv6-stateful
    description: Neutron subnet IPv6 address mode
    type: string
  IPv6RAMode:
    default: dhcpv6-stateful
    description: Neutron subnet IPv6 router advertisement mode
    type: string

resources:
  StorageMgmtNetwork:
    type: OS::Neutron::Net
    properties:
      admin_state_up: {get_param: StorageMgmtNetAdminStateUp}
      name: {get_param: StorageMgmtNetName}
      shared: {get_param: StorageMgmtNetShared}
      value_specs: {get_param: StorageMgmtNetValueSpecs}

  StorageMgmtSubnet:
    type: OS::Neutron::Subnet
    properties:
      ip_version: 6
      ipv6_address_mode: {get_param: IPv6AddressMode}
      ipv6_ra_mode: {get_param: IPv6RAMode}
      cidr: {get_param: StorageMgmtNetCidr}
      name: {get_param: StorageMgmtSubnetName}
      network: {get_resource: StorageMgmtNetwork}
      allocation_pools: {get_param: StorageMgmtAllocationPools}
      gateway_ip: null

outputs:
  OS::stack_id:
    description: Neutron storage management network
    value: {get_resource: StorageMgmtNetwork}
an> platform.system() == "Windows" or platform.system() == "Microsoft": return getpass.win_getpass(prompt=prompt) else: return getpass.getpass(prompt=prompt) def get_servers(handle=None): """ Return list of servers """ orgObj = handle.GetManagedObject( None, OrgOrg.ClassId(), {OrgOrg.DN: "org-root"})[0] servers = handle.GetManagedObject(orgObj, LsServer.ClassId()) for server in servers: if server.Type == 'instance' and POD_PREFIX in server.Dn: yield server def set_boot_policy(handle=None, server=None, policy=None): """ Modify Boot policy of server """ obj = handle.GetManagedObject(None, LsServer.ClassId(), { LsServer.DN: server.Dn}) handle.SetManagedObject(obj, LsServer.ClassId(), { LsServer.BOOT_POLICY_NAME: policy}) print(" Configured boot policy: {}".format(policy)) def ack_pending(handle=None, server=None): """ Acknowledge pending state of server """ handle.AddManagedObject(server, LsmaintAck.ClassId(), { LsmaintAck.DN: server.Dn + "/ack", LsmaintAck.DESCR: "", LsmaintAck.ADMIN_STATE: "trigger-immediate", LsmaintAck.SCHEDULER: "", LsmaintAck.POLICY_OWNER: "local"}, True) print(" Pending-reboot -> Acknowledged.") def boot_server(handle=None, server=None): """ Boot server (when is in power-off state) """ obj = handle.GetManagedObject( None, LsServer.ClassId(), {LsServer.DN: server.Dn}) handle.AddManagedObject(obj, LsPower.ClassId(), { LsPower.DN: server.Dn + "/power", LsPower.STATE: "admin-up"}, True) print(" Booting.") def get_vnics(handle=None, server=None): """ Return list of vnics for given server """ vnics = handle.ConfigResolveChildren( VnicEther.ClassId(), server.Dn, None, YesOrNo.TRUE) return vnics.OutConfigs.GetChild() def get_network_config(handle=None): """ Print current network config """ print("\nCURRENT NETWORK CONFIG:") print(" d - default, t - tagged") for server in get_servers(handle): print(' {}'.format(server.Name)) print(' Boot policy: {}'.format(server.OperBootPolicyName)) for vnic in get_vnics(handle, server): print(' {}'.format(vnic.Name)) print(' {}'.format(vnic.Addr)) vnicIfs = handle.ConfigResolveChildren( VnicEtherIf.ClassId(), vnic.Dn, None, YesOrNo.TRUE) for vnicIf in vnicIfs.OutConfigs.GetChild(): if vnicIf.DefaultNet == 'yes': print(' Vlan: {}d'.format(vnicIf.Vnet)) else: print(' Vlan: {}t'.format(vnicIf.Vnet)) def add_interface(handle=None, lsServerDn=None, vnicEther=None, templName=None, order=None, macAddr=None): """ Add interface to server specified by server.DN name """ print(" Adding interface: {}, template: {}, server.Dn: {}".format( vnicEther, templName, lsServerDn)) obj = handle.GetManagedObject( None, LsServer.ClassId(), {LsServer.DN: lsServerDn}) vnicEtherDn = lsServerDn + "/ether-" + vnicEther params = { VnicEther.STATS_POLICY_NAME: "default", VnicEther.NAME: vnicEther, VnicEther.DN: vnicEtherDn, VnicEther.SWITCH_ID: "A-B", VnicEther.ORDER: order, "adminHostPort": "ANY", VnicEther.ADMIN_VCON: "any", VnicEther.ADDR: macAddr, VnicEther.NW_TEMPL_NAME: templName, VnicEther.MTU: "1500"} handle.AddManagedObject(obj, VnicEther.ClassId(), params, True) def remove_interface(handle=None, vnicEtherDn=None): """ Remove interface specified by Distinguished Name (vnicEtherDn) """ print(" Removing interface: {}".format(vnicEtherDn)) obj = handle.GetManagedObject( None, VnicEther.ClassId(), {VnicEther.DN: vnicEtherDn}) handle.RemoveManagedObject(obj) def read_yaml_file(yamlFile): """ Read vnic config from yaml file """ # TODO: add check if vnic templates specified in file exist on UCS with open(yamlFile, 'r') as stream: return yaml.safe_load(stream) def set_network(handle=None, yamlFile=None): """ Configure VLANs on POD according specified network """ # add interfaces and bind them with vNIC templates print("\nRECONFIGURING VNICs...") pod_data = read_yaml_file(yamlFile) network = pod_data['network'] for index, server in enumerate(get_servers(handle)): # Assign template to interface for iface, data in network.iteritems(): add_interface(handle, server.Dn, iface, data['template'], data[ 'order'], data['mac-list'][index]) # Remove other interfaces which have not assigned required vnic # template vnics = get_vnics(handle, server) for vnic in vnics: if not any(data['template'] in vnic.OperNwTemplName for iface, data in network.iteritems()): remove_interface(handle, vnic.Dn) print(" {} removed, template: {}".format( vnic.Name, vnic.OperNwTemplName)) # Set boot policy template if INSTALLER not in server.Dn: set_boot_policy(handle, server, pod_data['boot-policy']) if __name__ == "__main__": print("\n*** SKIPING RECONFIGURATION.***\n") sys.exit(0) # Latest urllib2 validate certs by default # The process wide "revert to the old behaviour" hook is to monkeypatch # the ssl module # https://bugs.python.org/issue22417 import ssl if hasattr(ssl, '_create_unverified_context'): ssl._create_default_https_context = ssl._create_unverified_context try: handle = UcsHandle() parser = optparse.OptionParser() parser.add_option('-i', '--ip', dest="ip", help="[Mandatory] UCSM IP Address") parser.add_option('-u', '--username', dest="userName", help="[Mandatory] Account Username for UCSM Login") parser.add_option('-p', '--password', dest="password", help="[Mandatory] Account Password for UCSM Login") parser.add_option('-f', '--file', dest="yamlFile", help=("[Optional] Yaml file contains network " "config you want to set on UCS POD1")) (options, args) = parser.parse_args() if not options.ip: parser.print_help() parser.error("Provide UCSM IP Address") if not options.userName: parser.print_help() parser.error("Provide UCSM UserName") if not options.password: options.password = getpassword("UCSM Password:") handle.Login(options.ip, options.userName, options.password) # Change vnic template if specified in cli option if (options.yamlFile is not None): set_network(handle, options.yamlFile) time.sleep(5) print("\nWait until Overall Status of all nodes is OK...") timeout = time.time() + 60 * 10 # 10 minutes timeout while True: list_of_states = [] for server in get_servers(handle): if server.OperState == "power-off": boot_server(handle, server) if server.OperState == "pending-reboot": ack_pending(handle, server) list_of_states.append(server.OperState) print(" {}, {} seconds remains.".format( list_of_states, round(timeout - time.time()))) if all(state == "ok" for state in list_of_states): break if time.time() > timeout: raise Exception("Timeout reached while waiting for OK status.") time.sleep(10) # Show current vnic MACs and VLANs get_network_config(handle) handle.Logout() except Exception as err: handle.Logout() print("Exception:", str(err)) import traceback import sys print('-' * 60) traceback.print_exc(file=sys.stdout) print('-' * 60) sys.exit(1)