|
1 # vim: tabstop=4 shiftwidth=4 softtabstop=4 |
|
2 |
|
3 # Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
6 # not use this file except in compliance with the License. You may obtain |
|
7 # a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
14 # License for the specific language governing permissions and limitations |
|
15 # under the License. |
|
16 |
|
17 |
|
18 import locale |
|
19 |
|
20 from lxml import etree |
|
21 |
|
22 from solaris_install.utils import encrypt_password |
|
23 |
|
24 |
|
25 DTD_URL = '/usr/share/lib/xml/dtd/service_bundle.dtd.1' |
|
26 DOCTYPE_STR = '<!DOCTYPE service_bundle SYSTEM "%s">' % DTD_URL |
|
27 |
|
28 |
|
29 def create_ncp_defaultfixed(addrtype, linkname, netid, ip_version, ip=None, |
|
30 route=None, nameservers=None): |
|
31 """ return an etree object representing fixed (static) networking |
|
32 """ |
|
33 svcbundle = etree.Element("service_bundle", type="profile", |
|
34 name="openstack") |
|
35 |
|
36 # create the network/physical service profile |
|
37 physical = etree.SubElement(svcbundle, "service", version="1", |
|
38 type="service", name="network/physical") |
|
39 instance = etree.SubElement(physical, "instance", enabled="true", |
|
40 name="default") |
|
41 pg = etree.SubElement(instance, "property_group", type="application", |
|
42 name="netcfg") |
|
43 etree.SubElement(pg, "propval", type="astring", name="active_ncp", |
|
44 value="DefaultFixed") |
|
45 |
|
46 # create the network/install service profile |
|
47 install = etree.SubElement(svcbundle, "service", version="1", |
|
48 type="service", name="network/install") |
|
49 instance = etree.SubElement(install, "instance", enabled="true", |
|
50 name="default") |
|
51 |
|
52 if ip_version == 4: |
|
53 pg4 = etree.SubElement(instance, "property_group", |
|
54 type="ipv4_interface", |
|
55 name="install_ipv4_interface_%d" % netid) |
|
56 etree.SubElement(pg4, "propval", type="astring", name="address_type", |
|
57 value=addrtype) |
|
58 |
|
59 if addrtype == "static": |
|
60 etree.SubElement(pg4, "propval", type="net_address_v4", |
|
61 name="static_address", value=ip) |
|
62 etree.SubElement(pg4, "propval", type="astring", name="name", |
|
63 value="%s/v4" % linkname) |
|
64 etree.SubElement(pg4, "propval", type="net_address_v4", |
|
65 name="default_route", value=route) |
|
66 else: |
|
67 etree.SubElement(pg4, "propval", type="astring", name="name", |
|
68 value="%s/dhcp" % linkname) |
|
69 else: |
|
70 if addrtype == "static": |
|
71 link = etree.SubElement(instance, "property_group", |
|
72 type="ipv6_interface", |
|
73 name="install_ipv6_interface_%d" % netid) |
|
74 etree.SubElement(link, "propval", type="astring", |
|
75 name="address_type", value="addrconf") |
|
76 etree.SubElement(link, "propval", type="astring", |
|
77 name="name", value="%s/aconf" % linkname) |
|
78 etree.SubElement(link, "propval", type="astring", |
|
79 name="stateless", value="no") |
|
80 etree.SubElement(link, "propval", type="astring", |
|
81 name="stateful", value="no") |
|
82 |
|
83 pg6 = etree.SubElement(instance, "property_group", |
|
84 type="ipv6_interface", |
|
85 name="install_ipv6_interface_%d_1" % netid) |
|
86 etree.SubElement(pg6, "propval", type="astring", |
|
87 name="address_type", value="static") |
|
88 etree.SubElement(pg6, "propval", type="net_address_v6", |
|
89 name="static_address", value=ip) |
|
90 etree.SubElement(pg6, "propval", type="astring", name="name", |
|
91 value="%s/v6" % linkname) |
|
92 else: |
|
93 pg6 = etree.SubElement(instance, "property_group", |
|
94 type="ipv6_interface", |
|
95 name="install_ipv6_interface_%d" % netid) |
|
96 etree.SubElement(pg6, "propval", type="astring", |
|
97 name="address_type", value="addrconf") |
|
98 etree.SubElement(pg6, "propval", type="astring", name="name", |
|
99 value="%s/dhcp" % linkname) |
|
100 etree.SubElement(pg6, "propval", type="astring", |
|
101 name="stateless", value="yes") |
|
102 etree.SubElement(pg6, "propval", type="astring", |
|
103 name="stateful", value="yes") |
|
104 |
|
105 # create DNS profile for static configurations |
|
106 if addrtype == "static" and nameservers is not None: |
|
107 dns = etree.SubElement(svcbundle, "service", version="1", |
|
108 type="service", name="network/dns/client") |
|
109 etree.SubElement(dns, "instance", enabled="true", name="default") |
|
110 pg = etree.SubElement(dns, "property_group", type="application", |
|
111 name="config") |
|
112 prop = etree.SubElement(pg, "property", type="net_address", |
|
113 name="nameserver") |
|
114 proplist = etree.SubElement(prop, "net_address_list") |
|
115 |
|
116 if isinstance(nameservers, str): |
|
117 etree.SubElement(proplist, "value_node", value=nameservers) |
|
118 elif isinstance(nameservers, list): |
|
119 for entry in nameservers: |
|
120 etree.SubElement(proplist, "value_node", value=entry) |
|
121 |
|
122 search = etree.SubElement(pg, "property", type="astring", |
|
123 name="search") |
|
124 etree.SubElement(search, "astring_list") |
|
125 |
|
126 return svcbundle |
|
127 |
|
128 |
|
129 def create_ncp_automatic(): |
|
130 """ return an etree object representing dynamic networking |
|
131 """ |
|
132 svcbundle = etree.Element("service_bundle", type="profile", |
|
133 name="openstack") |
|
134 |
|
135 # create the network/physical service profile |
|
136 physical = etree.SubElement(svcbundle, "service", version="1", |
|
137 type="service", name="network/physical") |
|
138 instance = etree.SubElement(physical, "instance", enabled="true", |
|
139 name="default") |
|
140 pg = etree.SubElement(instance, "property_group", type="application", |
|
141 name="netcfg") |
|
142 etree.SubElement(pg, "propval", type="astring", name="active_ncp", |
|
143 value="Automatic") |
|
144 |
|
145 return svcbundle |
|
146 |
|
147 |
|
148 def create_default_root_account(expire=None, sshkey=None): |
|
149 """ return an etree object representing the root account |
|
150 """ |
|
151 svcbundle = etree.Element("service_bundle", type="profile", |
|
152 name="openstack") |
|
153 service = etree.SubElement(svcbundle, "service", version="1", |
|
154 type="service", name="system/config-user") |
|
155 instance = etree.SubElement(service, "instance", enabled="true", |
|
156 name="default") |
|
157 root_pg = etree.SubElement(instance, "property_group", type="application", |
|
158 name="root_account") |
|
159 etree.SubElement(root_pg, "propval", type="astring", name="password", |
|
160 value="NP") |
|
161 etree.SubElement(root_pg, "propval", type="astring", name="type", |
|
162 value="normal") |
|
163 |
|
164 if expire is not None: |
|
165 etree.SubElement(root_pg, "propval", type="astring", name="expire", |
|
166 value=expire) |
|
167 |
|
168 if sshkey is not None: |
|
169 prop = etree.SubElement(root_pg, "property", type="astring", |
|
170 name="ssh_public_keys") |
|
171 alist = etree.SubElement(prop, "astring_list") |
|
172 etree.SubElement(alist, "value_node", value=sshkey) |
|
173 |
|
174 return svcbundle |
|
175 |
|
176 |
|
177 def create_root_ssh_keys(key): |
|
178 """ return an etree object to set a public SSH key for root |
|
179 """ |
|
180 svcbundle = etree.Element("service_bundle", type="profile", |
|
181 name="openstack") |
|
182 service = etree.SubElement(svcbundle, "service", version="1", |
|
183 type="service", name="system/config-user") |
|
184 instance = etree.SubElement(service, "instance", enabled="true", |
|
185 name="default") |
|
186 root_pg = etree.SubElement(instance, "property_group", type="application", |
|
187 name="root_account") |
|
188 prop = etree.SubElement(root_pg, "property", type="astring", |
|
189 name="ssh_public_keys") |
|
190 alist = etree.SubElement(prop, "astring_list") |
|
191 etree.SubElement(alist, "value_node", value=key) |
|
192 return svcbundle |
|
193 |
|
194 |
|
195 def create_hostname(name): |
|
196 """ return an etree object representing the instance's hostname |
|
197 """ |
|
198 |
|
199 svcbundle = etree.Element("service_bundle", type="profile", |
|
200 name="openstack") |
|
201 service = etree.SubElement(svcbundle, "service", version="1", |
|
202 type="service", name="system/identity") |
|
203 instance = etree.SubElement(service, "instance", enabled="true", |
|
204 name="node") |
|
205 pg = etree.SubElement(instance, "property_group", type="application", |
|
206 name="config") |
|
207 etree.SubElement(pg, "propval", type="astring", name="nodename", |
|
208 value=name) |
|
209 |
|
210 return svcbundle |
|
211 |
|
212 |
|
213 def create_sc_profile(path, tree): |
|
214 """ create a file containing the proper XML headers and encoding for a |
|
215 given etree object |
|
216 """ |
|
217 encoding = locale.getpreferredencoding() |
|
218 if encoding == "646": |
|
219 # The C locale on Solaris is returned as '646'. Set it to 'US-ASCII' |
|
220 # instead |
|
221 encoding = 'US-ASCII' |
|
222 |
|
223 xml_str = etree.tostring(tree, pretty_print=True, encoding=encoding, |
|
224 xml_declaration=True, doctype=DOCTYPE_STR) |
|
225 |
|
226 # insert a comment just under the doctype line |
|
227 comment = etree.Comment(" Auto-generated by OpenStack Nova ") |
|
228 xml_list = xml_str.split("\n") |
|
229 xml_list.insert(2, etree.tostring(comment)) |
|
230 xml_str = "\n".join(xml_list) |
|
231 |
|
232 with open(path, "w+") as fh: |
|
233 fh.write(xml_str) |