Handle removal of Heat stacks
Add a new resource class to remove heat stacks from a tenant Change-Id: Ib6937b9dffc2747f537d64b3ac6b3ae45b094699
This commit is contained in:
parent
20079b574c
commit
af72f82d71
@ -35,6 +35,8 @@ import cinderclient.exceptions
|
|||||||
from cinderclient.v1 import client as cinder_client
|
from cinderclient.v1 import client as cinder_client
|
||||||
import glanceclient.exc
|
import glanceclient.exc
|
||||||
from glanceclient.v1 import client as glance_client
|
from glanceclient.v1 import client as glance_client
|
||||||
|
from heatclient import client as heat_client
|
||||||
|
import heatclient.openstack.common.apiclient.exceptions
|
||||||
from keystoneclient.apiclient import exceptions as api_exceptions
|
from keystoneclient.apiclient import exceptions as api_exceptions
|
||||||
import keystoneclient.openstack.common.apiclient.exceptions
|
import keystoneclient.openstack.common.apiclient.exceptions
|
||||||
from keystoneclient.v2_0 import client as keystone_client
|
from keystoneclient.v2_0 import client as keystone_client
|
||||||
@ -98,7 +100,8 @@ RESOURCES_CLASSES = ['CinderSnapshots',
|
|||||||
'SwiftObjects',
|
'SwiftObjects',
|
||||||
'SwiftContainers',
|
'SwiftContainers',
|
||||||
'CinderVolumes',
|
'CinderVolumes',
|
||||||
'CeilometerAlarms']
|
'CeilometerAlarms',
|
||||||
|
'HeatStacks']
|
||||||
|
|
||||||
|
|
||||||
# Decorators
|
# Decorators
|
||||||
@ -582,6 +585,29 @@ class GlanceImages(Resources):
|
|||||||
return res.owner == self.project_id
|
return res.owner == self.project_id
|
||||||
|
|
||||||
|
|
||||||
|
class HeatStacks(Resources):
|
||||||
|
|
||||||
|
def __init__(self, session):
|
||||||
|
self.client = heat_client.Client(
|
||||||
|
"1",
|
||||||
|
endpoint=session.get_endpoint("orchestration"),
|
||||||
|
token=session.token, insecure=session.insecure)
|
||||||
|
self.project_id = session.project_id
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
return self.client.stacks.list()
|
||||||
|
|
||||||
|
def delete(self, stack):
|
||||||
|
super(HeatStacks, self).delete(stack)
|
||||||
|
if stack.stack_status == "DELETE_FAILED":
|
||||||
|
self.client.stacks.abandon(stack.id)
|
||||||
|
else:
|
||||||
|
self.client.stacks.delete(stack.id)
|
||||||
|
|
||||||
|
def resource_str(self, stack):
|
||||||
|
return "stack {})".format(stack.id)
|
||||||
|
|
||||||
|
|
||||||
class CeilometerAlarms(Resources):
|
class CeilometerAlarms(Resources):
|
||||||
|
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
@ -704,6 +730,7 @@ def perform_on_project(admin_name, password, project, auth_url,
|
|||||||
neutronclient.common.exceptions.EndpointNotFound,
|
neutronclient.common.exceptions.EndpointNotFound,
|
||||||
cinderclient.exceptions.EndpointNotFound,
|
cinderclient.exceptions.EndpointNotFound,
|
||||||
novaclient.exceptions.EndpointNotFound,
|
novaclient.exceptions.EndpointNotFound,
|
||||||
|
heatclient.openstack.common.apiclient.exceptions.EndpointNotFound,
|
||||||
ResourceNotEnabled):
|
ResourceNotEnabled):
|
||||||
# If service is not in Keystone's services catalog, ignoring it
|
# If service is not in Keystone's services catalog, ignoring it
|
||||||
pass
|
pass
|
||||||
|
@ -25,12 +25,14 @@ STORAGE_PUBLIC_ENDPOINT = 'http://public:8080/v1/AUTH_ee5b90900a4b4e85938b0ceadf
|
|||||||
NETWORK_PUBLIC_ENDPOINT = 'https://network0.cw-labs.net'
|
NETWORK_PUBLIC_ENDPOINT = 'https://network0.cw-labs.net'
|
||||||
COMPUTE_PUBLIC_ENDPOINT = 'https://compute0.cw-labs.net/v2/43c9e28327094e1b81484f4b9aee74d5'
|
COMPUTE_PUBLIC_ENDPOINT = 'https://compute0.cw-labs.net/v2/43c9e28327094e1b81484f4b9aee74d5'
|
||||||
METERING_PUBLIC_ENDPOINT = 'https://metric0.cw-labs.net'
|
METERING_PUBLIC_ENDPOINT = 'https://metric0.cw-labs.net'
|
||||||
|
ORCHESTRATION_PUBLIC_ENDPOINT = 'https://orchestration0.cw-labs.net/v1'
|
||||||
VOLUME_INTERNAL_ENDPOINT = 'http://internal:8776/v1/225da22d3ce34b15877ea70b2a575f58'
|
VOLUME_INTERNAL_ENDPOINT = 'http://internal:8776/v1/225da22d3ce34b15877ea70b2a575f58'
|
||||||
IMAGE_INTERNAL_ENDPOINT = 'http://internal:9292'
|
IMAGE_INTERNAL_ENDPOINT = 'http://internal:9292'
|
||||||
STORAGE_INTERNAL_ENDPOINT = 'http://internal:8080/v1/AUTH_ee5b90900a4b4e85938b0ceadf4467f8'
|
STORAGE_INTERNAL_ENDPOINT = 'http://internal:8080/v1/AUTH_ee5b90900a4b4e85938b0ceadf4467f8'
|
||||||
NETWORK_INTERNAL_ENDPOINT = 'http://neutron.usr.lab0.aub.cw-labs.net:9696'
|
NETWORK_INTERNAL_ENDPOINT = 'http://neutron.usr.lab0.aub.cw-labs.net:9696'
|
||||||
COMPUTE_INTERNAL_ENDPOINT = 'http://nova.usr.lab0.aub.cw-labs.net:8774/v2/43c9e28327094e1b81484f4b9aee74d5'
|
COMPUTE_INTERNAL_ENDPOINT = 'http://nova.usr.lab0.aub.cw-labs.net:8774/v2/43c9e28327094e1b81484f4b9aee74d5'
|
||||||
METERING_INTERNAL_ENDPOINT = 'http://ceilometer.usr.lab0.aub.cw-labs.net:8777'
|
METERING_INTERNAL_ENDPOINT = 'http://ceilometer.usr.lab0.aub.cw-labs.net:8777'
|
||||||
|
ORCHESTRATION_INTERNAL_ENDPOINT = 'http://heat.usr.lab0.aub.cw-labs.net:8004/v1'
|
||||||
|
|
||||||
|
|
||||||
STORAGE_CONTAINERS = ['janeausten', 'marktwain']
|
STORAGE_CONTAINERS = ['janeausten', 'marktwain']
|
||||||
@ -54,6 +56,8 @@ SERVERS_IDS = ["616fb98f-46ca-475e-917e-2563e5a8cd19"]
|
|||||||
IMAGES_IDS = ["37717f53-3707-49b9-9dd0-fd063e6b9fc5", "4e150966-cbe7-4fd7-a964-41e008d20f10",
|
IMAGES_IDS = ["37717f53-3707-49b9-9dd0-fd063e6b9fc5", "4e150966-cbe7-4fd7-a964-41e008d20f10",
|
||||||
"482fbcc3-d831-411d-a073-ddc828a7a9ed"]
|
"482fbcc3-d831-411d-a073-ddc828a7a9ed"]
|
||||||
ALARMS_IDS = ["ca950223-e982-4552-9dec-5dc5d3ea4172"]
|
ALARMS_IDS = ["ca950223-e982-4552-9dec-5dc5d3ea4172"]
|
||||||
|
STACKS_IDS = ["5c136348-5550-4ec5-8bd6-b83241844db3",
|
||||||
|
"ec4083c1-3667-47d2-91c9-ce0bc8e3c2b9"]
|
||||||
UNBOUND_PORT_ID = "abcdb45e-45fe-4e04-8704-bf6f58760000"
|
UNBOUND_PORT_ID = "abcdb45e-45fe-4e04-8704-bf6f58760000"
|
||||||
|
|
||||||
PRIVATE_PORT_IDS = ["p7815f5b-a228-47bb-a5e5-f139c4f476ft", "p78o5f5t-a228-47bb-a5e2-f139c4f476ft"]
|
PRIVATE_PORT_IDS = ["p7815f5b-a228-47bb-a5e5-f139c4f476ft", "p78o5f5t-a228-47bb-a5e2-f139c4f476ft"]
|
||||||
@ -145,6 +149,15 @@ PROJECT_SCOPED_TOKEN = {
|
|||||||
'endpoints_links': [],
|
'endpoints_links': [],
|
||||||
'name': 'Metering service',
|
'name': 'Metering service',
|
||||||
'type': 'metering'
|
'type': 'metering'
|
||||||
|
}, {
|
||||||
|
'endpoints': [{
|
||||||
|
'adminURL': 'http://heat.usr.lab0.aub.cw-labs.net:8777',
|
||||||
|
'internalURL': ORCHESTRATION_INTERNAL_ENDPOINT,
|
||||||
|
'publicURL': ORCHESTRATION_PUBLIC_ENDPOINT,
|
||||||
|
'region': 'RegionOne'}],
|
||||||
|
'endpoints_links': [],
|
||||||
|
'name': 'Orchestration service',
|
||||||
|
'type': 'orchestration'
|
||||||
}],
|
}],
|
||||||
'token': {
|
'token': {
|
||||||
'expires': '2012-10-03T16:53:36Z',
|
'expires': '2012-10-03T16:53:36Z',
|
||||||
@ -1002,3 +1015,38 @@ ALARMS_LIST = [
|
|||||||
"user_id": "c96c887c216949acbdfbd8b494863567"
|
"user_id": "c96c887c216949acbdfbd8b494863567"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
STACKS_LIST = {
|
||||||
|
"stacks": [
|
||||||
|
{
|
||||||
|
"description": "First test",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "http://site/5c136348-5550-4ec5-8bd6-b83241844db3",
|
||||||
|
"rel": "self"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stack_status_reason": "",
|
||||||
|
"stack_name": "stack1",
|
||||||
|
"creation_time": "2015-03-03T14:08:54Z",
|
||||||
|
"updated_time": None,
|
||||||
|
"stack_status": "CREATE_SUCCESS",
|
||||||
|
"id": "5c136348-5550-4ec5-8bd6-b83241844db3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Second test",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "http://site/ec4083c1-3667-47d2-91c9-ce0bc8e3c2b9",
|
||||||
|
"rel": "self"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stack_status_reason": "",
|
||||||
|
"stack_name": "stack2",
|
||||||
|
"creation_time": "2015-03-03T17:34:21Z",
|
||||||
|
"updated_time": None,
|
||||||
|
"stack_status": "DELETE_FAILED",
|
||||||
|
"id": "ec4083c1-3667-47d2-91c9-ce0bc8e3c2b9"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -626,3 +626,41 @@ class TestCeilometerAlarms(TestResourcesBase):
|
|||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
self._test_delete()
|
self._test_delete()
|
||||||
|
|
||||||
|
|
||||||
|
class TestHeatStacks(TestResourcesBase):
|
||||||
|
TEST_URL = client_fixtures.ORCHESTRATION_PUBLIC_ENDPOINT
|
||||||
|
IDS = client_fixtures.STACKS_IDS
|
||||||
|
|
||||||
|
def stub_list(self):
|
||||||
|
self.stub_url('GET', parts=['stacks?'],
|
||||||
|
json=client_fixtures.STACKS_LIST)
|
||||||
|
|
||||||
|
def stub_delete(self):
|
||||||
|
self.stub_url(
|
||||||
|
'DELETE', parts=['stacks', client_fixtures.STACKS_IDS[0]])
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestHeatStacks, self).setUp()
|
||||||
|
self.resources = ospurge.HeatStacks(self.session)
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
self._test_list()
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
self._test_delete()
|
||||||
|
|
||||||
|
@httpretty.activate
|
||||||
|
def test_abandon(self):
|
||||||
|
self.stub_auth()
|
||||||
|
self.stub_list()
|
||||||
|
get_result = {'stack': client_fixtures.STACKS_LIST['stacks'][1]}
|
||||||
|
self.stub_url(
|
||||||
|
'GET', parts=['stacks', client_fixtures.STACKS_IDS[1]],
|
||||||
|
json=get_result)
|
||||||
|
self.stub_url(
|
||||||
|
'DELETE',
|
||||||
|
parts=['stacks', 'stack2', client_fixtures.STACKS_IDS[1],
|
||||||
|
'abandon'])
|
||||||
|
elts = list(self.resources.list())
|
||||||
|
self.resources.delete(elts[1])
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
python-ceilometerclient
|
python-ceilometerclient
|
||||||
python-cinderclient
|
python-cinderclient
|
||||||
python-glanceclient
|
python-glanceclient
|
||||||
|
python-heatclient
|
||||||
python-keystoneclient
|
python-keystoneclient
|
||||||
python-neutronclient
|
python-neutronclient
|
||||||
python-novaclient
|
python-novaclient
|
||||||
|
Loading…
x
Reference in New Issue
Block a user