1 # Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 from neutronclient.common.utils import str2bool
19 class ServerType(enum.Enum):
21 The cluter server types supported
24 baremetal = 'baremetal'
27 class ContainerOrchestrationEngine(enum.Enum):
29 The types of supported COEs
31 kubernetes = 'kubernetes'
36 class DockerStorageDriver(enum.Enum):
38 Drivers for managing storage for the images in the container's writable
41 devicemapper = 'devicemapper'
45 class ClusterTemplateConfig(object):
47 Configuration settings for OpenStack cluster template creation
50 def __init__(self, **kwargs):
53 :param name: the cluster template's name (required)
54 :param image: name or ID of the base image in Glance used to boot the
55 cluster's servers. The image must have the attribute
56 'os-distro' defined as appropriate for the cluster
58 :param keypair: name or ID of the keypair to gain cluster machine
60 :param network_driver: The name of a network driver for providing the
61 networks for the containers. Note that this is
62 different and separate from the Neutron network
63 for the bay/cluster. The operation and
64 networking model are specific to the particular
66 :param external_net: name or IDof the external Neutron network to
67 provide connectivity to the cluster (required)
68 :param floating_ip_enabled: Whether enable or not using the floating IP
69 of cloud provider. Some cloud providers
70 used floating IP, some used public IP,
71 thus Magnum provide this option for
72 specifying the choice of using floating IP
74 :param docker_volume_size: The size in GB for the local storage on each
75 server for the Docker daemon to cache the
76 images and host the containers. Cinder
77 volumes provide the storage. The default is
78 25 GB. For the devicemapper storage driver,
79 the minimum value is 3GB. For the overlay
80 storage driver, the minimum value is 1GB.
82 :param server_type: ServerType enumeration (default - vm)
83 :param flavor: name or ID of the nova flavor for booting the node
84 servers (default - m1.small)
85 :param master_flavor: name or ID of the nova flavor of the master node
86 for this cluster (optional)
87 :param coe: ContainerOrchestrationEngine enum instance
88 (default - kubernetes)
89 :param fixed_net: name of a Neutron network to provide connectivity
90 to the internal network for the cluster
92 :param fixed_subnet: Fixed subnet that are using to allocate network
93 address for nodes in bay/cluster (optional)
94 :param registry_enabled: Docker images by default are pulled from the
95 public Docker registry, but in some cases,
96 users may want to use a private registry.
97 This option provides an alternative registry
98 based on the Registry V2: Magnum will create a
99 local registry in the bay/cluster backed by
100 swift to host the images (default - True)
101 :param insecure_registry: The URL pointing to the user's own private
102 insecure docker registry to deploy and run
103 docker containers (optional)
104 :param docker_storage_driver: DockerStorageDriver enum instance to
105 manage storage for the images and
106 container's writable layer
107 (default - devicemapper)
108 :param dns_nameserver: The DNS nameserver for the servers and
109 containers in the bay/cluster to use.
110 This is configured in the private Neutron
111 network for the bay/cluster.
112 (default provided by Magnum - 8.8.8.8)
113 :param public: denotes whether or not the cluster template is public
115 :param tls_disabled: denotes whether or not TLS should be enabled
117 :param http_proxy: host:port for a proxy to use when direct HTTP
118 access from the servers to sites on the external
119 internet is blocked (optional)
120 :param https_proxy: host:port for a proxy to use when direct HTTPS
121 access from the servers to sites on the external
122 internet is blocked (optional)
123 :param no_proxy: comma separated list of IPs that should not be
124 redirected through the proxy (optional)
125 :param volume_driver: The name of a volume driver for managing the
126 persistent storage for the containers. The
127 functionality supported are specific to the
129 :param master_lb_enabled: Since multiple masters may exist in a
130 bay/cluster, a Neutron load balancer is
131 created to provide the API endpoint for the
132 bay/cluster and to direct requests to the
133 masters. In some cases, such as when the
134 LBaaS service is not available, this option
135 can be set to false to create a bay/cluster
136 without the load balancer. In this case, one
137 of the masters will serve as the API endpoint
139 :param labels: Arbitrary labels in the form of a dict. The accepted
140 keys and valid values are defined in the bay/cluster
141 drivers. They are used as a way to pass additional
142 parameters that are specific to a bay/cluster driver.
145 self.name = kwargs.get('name')
146 self.image = kwargs.get('image')
147 self.keypair = kwargs.get('keypair')
148 self.network_driver = kwargs.get('network_driver')
149 self.external_net = kwargs.get('external_net')
150 self.floating_ip_enabled = str2bool(
151 str(kwargs.get('floating_ip_enabled', True)))
152 self.docker_volume_size = int(kwargs.get('docker_volume_size', 3))
153 self.server_type = map_server_type(
154 kwargs.get('server_type', ServerType.vm))
155 self.flavor = kwargs.get('flavor')
156 self.master_flavor = kwargs.get('master_flavor')
158 kwargs.get('coe', ContainerOrchestrationEngine.kubernetes))
159 self.fixed_net = kwargs.get('fixed_net')
160 self.fixed_subnet = kwargs.get('fixed_subnet')
161 self.registry_enabled = str2bool(
162 str(kwargs.get('registry_enabled', True)))
163 self.insecure_registry = kwargs.get('insecure_registry')
164 self.docker_storage_driver = map_docker_storage_driver(
165 kwargs.get('docker_storage_driver',
166 DockerStorageDriver.devicemapper))
167 self.dns_nameserver = kwargs.get('dns_nameserver')
168 self.public = str2bool(str(kwargs.get('public', False)))
169 self.tls_disabled = str2bool(str(kwargs.get('tls_disabled', False)))
170 self.http_proxy = kwargs.get('http_proxy')
171 self.https_proxy = kwargs.get('https_proxy')
172 self.no_proxy = kwargs.get('no_proxy')
173 self.volume_driver = kwargs.get('volume_driver')
174 self.master_lb_enabled = str2bool(
175 str(kwargs.get('master_lb_enabled', True)))
176 self.labels = kwargs.get('labels')
178 if (not self.name or not self.image or not self.keypair
179 or not self.external_net):
180 raise ClusterTemplateConfigError(
181 'The attributes name, image, keypair, and '
182 'external_net are required for ClusterTemplateConfig')
184 def magnum_dict(self):
186 Returns a dictionary object representing this object.
187 This is meant to be sent into as kwargs into the Magnum client
189 :return: the dictionary object
194 out['name'] = self.name
196 out['image_id'] = self.image
198 out['keypair_id'] = self.keypair
199 if self.network_driver:
200 out['network_driver'] = self.network_driver
201 if self.external_net:
202 out['external_network_id'] = self.external_net
203 if self.floating_ip_enabled:
204 out['floating_ip_enabled'] = self.floating_ip_enabled
205 if self.docker_volume_size:
206 out['docker_volume_size'] = self.docker_volume_size
208 out['server_type'] = self.server_type.value
210 out['flavor_id'] = self.flavor
211 if self.master_flavor:
212 out['master_flavor_id'] = self.master_flavor
214 out['coe'] = self.coe.value
216 out['fixed_network'] = self.fixed_net
217 if self.fixed_subnet:
218 out['fixed_subnet'] = self.fixed_subnet
219 if self.registry_enabled:
220 out['registry_enabled'] = self.registry_enabled
221 if self.insecure_registry:
222 out['insecure_registry'] = self.insecure_registry
223 if self.docker_storage_driver:
224 out['docker_storage_driver'] = self.docker_storage_driver.value
225 if self.dns_nameserver:
226 out['dns_nameserver'] = self.dns_nameserver
228 out['public'] = self.public
229 if self.tls_disabled:
230 out['tls_disabled'] = self.tls_disabled
232 out['http_proxy'] = self.http_proxy
234 out['https_proxy'] = self.https_proxy
236 out['no_proxy'] = self.no_proxy
237 if self.volume_driver:
238 out['volume_driver'] = self.volume_driver
239 if self.master_lb_enabled:
240 out['master_lb_enabled'] = self.master_lb_enabled
242 out['labels'] = self.labels
246 class ClusterTemplateConfigError(Exception):
248 Exception to be thrown when a cluster template configuration is incorrect
252 def map_server_type(server_type):
254 Takes a the server_type value maps it to the ServerType enum. When None
256 :param server_type: the server_type value to map
257 :return: the ServerType enum object
258 :raise: ClusterTemplateConfigError if value is invalid
262 if isinstance(server_type, ServerType):
264 elif isinstance(server_type, str):
265 for this_type in ServerType:
266 if this_type.value == server_type:
268 raise ClusterTemplateConfigError(
269 'Invalid server type - ' + server_type)
274 Takes a the coe value maps it to the ContainerOrchestrationEngine enum.
275 When None return None
276 :param coe: the COE value to map
277 :return: the ContainerOrchestrationEngine enum object
278 :raise: ClusterTemplateConfigError if value is invalid
282 if isinstance(coe, ContainerOrchestrationEngine):
284 elif isinstance(coe, str):
285 for this_type in ContainerOrchestrationEngine:
286 if this_type.value == coe:
288 raise ClusterTemplateConfigError('Invalid COE - ' + coe)
291 def map_docker_storage_driver(driver):
293 Takes a the coe value maps it to the ContainerOrchestrationEngine enum.
294 When None return None
295 :param driver: the docker storage driver value to map
296 :return: the DockerStorageDriver enum object
297 :raise: ClusterTemplateConfigError if value is invalid
301 if isinstance(driver, DockerStorageDriver):
303 elif isinstance(driver, str):
304 for this_type in DockerStorageDriver:
305 if this_type.value == driver:
307 raise ClusterTemplateConfigError(
308 'Invalid DockerStorageDriver - ' + driver)