3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 # This script reconfigure UCSM vnics for varios OPNFV deployers
15 # Usage: reconfigUcsNet.py [options]
18 # -h, --help show this help message and exit
19 # -i IP, --ip=IP [Mandatory] UCSM IP Address
20 # -u USERNAME, --username=USERNAME
21 # [Mandatory] Account Username for UCSM Login
22 # -p PASSWORD, --password=PASSWORD
23 # [Mandatory] Account Password for UCSM Login
24 # -f FILE, --file=FILE
25 # [Optional] Yaml file with network config you
27 # If not present only current network config
37 from UcsSdk import LsmaintAck, LsPower, LsServer, OrgOrg
38 from UcsSdk import UcsHandle, VnicEther, VnicEtherIf, YesOrNo
45 def getpassword(prompt):
46 if platform.system() == "Linux":
47 return getpass.unix_getpass(prompt=prompt)
48 elif platform.system() == "Windows" or platform.system() == "Microsoft":
49 return getpass.win_getpass(prompt=prompt)
51 return getpass.getpass(prompt=prompt)
54 def get_servers(handle=None):
56 Return list of servers
58 orgObj = handle.GetManagedObject(
59 None, OrgOrg.ClassId(), {OrgOrg.DN: "org-root"})[0]
60 servers = handle.GetManagedObject(orgObj, LsServer.ClassId())
61 for server in servers:
62 if server.Type == 'instance' and POD_PREFIX in server.Dn:
66 def set_boot_policy(handle=None, server=None, policy=None):
68 Modify Boot policy of server
70 obj = handle.GetManagedObject(None, LsServer.ClassId(), {
71 LsServer.DN: server.Dn})
72 handle.SetManagedObject(obj, LsServer.ClassId(), {
73 LsServer.BOOT_POLICY_NAME: policy})
74 print(" Configured boot policy: {}".format(policy))
77 def ack_pending(handle=None, server=None):
79 Acknowledge pending state of server
81 handle.AddManagedObject(server, LsmaintAck.ClassId(), {
82 LsmaintAck.DN: server.Dn + "/ack",
84 LsmaintAck.ADMIN_STATE: "trigger-immediate",
85 LsmaintAck.SCHEDULER: "",
86 LsmaintAck.POLICY_OWNER: "local"}, True)
87 print(" Pending-reboot -> Acknowledged.")
90 def boot_server(handle=None, server=None):
92 Boot server (when is in power-off state)
94 obj = handle.GetManagedObject(
95 None, LsServer.ClassId(), {LsServer.DN: server.Dn})
96 handle.AddManagedObject(obj, LsPower.ClassId(), {
97 LsPower.DN: server.Dn + "/power",
98 LsPower.STATE: "admin-up"}, True)
102 def get_vnics(handle=None, server=None):
104 Return list of vnics for given server
106 vnics = handle.ConfigResolveChildren(
107 VnicEther.ClassId(), server.Dn, None, YesOrNo.TRUE)
108 return vnics.OutConfigs.GetChild()
111 def get_network_config(handle=None):
113 Print current network config
115 print("\nCURRENT NETWORK CONFIG:")
116 print(" d - default, t - tagged")
117 for server in get_servers(handle):
118 print(' {}'.format(server.Name))
119 print(' Boot policy: {}'.format(server.OperBootPolicyName))
120 for vnic in get_vnics(handle, server):
121 print(' {}'.format(vnic.Name))
122 print(' {}'.format(vnic.Addr))
123 vnicIfs = handle.ConfigResolveChildren(
124 VnicEtherIf.ClassId(), vnic.Dn, None, YesOrNo.TRUE)
125 for vnicIf in vnicIfs.OutConfigs.GetChild():
126 if vnicIf.DefaultNet == 'yes':
127 print(' Vlan: {}d'.format(vnicIf.Vnet))
129 print(' Vlan: {}t'.format(vnicIf.Vnet))
132 def add_interface(handle=None,
139 Add interface to server specified by server.DN name
141 print(" Adding interface: {}, template: {}, server.Dn: {}".format(
142 vnicEther, templName, lsServerDn))
143 obj = handle.GetManagedObject(
144 None, LsServer.ClassId(), {LsServer.DN: lsServerDn})
145 vnicEtherDn = lsServerDn + "/ether-" + vnicEther
147 VnicEther.STATS_POLICY_NAME: "default",
148 VnicEther.NAME: vnicEther,
149 VnicEther.DN: vnicEtherDn,
150 VnicEther.SWITCH_ID: "A-B",
151 VnicEther.ORDER: order,
152 "adminHostPort": "ANY",
153 VnicEther.ADMIN_VCON: "any",
154 VnicEther.ADDR: macAddr,
155 VnicEther.NW_TEMPL_NAME: templName,
156 VnicEther.MTU: "1500"}
157 handle.AddManagedObject(obj, VnicEther.ClassId(), params, True)
160 def remove_interface(handle=None, vnicEtherDn=None):
162 Remove interface specified by Distinguished Name (vnicEtherDn)
164 print(" Removing interface: {}".format(vnicEtherDn))
165 obj = handle.GetManagedObject(
166 None, VnicEther.ClassId(), {VnicEther.DN: vnicEtherDn})
167 handle.RemoveManagedObject(obj)
170 def read_yaml_file(yamlFile):
172 Read vnic config from yaml file
174 # TODO: add check if vnic templates specified in file exist on UCS
175 with open(yamlFile, 'r') as stream:
176 return yaml.safe_load(stream)
179 def set_network(handle=None, yamlFile=None):
181 Configure VLANs on POD according specified network
183 # add interfaces and bind them with vNIC templates
184 print("\nRECONFIGURING VNICs...")
185 pod_data = read_yaml_file(yamlFile)
186 network = pod_data['network']
188 for index, server in enumerate(get_servers(handle)):
189 # Assign template to interface
190 for iface, data in network.iteritems():
191 add_interface(handle, server.Dn, iface, data['template'], data[
192 'order'], data['mac-list'][index])
194 # Remove other interfaces which have not assigned required vnic
196 vnics = get_vnics(handle, server)
198 if not any(data['template'] in vnic.OperNwTemplName for
199 iface, data in network.iteritems()):
200 remove_interface(handle, vnic.Dn)
201 print(" {} removed, template: {}".format(
202 vnic.Name, vnic.OperNwTemplName))
204 # Set boot policy template
205 if INSTALLER not in server.Dn:
206 set_boot_policy(handle, server, pod_data['boot-policy'])
209 if __name__ == "__main__":
210 print("\n*** SKIPING RECONFIGURATION.***\n")
212 # Latest urllib2 validate certs by default
213 # The process wide "revert to the old behaviour" hook is to monkeypatch
215 # https://bugs.python.org/issue22417
217 if hasattr(ssl, '_create_unverified_context'):
218 ssl._create_default_https_context = ssl._create_unverified_context
221 parser = optparse.OptionParser()
222 parser.add_option('-i', '--ip', dest="ip",
223 help="[Mandatory] UCSM IP Address")
224 parser.add_option('-u', '--username', dest="userName",
225 help="[Mandatory] Account Username for UCSM Login")
226 parser.add_option('-p', '--password', dest="password",
227 help="[Mandatory] Account Password for UCSM Login")
228 parser.add_option('-f', '--file', dest="yamlFile",
229 help=("[Optional] Yaml file contains network "
230 "config you want to set on UCS POD1"))
231 (options, args) = parser.parse_args()
235 parser.error("Provide UCSM IP Address")
236 if not options.userName:
238 parser.error("Provide UCSM UserName")
239 if not options.password:
240 options.password = getpassword("UCSM Password:")
242 handle.Login(options.ip, options.userName, options.password)
244 # Change vnic template if specified in cli option
245 if (options.yamlFile is not None):
246 set_network(handle, options.yamlFile)
249 print("\nWait until Overall Status of all nodes is OK...")
250 timeout = time.time() + 60 * 10 # 10 minutes timeout
253 for server in get_servers(handle):
254 if server.OperState == "power-off":
255 boot_server(handle, server)
256 if server.OperState == "pending-reboot":
257 ack_pending(handle, server)
258 list_of_states.append(server.OperState)
259 print(" {}, {} seconds remains.".format(
260 list_of_states, round(timeout - time.time())))
261 if all(state == "ok" for state in list_of_states):
263 if time.time() > timeout:
264 raise Exception("Timeout reached while waiting for OK status.")
267 # Show current vnic MACs and VLANs
268 get_network_config(handle)
272 except Exception as err:
274 print("Exception:", str(err))
278 traceback.print_exc(file=sys.stdout)