1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
17
from pyrax.exceptions import NotFound
19
# fake exception for testing without pyrax
20
class NotFound(Exception):
23
from heat.common import exception
24
from heat.openstack.common import log as logging
26
from . import rackspace_resource
28
logger = logging.getLogger(__name__)
31
class CloudDBInstance(rackspace_resource.RackspaceResource):
33
Rackspace cloud database resource.
43
"Default": "utf8_general_ci",
50
"AllowedPattern": "[a-zA-Z0-9_]+[a-zA-Z0-9_@?#\s]*[a-zA-Z0-9_]+"
59
"AllowedPattern": "[a-zA-Z0-9_]+[a-zA-Z0-9_@?#\s]*[a-zA-Z0-9_]+"
64
"AllowedPattern": "[a-zA-Z0-9_]+[a-zA-Z0-9_@?#\s]*[a-zA-Z0-9_]+"
100
'Schema': database_schema
109
'Schema': user_schema
114
attributes_schema = {
115
"hostname": "Hostname of the instance",
116
"href": "Api endpoint reference of the instance"
119
def __init__(self, name, json_snippet, stack):
120
super(CloudDBInstance, self).__init__(name, json_snippet, stack)
124
def handle_create(self):
126
Create Rackspace Cloud DB Instance.
128
logger.debug("Cloud DB instance handle_create called")
129
self.sqlinstancename = self.properties['InstanceName']
130
self.flavor = self.properties['FlavorRef']
131
self.volume = self.properties['VolumeSize']
132
self.databases = self.properties.get('Databases', None)
133
self.users = self.properties.get('Users', None)
136
logger.info("Creating Cloud DB instance %s" % self.sqlinstancename)
137
instance = self.cloud_db().create(self.sqlinstancename,
140
if instance is not None:
141
self.resource_id_set(instance.id)
143
self.hostname = instance.hostname
144
self.href = instance.links[0]['href']
147
def check_create_complete(self, instance):
149
Check if cloud DB instance creation is complete.
151
instance.get() # get updated attributes
152
if instance.status == 'ERROR':
154
raise exception.Error("Cloud DB instance creation failed.")
156
if instance.status != 'ACTIVE':
159
logger.info("Cloud DB instance %s created (flavor:%s, volume:%s)" %
160
(self.sqlinstancename, self.flavor, self.volume))
162
for database in self.databases:
163
instance.create_database(
165
character_set=database['Character_set'],
166
collate=database['Collate'])
167
logger.info("Database %s created on cloud DB instance %s" %
168
(database['Name'], self.sqlinstancename))
172
for user in self.users:
173
if user['Databases']:
174
dbs = user['Databases']
175
instance.create_user(user['Name'], user['Password'], dbs)
176
logger.info("Cloud database user %s created successfully" %
180
def handle_delete(self):
182
Delete a Rackspace Cloud DB Instance.
184
logger.debug("CloudDBInstance handle_delete called.")
185
if self.resource_id is None:
189
instances = self.cloud_db().delete(self.resource_id)
192
self.resource_id = None
196
Validate any of the provided params
198
res = super(CloudDBInstance, self).validate()
202
# check validity of user and databases
203
users = self.properties.get('Users', None)
207
databases = self.properties.get('Databases', None)
210
'Databases property is required if Users property'
214
if not user['Databases']:
216
'Must provide access to at least one database for '
217
'user %s' % user['Name']}
219
missing_db = [db_name for db_name in user['Databases']
220
if db_name not in [db['Name'] for db in databases]]
223
'Database %s specified for user does not exist in '
224
'databases.' % missing_db}
228
if self.hostname is None and self.resource_id is not None:
229
dbinstance = self.cloud_db().get(self.resource_id)
230
self.hostname = dbinstance.hostname
235
if self.href is None and self.resource_id is not None:
236
dbinstance = self.cloud_db().get(self.resource_id)
237
self.href = self._gethref(dbinstance)
241
def _gethref(self, dbinstance):
242
if dbinstance is None or dbinstance.links is None:
245
for link in dbinstance.links:
246
if link['rel'] == 'self':
249
def _resolve_attribute(self, name):
250
if name == 'hostname':
251
return self._hostname()
258
# pyrax module is required to work with Rackspace cloud database provider.
259
# If it is not installed, don't register clouddatabase provider
260
def resource_mapping():
261
if rackspace_resource.PYRAX_INSTALLED:
263
'Rackspace::Cloud::DBInstance': CloudDBInstance,