blob: cf52512baeea40a995227e598f0ef162ed00e9ba [file] [log] [blame]
Jiri Broulik0ce9fc92017-02-01 23:10:40 +01001# -*- coding: utf-8 -*-
2'''
3Nova state that ensures that defined flavor is present
4'''
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 '''
Adam Tenglere8afccc2017-06-27 17:57:21 +000015 return 'novang' if 'novang.flavor_list' in __salt__ else False
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 Broulika2c79292017-02-05 21:01:38 +010038def quota_present(tenant_name, profile, name=None, **kwargs):
39 '''
40 Ensures that the nova quota exists
41 '''
42 changes = {}
43 for key, value in kwargs.items():
44 quota = __salt__['novang.quota_get'](key, tenant_name, profile)
45 if quota != value:
46 arg = {}
47 arg[key] = value
48 changes[key] = value
49 __salt__['novang.quota_update'](tenant_name, profile, **arg)
50 if bool(changes):
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010051 return _updated(tenant_name, 'tenant', changes)
Jiri Broulika2c79292017-02-05 21:01:38 +010052 else:
53 return _no_change(tenant_name, 'tenant')
54
Jiri Broulika2c79292017-02-05 21:01:38 +010055
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010056def availability_zone_present(name=None, availability_zone=None, profile=None):
57 '''
58 Ensures that the nova availability zone exists
59 '''
60 name = availability_zone
61 zone_exists = __salt__['novang.availability_zone_get'](name, profile)
62 if zone_exists == False:
63 item_created = __salt__['novang.availability_zone_create'](name, availability_zone, profile)
64 if bool(item_created):
65 return _created(availability_zone, 'availabilty zone', item_created)
Jiri Broulika2c79292017-02-05 21:01:38 +010066 else:
Jiri Broulik70d9e3f2017-02-15 18:37:13 +010067 return _already_exists(availability_zone, 'availabilty zone')
68 return existing_availability_zones
69
Damian Szeluga5dca0f02017-04-13 17:27:15 +020070def aggregate_present(name=None, aggregate=None, profile=None):
71 '''
72 Ensures that the nova aggregate exists
73 '''
74 name = aggregate
75 aggregate_exists = __salt__['novang.aggregate_get'](name, profile)
76 if aggregate_exists == False:
77 item_created = __salt__['novang.aggregate_create'](name, aggregate, profile)
78 if bool(item_created):
79 return _created(aggregate, 'aggregate', item_created)
80 else:
81 return _already_exists(aggregate, 'aggregate')
82 return existing_aggregate
83
Richard Felkl55d1f572017-02-15 16:41:53 +010084
85def instance_present(name, flavor, image, networks, security_groups=None, profile=None, tenant_name=None):
86 ret = {'name': name,
87 'changes': {},
88 'result': True,
89 'comment': 'Instance "{0}" already exists'.format(name)}
90 kwargs = {}
91 nics = []
92 existing_instances = __salt__['novang.server_list'](profile, tenant_name)
93 if name in existing_instances:
94 return ret
Adam Tenglere8afccc2017-06-27 17:57:21 +000095 existing_flavors = __salt__['novang.flavor_list'](profile)
Richard Felkl55d1f572017-02-15 16:41:53 +010096 if flavor in existing_flavors:
Ondrej Smolab7b0dda2017-02-28 14:36:46 +010097 flavor_id = existing_flavors[flavor]['id']
Richard Felkl55d1f572017-02-15 16:41:53 +010098 else:
99 return {'name': name,
100 'changes': {},
101 'result': False,
102 'comment': 'Flavor "{0}" doesn\'t exists'.format(flavor)}
103
Adam Tenglere8afccc2017-06-27 17:57:21 +0000104 existing_image = __salt__['novang.image_list'](image, profile)
Richard Felkl55d1f572017-02-15 16:41:53 +0100105 if not existing_image:
106 return {'name': name,
107 'changes': {},
108 'result': False,
109 'comment': 'Image "{0}" doesn\'t exists'.format(image)}
110 else:
111 image_id = existing_image.get(image).get('id')
112 if security_groups is not None:
113 kwargs['security_groups'] = []
114 for secgroup in security_groups:
115 existing_secgroups = __salt__['novang.secgroup_list'](profile, tenant_name)
116 if not secgroup in existing_secgroups:
117 return {'name': name,
118 'changes': {},
119 'result': False,
120 'comment': 'Security group "{0}" doesn\'t exists'.format(secgroup)}
121 else:
122 kwargs['security_groups'].append(secgroup)
123 for net in networks:
124 existing_network = __salt__['novang.network_show'](net.get('name'), profile)
125 if not existing_network:
126 return {'name': name,
127 'changes': {},
128 'result': False,
129 'comment': 'Network "{0}" doesn\'t exists'.format(net.get(name))}
130 else:
131 network_id = existing_network.get('id')
132 if net.get('v4_fixed_ip') is not None:
133 nics.append({'net-id': network_id, 'v4-fixed-ip': net.get('v4_fixed_ip')})
134 else:
135 nics.append({'net-id': network_id})
136 kwargs['nics'] = nics
137 new_instance_id = __salt__['novang.boot'] (name, flavor_id, image_id, profile, tenant_name, **kwargs)
138 return {'name': name,
139 'changes': {},
140 'result': True,
141 'comment': 'Instance "{0}" was successfuly created'.format(name)}
Jiri Broulik70d9e3f2017-02-15 18:37:13 +0100142
143def _already_exists(name, resource):
144 changes_dict = {'name': name,
145 'changes': {},
146 'result': True}
147 changes_dict['comment'] = \
148 '{0} {1} already exists'.format(resource, name)
149 return changes_dict
150
151
152def _created(name, resource, resource_definition):
153 changes_dict = {'name': name,
154 'changes': resource_definition,
155 'result': True,
156 'comment': '{0} {1} created'.format(resource, name)}
157 return changes_dict
158
159def _updated(name, resource, resource_definition):
160 changes_dict = {'name': name,
161 'changes': resource_definition,
162 'result': True,
163 'comment': '{0} {1} tenant was updated'.format(resource, name)}
164 return changes_dict
165
166def _update_failed(name, resource):
167 changes_dict = {'name': name,
168 'changes': {},
169 'comment': '{0} {1} failed to update'.format(resource, name),
170 'result': False}
171 return changes_dict
172
173def _no_change(name, resource, test=False):
174 changes_dict = {'name': name,
175 'changes': {},
176 'result': True}
177 if test:
178 changes_dict['comment'] = \
179 '{0} {1} will be {2}'.format(resource, name, test)
180 else:
181 changes_dict['comment'] = \
182 '{0} {1} is in correct state'.format(resource, name)
Damian Szeluga5dca0f02017-04-13 17:27:15 +0200183 return changes_dict
Adam Tenglere8afccc2017-06-27 17:57:21 +0000184