fix container image and use latest code
[samplevnf.git] / VNFs / DPPD-PROX / helper-scripts / rapid / stackdeployment.py
1 #!/usr/bin/python
2
3 ##
4 ## Copyright (c) 2020 Intel Corporation
5 ##
6 ## Licensed under the Apache License, Version 2.0 (the "License");
7 ## you may not use this file except in compliance with the License.
8 ## You may obtain a copy of the License at
9 ##
10 ##     http://www.apache.org/licenses/LICENSE-2.0
11 ##
12 ## Unless required by applicable law or agreed to in writing, software
13 ## distributed under the License is distributed on an "AS IS" BASIS,
14 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ## See the License for the specific language governing permissions and
16 ## limitations under the License.
17 ##
18
19 import os_client_config
20 import heatclient
21 from heatclient.client import Client as Heat_Client
22 from keystoneclient.v3 import Client as Keystone_Client
23 from heatclient.common import template_utils
24 from novaclient import client as NovaClient
25 import yaml
26 import os
27 import time
28 import sys
29 from collections import OrderedDict
30 from rapid_log import RapidLog
31
32 class StackDeployment(object):
33     """Deployment class to create VMs for test execution in OpenStack
34     environment.
35     """
36     def __init__(self, cloud_name):
37 #        RapidLog.log_init('CREATEStack.log', 'DEBUG', 'INFO', '2020.05.05')
38         self.dp_ips = []
39         self.dp_macs = []
40         self.mngmt_ips = []
41         self.names = []
42         self.number_of_servers = 0
43         self.cloud_name = cloud_name
44         self.heat_template = 'L6_heat_template.yaml'
45         self.heat_param = 'params_rapid.yaml'
46         self.cloud_config = os_client_config.OpenStackConfig().get_all_clouds()
47         ks_client = None
48         for cloud in self.cloud_config:
49             if cloud.name == self.cloud_name:
50                 ks_client = Keystone_Client(**cloud.config['auth'])
51                 break
52         if ks_client == None:
53             sys.exit()
54         heat_endpoint = ks_client.service_catalog.url_for(service_type='orchestration',
55         endpoint_type='publicURL')
56         self.heatclient = Heat_Client('1', heat_endpoint, token=ks_client.auth_token)
57         self.nova_client = NovaClient.Client(2, **cloud.config['auth']) 
58
59     def generate_paramDict(self):
60         for output in self.stack.output_list()['outputs']:
61             output_value = self.stack.output_show(output['output_key'])['output']['output_value']
62             for server_group_output in output_value:
63                 if (output['output_key'] == 'number_of_servers'):
64                     self.number_of_servers += int (server_group_output)
65                 elif (output['output_key'] == 'mngmt_ips'):
66                     for ip in server_group_output:
67                         self.mngmt_ips.append(ip)
68                 elif (output['output_key'] == 'data_plane_ips'):
69                     for dps in server_group_output:
70                         self.dp_ips.append(dps)
71                 elif (output['output_key'] == 'data_plane_macs'):
72                     for mac in server_group_output:
73                         self.dp_macs.append(mac)
74                 elif (output['output_key'] == 'server_name'):
75                     for name in server_group_output:
76                         self.names.append(name)
77
78     def print_paramDict(self, user, dataplane_subnet_mask):
79         if not(len(self.dp_ips) == len(self.dp_macs) == len(self.mngmt_ips)):
80             sys.exit()
81         _ENV_FILE_DIR = os.path.dirname(os.path.realpath(__file__))
82         env_file = os.path.join(_ENV_FILE_DIR, self.stack.stack_name)+ '.env'
83         with open(env_file, 'w') as env_file:
84             env_file.write('[rapid]\n')
85             env_file.write('total_number_of_machines = {}\n'.format(str(self.number_of_servers)))
86             env_file.write('\n')
87             for count in range(self.number_of_servers):
88                 env_file.write('[M' + str(count+1) + ']\n')
89                 env_file.write('name = {}\n'.format(str(self.names[count])))
90                 env_file.write('admin_ip = {}\n'.format(str(self.mngmt_ips[count])))
91                 if type(self.dp_ips[count]) == list:
92                     for i, dp_ip in enumerate(self.dp_ips[count], start = 1):
93                         env_file.write('dp_ip{} = {}/{}\n'.format(i, str(dp_ip),
94                             dataplane_subnet_mask))
95                 else:
96                     env_file.write('dp_ip1 = {}/{}\n'.format(str(self.dp_ips[count]),
97                         dataplane_subnet_mask))
98                 if type(self.dp_macs[count]) == list:
99                     for i, dp_mac in enumerate(self.dp_macs[count], start = 1):
100                         env_file.write('dp_mac{} = {}\n'.format(i, str(dp_mac)))
101                 else:
102                     env_file.write('dp_mac1 = {}\n'.format(str(self.dp_macs[count])))
103                 env_file.write('\n')
104             env_file.write('[ssh]\n')
105             env_file.write('key = {}\n'.format(self.key_name))
106             env_file.write('user = {}\n'.format(user))
107             env_file.write('\n')
108             env_file.write('[Varia]\n')
109             env_file.write('vim = OpenStack\n')
110             env_file.write('stack = {}\n'.format(self.stack.stack_name))
111
112     def create_stack(self, stack_name, stack_file_path, heat_parameters):
113         files, template = template_utils.process_template_path(stack_file_path)
114         stack_created = self.heatclient.stacks.create(stack_name = stack_name,
115                 template = template, parameters = heat_parameters,
116                 files = files)
117         stack = self.heatclient.stacks.get(stack_created['stack']['id'],
118                 resolve_outputs=True)
119         # Poll at 5 second intervals, until the status is no longer 'BUILD'
120         while stack.stack_status == 'CREATE_IN_PROGRESS':
121             print('waiting..')
122             time.sleep(5)
123             stack = self.heatclient.stacks.get(stack_created['stack']['id'], resolve_outputs=True)
124         if stack.stack_status == 'CREATE_COMPLETE':    
125             return stack
126         else:
127             RapidLog.exception('Error in stack deployment')
128
129     def create_key(self):
130         if os.path.exists(self.key_name):
131             public_key_file = "{}.pub".format(self.key_name)
132             if not os.path.exists(public_key_file):
133                 RapidLog.critical('Keypair {}.pub does not exist'.format(
134                     self.key_name))
135             with open(public_key_file, mode='rb') as public_file:
136                 public_key = public_file.read()
137         else:
138             public_key = None
139         keypair = self.nova_client.keypairs.create(name = self.key_name, 
140                 public_key = public_key)
141         # Create a file for writing that can only be read and written by owner
142         if not os.path.exists(self.key_name):
143             fp = os.open(self.key_name, os.O_WRONLY | os.O_CREAT, 0o600)
144             with os.fdopen(fp, 'w') as f:
145                     f.write(keypair.private_key)
146         RapidLog.info('Keypair {} created'.format(self.key_name))
147
148     def IsDeployed(self, stack_name):
149         for stack in self.heatclient.stacks.list():
150             if stack.stack_name == stack_name:
151                 RapidLog.info('Stack already existing: {}'.format(stack_name))
152                 self.stack = stack
153                 return True
154         return False
155
156     def IsKey(self):
157         keypairs = self.nova_client.keypairs.list()
158         if next((x for x in keypairs if x.name == self.key_name), None):
159             RapidLog.info('Keypair {} already exists'.format(self.key_name))
160             return True
161         return False
162
163     def deploy(self, stack_name, heat_template, heat_param):
164         heat_parameters_file = open(heat_param)
165         heat_parameters = yaml.load(heat_parameters_file,
166                 Loader=yaml.BaseLoader)['parameters']
167         heat_parameters_file.close()
168         self.key_name = heat_parameters['PROX_key']
169         if not self.IsDeployed(stack_name):
170             if not self.IsKey():
171                 self.create_key()
172             self.stack = self.create_stack(stack_name, heat_template,
173                     heat_parameters)
174
175     def generate_env_file(self, user = 'centos', dataplane_subnet_mask = '24'):
176         self.generate_paramDict()
177         self.print_paramDict(user, dataplane_subnet_mask)