blob: 4bc94a81a414d296b8560e25c288c029317eb279 [file] [log] [blame]
Jiri Broulik0ce9fc92017-02-01 23:10:40 +01001# -*- coding: utf-8 -*-
2'''
Jiri Broulik5589c012017-06-20 11:28:52 +02003Custom Nova state
Jiri Broulik0ce9fc92017-02-01 23:10:40 +01004'''
Jiri Broulika2c79292017-02-05 21:01:38 +01005import logging
Richard Felkl55d1f572017-02-15 16:41:53 +01006import collections
Jiri Broulika2c79292017-02-05 21:01:38 +01007from functools import wraps
8LOG = logging.getLogger(__name__)
Jiri Broulik0ce9fc92017-02-01 23:10:40 +01009
10
11def __virtual__():
12 '''
13 Only load if the nova module is in __salt__
14 '''
Jiri Broulik5589c012017-06-20 11:28:52 +020015 return 'novang'
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010016
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010017
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010018def flavor_present(name, flavor_id=0, ram=0, disk=0, vcpus=1, profile=None):
19 '''
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010020 Ensures that the nova flavor exists
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010021 '''
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010022 ret = {'name': name,
23 'changes': {},
24 'result': True,
25 'comment': 'Flavor "{0}" already exists'.format(name)}
Adam Tenglere8afccc2017-06-27 17:57:21 +000026 project = __salt__['novang.flavor_list'](profile)
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010027 if 'Error' in project:
28 pass
29 elif name in project:
30 pass
31 else:
Adam Tenglere8afccc2017-06-27 17:57:21 +000032 __salt__['novang.flavor_create'](name, flavor_id, ram, disk, vcpus, profile)
Jiri Broulik0ce9fc92017-02-01 23:10:40 +010033 ret['comment'] = 'Flavor {0} has been created'.format(name)
34 ret['changes']['Flavor'] = 'Created'
35 return ret
36
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010037
Jiri Broulik5589c012017-06-20 11:28:52 +020038def map_instances(name='cell1'):
39 '''
40 Ensures that the nova instances are mapped to cell
41 '''
42 ret = {'name': name,
43 'changes': {},
44 'result': False,
45 'comment': 'Cell "{0}" does not exists'.format(name)}
46 cell_uuid = __salt__['cmd.shell']('nova-manage cell_v2 list_cells 2>&- | grep ' + name + ' | tr -d \"\n\" | awk \'{print $4}\'')
Jiri Broulik7e72aa22017-07-03 16:05:11 +020047 if cell_uuid:
Jiri Broulik5589c012017-06-20 11:28:52 +020048 try:
49 __salt__['cmd.shell']('nova-manage cell_v2 map_instances --cell_uuid ' + cell_uuid)
50 ret['result'] = True
51 ret['comment'] = 'Instances were mapped to cell named {0}'.format(name)
52 ret['changes']['Instances'] = 'Mapped to cell named {0}'.format(name)
53 except:
54 ret['result'] = False
55 ret['comment'] = 'Error while mapping instances to cell named {0}'.format(name)
56 ret['changes']['Instances'] = 'Failed to map to cell named {0}'.format(name)
57 return ret
58
59
Jiri Broulika2c79292017-02-05 21:01:38 +010060def quota_present(tenant_name, profile, name=None, **kwargs):
61 '''
62 Ensures that the nova quota exists
63 '''
64 changes = {}
65 for key, value in kwargs.items():
66 quota = __salt__['novang.quota_get'](key, tenant_name, profile)
67 if quota != value:
68 arg = {}
69 arg[key] = value
70 changes[key] = value
71 __salt__['novang.quota_update'](tenant_name, profile, **arg)
72 if bool(changes):
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010073 return _updated(tenant_name, 'tenant', changes)
Jiri Broulika2c79292017-02-05 21:01:38 +010074 else:
75 return _no_change(tenant_name, 'tenant')
76
Jiri Broulika2c79292017-02-05 21:01:38 +010077
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010078def availability_zone_present(name=None, availability_zone=None, profile=None):
79 '''
80 Ensures that the nova availability zone exists
81 '''
82 name = availability_zone
83 zone_exists = __salt__['novang.availability_zone_get'](name, profile)
84 if zone_exists == False:
85 item_created = __salt__['novang.availability_zone_create'](name, availability_zone, profile)
86 if bool(item_created):
87 return _created(availability_zone, 'availabilty zone', item_created)
Jiri Broulika2c79292017-02-05 21:01:38 +010088 else:
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010089 return _already_exists(availability_zone, 'availabilty zone')
90 return existing_availability_zones
91
Damian Szeluga5dca0f02017-04-13 17:27:15 +020092def aggregate_present(name=None, aggregate=None, profile=None):
93 '''
94 Ensures that the nova aggregate exists
95 '''
96 name = aggregate
97 aggregate_exists = __salt__['novang.aggregate_get'](name, profile)
98 if aggregate_exists == False:
99 item_created = __salt__['novang.aggregate_create'](name, aggregate, profile)
100 if bool(item_created):
101 return _created(aggregate, 'aggregate', item_created)
102 else:
103 return _already_exists(aggregate, 'aggregate')
104 return existing_aggregate
105
Richard Felkl55d1f572017-02-15 16:41:53 +0100106
107def instance_present(name, flavor, image, networks, security_groups=None, profile=None, tenant_name=None):
108 ret = {'name': name,
109 'changes': {},
110 'result': True,
111 'comment': 'Instance "{0}" already exists'.format(name)}
112 kwargs = {}
113 nics = []
114 existing_instances = __salt__['novang.server_list'](profile, tenant_name)
115 if name in existing_instances:
116 return ret
Adam Tenglere8afccc2017-06-27 17:57:21 +0000117 existing_flavors = __salt__['novang.flavor_list'](profile)
Richard Felkl55d1f572017-02-15 16:41:53 +0100118 if flavor in existing_flavors:
Ondrej Smolab7b0dda2017-02-28 14:36:46 +0100119 flavor_id = existing_flavors[flavor]['id']
Richard Felkl55d1f572017-02-15 16:41:53 +0100120 else:
121 return {'name': name,
122 'changes': {},
123 'result': False,
124 'comment': 'Flavor "{0}" doesn\'t exists'.format(flavor)}
125
Adam Tenglere8afccc2017-06-27 17:57:21 +0000126 existing_image = __salt__['novang.image_list'](image, profile)
Richard Felkl55d1f572017-02-15 16:41:53 +0100127 if not existing_image:
128 return {'name': name,
129 'changes': {},
130 'result': False,
131 'comment': 'Image "{0}" doesn\'t exists'.format(image)}
132 else:
133 image_id = existing_image.get(image).get('id')
134 if security_groups is not None:
135 kwargs['security_groups'] = []
136 for secgroup in security_groups:
137 existing_secgroups = __salt__['novang.secgroup_list'](profile, tenant_name)
138 if not secgroup in existing_secgroups:
139 return {'name': name,
140 'changes': {},
141 'result': False,
142 'comment': 'Security group "{0}" doesn\'t exists'.format(secgroup)}
143 else:
144 kwargs['security_groups'].append(secgroup)
145 for net in networks:
146 existing_network = __salt__['novang.network_show'](net.get('name'), profile)
147 if not existing_network:
148 return {'name': name,
149 'changes': {},
150 'result': False,
151 'comment': 'Network "{0}" doesn\'t exists'.format(net.get(name))}
152 else:
153 network_id = existing_network.get('id')
154 if net.get('v4_fixed_ip') is not None:
155 nics.append({'net-id': network_id, 'v4-fixed-ip': net.get('v4_fixed_ip')})
156 else:
157 nics.append({'net-id': network_id})
158 kwargs['nics'] = nics
159 new_instance_id = __salt__['novang.boot'] (name, flavor_id, image_id, profile, tenant_name, **kwargs)
160 return {'name': name,
161 'changes': {},
162 'result': True,
163 'comment': 'Instance "{0}" was successfuly created'.format(name)}
Jiri Broulik70d9e3f2017-02-15 18:37:13 +0100164
165def _already_exists(name, resource):
166 changes_dict = {'name': name,
167 'changes': {},
168 'result': True}
169 changes_dict['comment'] = \
170 '{0} {1} already exists'.format(resource, name)
171 return changes_dict
172
173
174def _created(name, resource, resource_definition):
175 changes_dict = {'name': name,
176 'changes': resource_definition,
177 'result': True,
178 'comment': '{0} {1} created'.format(resource, name)}
179 return changes_dict
180
181def _updated(name, resource, resource_definition):
182 changes_dict = {'name': name,
183 'changes': resource_definition,
184 'result': True,
185 'comment': '{0} {1} tenant was updated'.format(resource, name)}
186 return changes_dict
187
188def _update_failed(name, resource):
189 changes_dict = {'name': name,
190 'changes': {},
191 'comment': '{0} {1} failed to update'.format(resource, name),
192 'result': False}
193 return changes_dict
194
195def _no_change(name, resource, test=False):
196 changes_dict = {'name': name,
197 'changes': {},
198 'result': True}
199 if test:
200 changes_dict['comment'] = \
201 '{0} {1} will be {2}'.format(resource, name, test)
202 else:
203 changes_dict['comment'] = \
204 '{0} {1} is in correct state'.format(resource, name)
Damian Szeluga5dca0f02017-04-13 17:27:15 +0200205 return changes_dict
Adam Tenglere8afccc2017-06-27 17:57:21 +0000206