96f8c9ba932cd09d217e5e923f2516df455431b5
[snaps.git] / snaps / openstack / create_qos.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 import logging
17
18 import enum
19 from cinderclient.exceptions import NotFound
20
21 from snaps.openstack.openstack_creator import OpenStackVolumeObject
22 from snaps.openstack.utils import cinder_utils
23
24 __author__ = 'spisarski'
25
26 logger = logging.getLogger('create_qos')
27
28 IMAGE_ACTIVE_TIMEOUT = 600
29 POLL_INTERVAL = 3
30 STATUS_ACTIVE = 'active'
31
32
33 class OpenStackQoS(OpenStackVolumeObject):
34     """
35     Class responsible for managing an qos in OpenStack
36     """
37
38     def __init__(self, os_creds, qos_settings):
39         """
40         Constructor
41         :param os_creds: The OpenStack connection credentials
42         :param qos_settings: The qos settings
43         :return:
44         """
45         super(self.__class__, self).__init__(os_creds)
46
47         self.qos_settings = qos_settings
48         self.__qos = None
49
50     def initialize(self):
51         """
52         Loads the existing QoS
53         :return: The QoS domain object or None
54         """
55         super(self.__class__, self).initialize()
56
57         self.__qos = cinder_utils.get_qos(
58             self._cinder, qos_settings=self.qos_settings)
59
60         return self.__qos
61
62     def create(self):
63         """
64         Creates the qos in OpenStack if it does not already exist and returns
65         the domain QoS object
66         :return: The QoS domain object or None
67         """
68         self.initialize()
69
70         if not self.__qos:
71             self.__qos = cinder_utils.create_qos(
72                 self._cinder, self.qos_settings)
73
74             logger.info(
75                 'Created qos with name - %s', self.qos_settings.name)
76
77         return self.__qos
78
79     def clean(self):
80         """
81         Cleanse environment of all artifacts
82         :return: void
83         """
84         if self.__qos:
85             try:
86                 cinder_utils.delete_qos(self._cinder, self.__qos)
87             except NotFound:
88                 pass
89
90         self.__qos = None
91
92     def get_qos(self):
93         """
94         Returns the domain QoS object as it was populated when create() was
95         called
96         :return: the object
97         """
98         return self.__qos
99
100
101 class Consumer(enum.Enum):
102     """
103     QoS Specification consumer types
104     """
105     front_end = 'front-end'
106     back_end = 'back-end'
107     both = 'both'
108
109
110 class QoSSettings:
111     def __init__(self, **kwargs):
112         """
113         Constructor
114         :param name: the qos's name (required)
115         :param consumer: the qos's consumer type of the enum type Consumer
116                          (required)
117         :param specs: dict of key/values
118         """
119
120         self.name = kwargs.get('name')
121
122         if kwargs.get('consumer'):
123             self.consumer = map_consumer(kwargs['consumer'])
124         else:
125             self.consumer = None
126
127         self.specs = kwargs.get('specs')
128         if not self.specs:
129             self.specs = dict()
130
131         if not self.name or not self.consumer:
132             raise QoSSettingsError(
133                 "The attributes name and consumer are required")
134
135
136 def map_consumer(consumer):
137     """
138     Takes a the protocol value maps it to the Consumer enum. When None return
139     None
140     :param consumer: the value to map to the Enum
141     :return: the Protocol enum object
142     :raise: Exception if value is invalid
143     """
144     if not consumer:
145         return None
146     elif isinstance(consumer, Consumer):
147         return consumer
148     else:
149         proto_str = str(consumer)
150         if proto_str == 'front-end':
151             return Consumer.front_end
152         elif proto_str == 'back-end':
153             return Consumer.back_end
154         elif proto_str == 'both':
155             return Consumer.both
156         else:
157             raise QoSSettingsError('Invalid Consumer - ' + proto_str)
158
159
160 class QoSSettingsError(Exception):
161     """
162     Exception to be thrown when an qos settings are incorrect
163     """
164
165     def __init__(self, message):
166         Exception.__init__(self, message)
167
168
169 class QoSCreationError(Exception):
170     """
171     Exception to be thrown when an qos cannot be created
172     """
173
174     def __init__(self, message):
175         Exception.__init__(self, message)