def _get_signed_url(self, signal_type=SIGNAL): """Create properly formatted and pre-signed URL. This uses the created user for the credentials. See boto/auth.py::QuerySignatureV2AuthHandler :param signal_type: either WAITCONDITION or SIGNAL. """ try: stored = db_api.resource_data_get(self, 'ec2_signed_url') except exception.NotFound: stored = None if stored is not None: return stored try: access_key = db_api.resource_data_get(self, 'access_key') secret_key = db_api.resource_data_get(self, 'secret_key') except exception.NotFound: logger.warning( _('Cannot generate signed url, ' 'no stored access/secret key')) return waitcond_url = cfg.CONF.heat_waitcondition_server_url signal_url = waitcond_url.replace('/waitcondition', signal_type) host_url = urlutils.urlparse(signal_url) path = self.identifier().arn_url_path() # Note the WSGI spec apparently means that the webob request we end up # prcessing in the CFN API (ec2token.py) has an unquoted path, so we # need to calculate the signature with the path component unquoted, but # ensure the actual URL contains the quoted version... unquoted_path = urlutils.unquote(host_url.path + path) request = { 'host': host_url.netloc.lower(), 'verb': SIGNAL_VERB[signal_type], 'path': unquoted_path, 'params': { 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'AWSAccessKeyId': access_key, 'Timestamp': self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ") } } # Sign the request signer = ec2_utils.Ec2Signer(secret_key) request['params']['Signature'] = signer.generate(request) qs = urlutils.urlencode(request['params']) url = "%s%s?%s" % (signal_url.lower(), path, qs) db_api.resource_data_set(self, 'ec2_signed_url', url) return url
def _get_signed_url(self, signal_type=SIGNAL): """Create properly formatted and pre-signed URL. This uses the created user for the credentials. See boto/auth.py::QuerySignatureV2AuthHandler :param signal_type: either WAITCONDITION or SIGNAL. """ try: stored = db_api.resource_data_get(self, 'ec2_signed_url') except exception.NotFound: stored = None if stored is not None: return stored try: access_key = db_api.resource_data_get(self, 'access_key') secret_key = db_api.resource_data_get(self, 'secret_key') except exception.NotFound: logger.warning(_('Cannot generate signed url, ' 'no stored access/secret key')) return waitcond_url = cfg.CONF.heat_waitcondition_server_url signal_url = waitcond_url.replace('/waitcondition', signal_type) host_url = urlutils.urlparse(signal_url) path = self.identifier().arn_url_path() # Note the WSGI spec apparently means that the webob request we end up # prcessing in the CFN API (ec2token.py) has an unquoted path, so we # need to calculate the signature with the path component unquoted, but # ensure the actual URL contains the quoted version... unquoted_path = urlutils.unquote(host_url.path + path) request = {'host': host_url.netloc.lower(), 'verb': SIGNAL_VERB[signal_type], 'path': unquoted_path, 'params': {'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'AWSAccessKeyId': access_key, 'Timestamp': self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ") }} # Sign the request signer = ec2_utils.Ec2Signer(secret_key) request['params']['Signature'] = signer.generate(request) qs = urlutils.urlencode(request['params']) url = "%s%s?%s" % (signal_url.lower(), path, qs) db_api.resource_data_set(self, 'ec2_signed_url', url) return url
def test_adopt_with_resource_data_and_metadata(self): adopt_data = "{}" tmpl = template.Template({"Resources": {"foo": {"Type": "GenericResourceType"}}}) self.stack = parser.Stack( utils.dummy_context(), "test_stack", tmpl, stack_id=str(uuid.uuid4()), adopt_stack_data=json.loads(adopt_data), ) res = self.stack["foo"] res_data = { "status": "COMPLETE", "name": "foo", "resource_data": {"test-key": "test-value"}, "metadata": {"os_distro": "test-distro"}, "resource_id": "test-res-id", "action": "CREATE", "type": "GenericResourceType", } adopt = scheduler.TaskRunner(res.adopt, res_data) adopt() self.assertEqual("test-value", db_api.resource_data_get(res, "test-key")) self.assertEqual({"os_distro": "test-distro"}, res.metadata) self.assertEqual((res.ADOPT, res.COMPLETE), res.state)
def private_key(self): """Return the private SSH key for the resource.""" if self._private_key is None and self.id and self.properties["save_private_key"]: try: self._private_key = db_api.resource_data_get(self, "private_key") except exception.NotFound: pass return self._private_key or ""
def _get_user_id(self): try: return db_api.resource_data_get(self, 'user_id') except exception.NotFound: # Assume this is a resource that was created with # a previous version of heat and that the resource_id # is the user_id if self.resource_id: db_api.resource_data_set(self, 'user_id', self.resource_id) return self.resource_id
def handle_delete(self): client = self.neutron() for member in self.properties.get(self.MEMBERS): member_id = db_api.resource_data_get(self, member) try: client.delete_member(member_id) except NeutronClientException as ex: if ex.status_code != 404: raise ex db_api.resource_data_delete(self, member)
def private_key(self): """Return the private SSH key for the resource.""" if (self._private_key is None and self.id and self.properties[self.SAVE_PRIVATE_KEY]): try: self._private_key = db_api.resource_data_get(self, 'private_key') except exception.NotFound: pass return self._private_key or ""
def private_key(self): """Return the private SSH key for the resource.""" if (self._private_key is None and self.id and self.properties['save_private_key']): try: self._private_key = db_api.resource_data_get(self, 'private_key') except exception.NotFound: pass return self._private_key or ""
def _get_user_id(self): try: return db_api.resource_data_get(self, 'user_id') except exception.NotFound: # FIXME(shardy): This is a legacy hack for backwards compatibility # remove after an appropriate transitional period... # Assume this is a resource that was created with # a previous version of heat and that the resource_id # is the user_id if self.resource_id: db_api.resource_data_set(self, 'user_id', self.resource_id) return self.resource_id
def _delete_keypair(self): # Subclasses may optionally call this to delete a keypair created # via _create_keypair user_id = self._get_user_id() credential_id = db_api.resource_data_get(self, 'credential_id') try: self.keystone().delete_stack_domain_user_keypair( user_id=user_id, project_id=self.stack.stack_user_project_id, credential_id=credential_id) except ValueError: self.keystone().delete_ec2_keypair( user_id=user_id, credential_id=credential_id) for data_key in ('access_key', 'secret_key', 'credential_id'): try: db_api.resource_data_delete(self, data_key) except exception.NotFound: pass
def _secret_accesskey(self): ''' Return the user's access key, fetching it from keystone if necessary ''' if self._secret is None: if not self.resource_id: logger.warn( _('could not get secret for %(username)s ' 'Error:%(msg)s') % { 'username': self.properties[self.USER_NAME], 'msg': "resource_id not yet set" }) else: # First try to retrieve the secret from resource_data, but # for backwards compatibility, fall back to requesting from # keystone try: self._secret = db_api.resource_data_get(self, 'secret_key') except exception.NotFound: try: user_id = self._get_user().resource_id kp = self.keystone().get_ec2_keypair( user_id=user_id, access=self.resource_id) self._secret = kp.secret # Store the key in resource_data db_api.resource_data_set(self, 'secret_key', kp.secret, redact=True) # And the ID of the v3 credential db_api.resource_data_set(self, 'credential_id', kp.id, redact=True) except Exception as ex: logger.warn( _('could not get secret for %(username)s ' 'Error:%(msg)s') % { 'username': self.properties[self.USER_NAME], 'msg': ex }) return self._secret or '000-000-000'
def _delete_keypair(self): # Subclasses may optionally call this to delete a keypair created # via _create_keypair user_id = self._get_user_id() try: credential_id = db_api.resource_data_get(self, 'credential_id') except exception.NotFound: return try: self.keystone().delete_stack_domain_user_keypair( user_id=user_id, project_id=self.stack.stack_user_project_id, credential_id=credential_id) except ValueError: self.keystone().delete_ec2_keypair( user_id=user_id, credential_id=credential_id) for data_key in ('access_key', 'secret_key', 'credential_id'): try: db_api.resource_data_delete(self, data_key) except exception.NotFound: pass
def _secret_accesskey(self): ''' Return the user's access key, fetching it from keystone if necessary ''' if self._secret is None: if not self.resource_id: logger.warn(_('could not get secret for %(username)s ' 'Error:%(msg)s') % { 'username': self.properties[self.USER_NAME], 'msg': "resource_id not yet set"}) else: # First try to retrieve the secret from resource_data, but # for backwards compatibility, fall back to requesting from # keystone try: self._secret = db_api.resource_data_get(self, 'secret_key') except exception.NotFound: try: user_id = self._get_user().resource_id kp = self.keystone().get_ec2_keypair( user_id=user_id, access=self.resource_id) self._secret = kp.secret # Store the key in resource_data db_api.resource_data_set(self, 'secret_key', kp.secret, redact=True) # And the ID of the v3 credential db_api.resource_data_set(self, 'credential_id', kp.id, redact=True) except Exception as ex: logger.warn( _('could not get secret for %(username)s ' 'Error:%(msg)s') % { 'username': self.properties[self.USER_NAME], 'msg': str(ex)}) return self._secret or '000-000-000'
def handle_delete(self): vm_alarms = json.loads(db_api.resource_data_get(self, "alarm_ids")) logging.warning("ServiceInstanceAlarm:handle_delete vm_alarms: %s.", vm_alarms) for a in vm_alarms: self.ceilometer().alarms.delete(a)
def _resolve_attribute(self, name): if name == 'value': return db_api.resource_data_get(self, 'value')
def _resolve_attribute(self, name): if name == 'hostname': return db_api.resource_data_get(self, 'hostname') elif name == 'model': return db_api.resource_data_get(self, 'model') elif name == 'serialnumber': return db_api.resource_data_get(self, 'serialnumber') elif name == 'HOME': return db_api.resource_data_get(self, 'HOME') elif name == 'reboot_reason': return db_api.resource_data_get(self, 'reboot_reason') elif name == 'status': return db_api.resource_data_get(self, 'status') elif name == 'up_time': return db_api.resource_data_get(self, 'up_time') elif name == 'domain': return db_api.resource_data_get(self, 'domain') elif name == 'fqdn': return db_api.resource_data_get(self, 'fqdn') elif name == 'ifd_style': return db_api.resource_data_get(self, 'ifd_style') elif name == 'personality': return db_api.resource_data_get(self, 'personality') elif name == 'switch_style': return db_api.resource_data_get(self, 'switch_style') elif name == 'version': return db_api.resource_data_get(self, 'version')
def get_val(cls, resource, key): return db_api.resource_data_get(resource, key)
def access_key(self): try: return db_api.resource_data_get(self, 'access_key') except exception.NotFound: pass
def secret_key(self): try: return db_api.resource_data_get(self, 'secret_key') except exception.NotFound: pass
def password(self): try: return db_api.resource_data_get(self, 'password') except exception.NotFound: pass
def _resolve_attribute(self, name): if name == "alarm_ids": return db_api.resource_data_get(self, "alarm_ids") elif name == "name": return db_api.resource_data_get(self, "name")
def get_val(cls, resource, key): return db_api.resource_data_get(resource.context, resource.id, key)