blob: 46fae9ca52bae2361083665ac94155a9fc429bdc [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 '''
Richard Felkl55d1f572017-02-15 16:41:53 +010015 return 'novang' if 'nova.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)}
26 project = __salt__['nova.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:
32 __salt__['nova.flavor_create'](name, flavor_id, ram, disk, vcpus, profile)
33 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
Richard Felkl55d1f572017-02-15 16:41:53 +010070
71def instance_present(name, flavor, image, networks, security_groups=None, profile=None, tenant_name=None):
72 ret = {'name': name,
73 'changes': {},
74 'result': True,
75 'comment': 'Instance "{0}" already exists'.format(name)}
76 kwargs = {}
77 nics = []
78 existing_instances = __salt__['novang.server_list'](profile, tenant_name)
79 if name in existing_instances:
80 return ret
81 existing_flavors = __salt__['nova.flavor_list'](profile)
82 if flavor in existing_flavors:
Ondrej Smolab7b0dda2017-02-28 14:36:46 +010083 flavor_id = existing_flavors[flavor]['id']
Richard Felkl55d1f572017-02-15 16:41:53 +010084 else:
85 return {'name': name,
86 'changes': {},
87 'result': False,
88 'comment': 'Flavor "{0}" doesn\'t exists'.format(flavor)}
89
90 existing_image = __salt__['nova.image_list'](image, profile)
91 if not existing_image:
92 return {'name': name,
93 'changes': {},
94 'result': False,
95 'comment': 'Image "{0}" doesn\'t exists'.format(image)}
96 else:
97 image_id = existing_image.get(image).get('id')
98 if security_groups is not None:
99 kwargs['security_groups'] = []
100 for secgroup in security_groups:
101 existing_secgroups = __salt__['novang.secgroup_list'](profile, tenant_name)
102 if not secgroup in existing_secgroups:
103 return {'name': name,
104 'changes': {},
105 'result': False,
106 'comment': 'Security group "{0}" doesn\'t exists'.format(secgroup)}
107 else:
108 kwargs['security_groups'].append(secgroup)
109 for net in networks:
110 existing_network = __salt__['novang.network_show'](net.get('name'), profile)
111 if not existing_network:
112 return {'name': name,
113 'changes': {},
114 'result': False,
115 'comment': 'Network "{0}" doesn\'t exists'.format(net.get(name))}
116 else:
117 network_id = existing_network.get('id')
118 if net.get('v4_fixed_ip') is not None:
119 nics.append({'net-id': network_id, 'v4-fixed-ip': net.get('v4_fixed_ip')})
120 else:
121 nics.append({'net-id': network_id})
122 kwargs['nics'] = nics
123 new_instance_id = __salt__['novang.boot'] (name, flavor_id, image_id, profile, tenant_name, **kwargs)
124 return {'name': name,
125 'changes': {},
126 'result': True,
127 'comment': 'Instance "{0}" was successfuly created'.format(name)}
Jiri Broulik70d9e3f2017-02-15 18:37:13 +0100128
129def _already_exists(name, resource):
130 changes_dict = {'name': name,
131 'changes': {},
132 'result': True}
133 changes_dict['comment'] = \
134 '{0} {1} already exists'.format(resource, name)
135 return changes_dict
136
137
138def _created(name, resource, resource_definition):
139 changes_dict = {'name': name,
140 'changes': resource_definition,
141 'result': True,
142 'comment': '{0} {1} created'.format(resource, name)}
143 return changes_dict
144
145def _updated(name, resource, resource_definition):
146 changes_dict = {'name': name,
147 'changes': resource_definition,
148 'result': True,
149 'comment': '{0} {1} tenant was updated'.format(resource, name)}
150 return changes_dict
151
152def _update_failed(name, resource):
153 changes_dict = {'name': name,
154 'changes': {},
155 'comment': '{0} {1} failed to update'.format(resource, name),
156 'result': False}
157 return changes_dict
158
159def _no_change(name, resource, test=False):
160 changes_dict = {'name': name,
161 'changes': {},
162 'result': True}
163 if test:
164 changes_dict['comment'] = \
165 '{0} {1} will be {2}'.format(resource, name, test)
166 else:
167 changes_dict['comment'] = \
168 '{0} {1} is in correct state'.format(resource, name)
169 return changes_dict