Merge "Adding meniscus coordinator api support classes"
This commit is contained in:
@@ -30,19 +30,18 @@ class SystemInfo(AutoMarshallingModel):
|
||||
self.load_average = load_average
|
||||
self.disk_usage = disk_usage
|
||||
|
||||
def _obj_to_json(self):
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
body = {
|
||||
return {
|
||||
'os_type': self.os_type,
|
||||
'memory_mb': self.memory_mb,
|
||||
'architecture': self.architecture,
|
||||
'cpu_cores': self.cpu_cores,
|
||||
'load_average': self.load_average,
|
||||
'disk_usage': self.disk_usage._obj_to_dict()
|
||||
'disk_usage': self.disk_usage._obj_to_dict(),
|
||||
'load_average': self.load_average._obj_to_dict()
|
||||
}
|
||||
return body
|
||||
|
||||
def _obj_to_json(self):
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, dic):
|
||||
@@ -70,8 +69,8 @@ class LoadAverage(AutoMarshallingModel):
|
||||
self.five_average = five_average
|
||||
self.fifteen_average = fifteen_average
|
||||
|
||||
def _obj_to_json(self):
|
||||
body = {
|
||||
def _obj_to_dict(self):
|
||||
return {
|
||||
'load_average': {
|
||||
'1': self.one_average,
|
||||
'5': self.five_average,
|
||||
@@ -79,7 +78,8 @@ class LoadAverage(AutoMarshallingModel):
|
||||
}
|
||||
}
|
||||
|
||||
return json_to_str(body)
|
||||
def _obj_to_json(self):
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, dic):
|
||||
@@ -94,17 +94,16 @@ class LoadAverage(AutoMarshallingModel):
|
||||
class DiskUsage(AutoMarshallingModel):
|
||||
def __init__(self):
|
||||
super(DiskUsage, self).__init__()
|
||||
self.disks = []
|
||||
self.partitions = []
|
||||
|
||||
def add_disk(self, partition):
|
||||
if partition is not None:
|
||||
self.disks.append(partition)
|
||||
self.partitions.append(partition)
|
||||
|
||||
def _obj_to_dict(self):
|
||||
body = {}
|
||||
for disk in self.disks:
|
||||
key = disk.keys()[0]
|
||||
body[key] = disk[key]
|
||||
for partition in self.partitions:
|
||||
body.update(partition._obj_to_dict())
|
||||
return body
|
||||
|
||||
def _obj_to_json(self):
|
||||
@@ -112,7 +111,7 @@ class DiskUsage(AutoMarshallingModel):
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, json_dict):
|
||||
usage = DiskUsage()
|
||||
usage = cls()
|
||||
for disk in json_dict:
|
||||
part = Partition(name=disk,
|
||||
used=json_dict[disk]['used'],
|
||||
|
||||
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from json import loads as json_to_dict
|
||||
from cloudcafe.common.models.configuration import ConfigSectionInterface
|
||||
|
||||
|
||||
@@ -91,3 +91,83 @@ class TenantConfig(ConfigSectionInterface):
|
||||
@property
|
||||
def profile_name(self):
|
||||
return self.get("profile_name")
|
||||
|
||||
|
||||
class PairingConfig(ConfigSectionInterface):
|
||||
SECTION_NAME = 'meniscus-pairing'
|
||||
|
||||
@property
|
||||
def hostname(self):
|
||||
return self.get('hostname')
|
||||
|
||||
@property
|
||||
def coordinator_base_url(self):
|
||||
return self.get('coordinator_base_url')
|
||||
|
||||
@property
|
||||
def worker_base_url(self):
|
||||
return self.get('worker_base_url')
|
||||
|
||||
@property
|
||||
def callback(self):
|
||||
return self.get('callback')
|
||||
|
||||
@property
|
||||
def ip_v4(self):
|
||||
return self.get('ip_address_v4')
|
||||
|
||||
@property
|
||||
def ip_v6(self):
|
||||
return self.get('ip_address_v6')
|
||||
|
||||
@property
|
||||
def os_type(self):
|
||||
return self.get('os_type')
|
||||
|
||||
@property
|
||||
def memory_mb(self):
|
||||
return self.get('memory_mb')
|
||||
|
||||
@property
|
||||
def arch(self):
|
||||
return self.get('arch')
|
||||
|
||||
@property
|
||||
def api_secret(self):
|
||||
return self.get('api_secret')
|
||||
|
||||
@property
|
||||
def personality(self):
|
||||
return self.get('personality')
|
||||
|
||||
@property
|
||||
def cpu_cores(self):
|
||||
return self.get('cpu_cores')
|
||||
|
||||
@property
|
||||
def load_average(self):
|
||||
return json_to_dict(self.get('load_average'))
|
||||
|
||||
@property
|
||||
def disks(self):
|
||||
return json_to_dict(self.get('disks'))
|
||||
|
||||
|
||||
class CorrelationConfig(ConfigSectionInterface):
|
||||
SECTION_NAME = 'meniscus-correlation'
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
return self.get('host')
|
||||
|
||||
@property
|
||||
def pname(self):
|
||||
return self.get('pname')
|
||||
|
||||
@property
|
||||
def time(self):
|
||||
return self.get('time')
|
||||
|
||||
@property
|
||||
def native(self):
|
||||
return self.get('native')
|
||||
|
||||
15
cloudcafe/meniscus/coordinator_api/__init__.py
Normal file
15
cloudcafe/meniscus/coordinator_api/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
75
cloudcafe/meniscus/coordinator_api/behaviors.py
Normal file
75
cloudcafe/meniscus/coordinator_api/behaviors.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
|
||||
class PairingBehaviors(object):
|
||||
|
||||
def __init__(self, client, cleanup_client, config):
|
||||
super(PairingBehaviors, self).__init__()
|
||||
self.client = client
|
||||
self.cleanup_client = cleanup_client
|
||||
self.pairing_config = config
|
||||
self.worker_ids = []
|
||||
|
||||
def remove_created_workers(self):
|
||||
self.cleanup_client.connect()
|
||||
self.cleanup_client.auth()
|
||||
for worker_id in self.worker_ids:
|
||||
self.cleanup_client.remove_worker(worker_id)
|
||||
self.cleanup_client.disconnect()
|
||||
self.worker_ids = []
|
||||
|
||||
def pair_worker_from_config(self):
|
||||
resp = self.pair_worker(
|
||||
hostname=self.pairing_config.hostname,
|
||||
callback=self.pairing_config.callback,
|
||||
ip_v4=self.pairing_config.ip_v4,
|
||||
ip_v6=self.pairing_config.ip_v6,
|
||||
personality=self.pairing_config.personality,
|
||||
status='new',
|
||||
os_type=self.pairing_config.os_type,
|
||||
memory_mb=self.pairing_config.memory_mb,
|
||||
arch=self.pairing_config.arch,
|
||||
cpu_cores=self.pairing_config.cpu_cores,
|
||||
load_average=self.pairing_config.load_average,
|
||||
disks=self.pairing_config.disks)
|
||||
|
||||
return resp
|
||||
|
||||
def pair_worker(self, hostname=None, callback=None, ip_v4=None,
|
||||
ip_v6=None, personality=None, status=None, os_type=None,
|
||||
memory_mb=None, arch=None, cpu_cores=None,
|
||||
load_average=None, disks=None):
|
||||
|
||||
response = self.client.pair(
|
||||
hostname=hostname,
|
||||
callback=callback,
|
||||
ip_v4=ip_v4,
|
||||
ip_v6=ip_v6,
|
||||
personality=personality,
|
||||
status=status,
|
||||
os_type=os_type,
|
||||
memory_mb=memory_mb,
|
||||
arch=arch,
|
||||
cpu_cores=cpu_cores,
|
||||
load_average=load_average,
|
||||
disks=disks)
|
||||
|
||||
# Store information so we can remove all workers later
|
||||
if response.entity is not None:
|
||||
self.worker_ids.append(response.entity.worker_id)
|
||||
|
||||
return response
|
||||
96
cloudcafe/meniscus/coordinator_api/client.py
Normal file
96
cloudcafe/meniscus/coordinator_api/client.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
from cafe.engine.clients.rest import AutoMarshallingRestClient
|
||||
from cloudcafe.meniscus.common.models.system \
|
||||
import SystemInfo, DiskUsage, LoadAverage
|
||||
from cloudcafe.meniscus.coordinator_api.models.pairing \
|
||||
import WorkerRegistration, WorkerPairing
|
||||
from cloudcafe.meniscus.coordinator_api.models.routing import AllRoutes
|
||||
from cloudcafe.meniscus.coordinator_api.models.status import UpdateStatus
|
||||
|
||||
|
||||
class PairingClient(AutoMarshallingRestClient):
|
||||
def __init__(self, url, api_version, auth_token, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(PairingClient, self).__init__(serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url
|
||||
self.api_version = api_version
|
||||
self.auth_token = auth_token
|
||||
|
||||
def pair(self, hostname, callback, ip_v4, ip_v6, personality, status,
|
||||
os_type, memory_mb, arch, cpu_cores, load_average, disks):
|
||||
"""
|
||||
POST {base}/{version}/pairing
|
||||
@summary Registers a worker on the coordinator
|
||||
@return:
|
||||
"""
|
||||
remote = '{base}/{version}/pairing'.format(base=self.url,
|
||||
version=self.api_version)
|
||||
headers = {'X-AUTH-TOKEN': self.auth_token}
|
||||
|
||||
# Setup Request objects.
|
||||
disk_usage = DiskUsage._dict_to_obj(disks)
|
||||
load_average = LoadAverage._dict_to_obj(load_average)
|
||||
system_info = SystemInfo(disk_usage=disk_usage,
|
||||
os_type=os_type,
|
||||
memory_mb=memory_mb,
|
||||
architecture=arch,
|
||||
cpu_cores=cpu_cores,
|
||||
load_average=load_average)
|
||||
request_obj = WorkerRegistration(
|
||||
hostname=hostname, callback=callback, ip_v4=ip_v4, ip_v6=ip_v6,
|
||||
personality=personality, status=status, system_info=system_info)
|
||||
|
||||
# Pair request
|
||||
resp = self.request('POST',
|
||||
url=remote,
|
||||
headers=headers,
|
||||
request_entity=request_obj,
|
||||
response_entity_type=WorkerPairing)
|
||||
return resp
|
||||
|
||||
def get_routing(self, worker_id, worker_token):
|
||||
"""
|
||||
GET {base}/{version}/worker/{worker_id}/routes
|
||||
@summary Retrieves worker routing information
|
||||
@return:
|
||||
"""
|
||||
remote = '{base}/{version}/worker/{worker_id}/routes'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
worker_id=worker_id)
|
||||
headers = {'WORKER-TOKEN': worker_token}
|
||||
|
||||
resp = self.request('GET', remote, headers,
|
||||
response_entity_type=AllRoutes)
|
||||
return resp
|
||||
|
||||
def update_status(self, worker_id, worker_token, status):
|
||||
"""
|
||||
PUT {base}/{version}/worker/{worker_id}/status
|
||||
@return:
|
||||
"""
|
||||
remote = '{base}/{version}/worker/{worker_id}/status'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
worker_id=worker_id)
|
||||
headers = {'WORKER-TOKEN': worker_token}
|
||||
update_obj = UpdateStatus(status)
|
||||
|
||||
# Update request
|
||||
resp = self.request('PUT', remote, headers, request_entity=update_obj)
|
||||
return resp
|
||||
15
cloudcafe/meniscus/coordinator_api/models/__init__.py
Normal file
15
cloudcafe/meniscus/coordinator_api/models/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
65
cloudcafe/meniscus/coordinator_api/models/pairing.py
Normal file
65
cloudcafe/meniscus/coordinator_api/models/pairing.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
from json import dumps as json_to_str, loads as str_to_json
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class WorkerRegistration(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, hostname=None, callback=None, ip_v4=None, ip_v6=None,
|
||||
personality=None, status=None, system_info=None):
|
||||
super(WorkerRegistration, self).__init__()
|
||||
|
||||
self.hostname = hostname
|
||||
self.callback = callback
|
||||
self.ip_address_v4 = ip_v4
|
||||
self.ip_address_v6 = ip_v6
|
||||
self.personality = personality
|
||||
self.status = status
|
||||
self.system_info = system_info
|
||||
|
||||
def _obj_to_json(self):
|
||||
return json_to_str({'worker_registration': self._obj_to_dict()})
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {
|
||||
'hostname': self.hostname,
|
||||
'callback': self.callback,
|
||||
'ip_address_v4': self.ip_address_v4,
|
||||
'ip_address_v6': self.ip_address_v6,
|
||||
'personality': self.personality,
|
||||
'status': self.status,
|
||||
'system_info': self.system_info._obj_to_dict()
|
||||
}
|
||||
|
||||
|
||||
class WorkerPairing(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, personality_module, worker_id, worker_token):
|
||||
super(WorkerPairing, self).__init__()
|
||||
|
||||
self.personality_module = personality_module
|
||||
self.worker_id = worker_id
|
||||
self.worker_token = worker_token
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
json_dict = str_to_json(serialized_str)
|
||||
return cls._dict_to_obj(json_dict)
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, json_dict):
|
||||
return WorkerPairing(**json_dict)
|
||||
77
cloudcafe/meniscus/coordinator_api/models/routing.py
Normal file
77
cloudcafe/meniscus/coordinator_api/models/routing.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from json import loads as str_to_json
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class RouteTarget(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, worker_id, ip_address_v4, ip_address_v6, status):
|
||||
super(RouteTarget, self).__init__()
|
||||
|
||||
self.worker_id = worker_id
|
||||
self.ip_address_v4 = ip_address_v4
|
||||
self.ip_address_v6 = ip_address_v6
|
||||
self.status = status
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
json_dict = str_to_json(serialized_str)
|
||||
return cls._dict_to_obj(json_dict)
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, json_dict):
|
||||
return RouteTarget(**json_dict)
|
||||
|
||||
|
||||
class Route(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, service_domain, targets):
|
||||
super(Route, self).__init__()
|
||||
|
||||
self.service_domain = service_domain
|
||||
self.targets = targets
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
json_dict = str_to_json(serialized_str)
|
||||
return cls._dict_to_obj(json_dict)
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, json_dict):
|
||||
domain = json_dict.get('service_domain')
|
||||
targets_dict = json_dict.get('targets')
|
||||
targets = [RouteTarget._dict_to_obj(child) for child in targets_dict]
|
||||
return Route(service_domain=domain, targets=targets)
|
||||
|
||||
|
||||
class AllRoutes(AutoMarshallingModel):
|
||||
ROOT_TAG = 'routes'
|
||||
|
||||
def __init__(self, routes=None):
|
||||
super(AllRoutes, self).__init__()
|
||||
self.routes = routes
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
json_dict = str_to_json(serialized_str)
|
||||
return cls._dict_to_obj(json_dict.get(cls.ROOT_TAG))
|
||||
|
||||
@classmethod
|
||||
def _dict_to_obj(cls, json_dict):
|
||||
routes = [Route._dict_to_obj(child) for child in json_dict]
|
||||
return AllRoutes(routes=routes)
|
||||
32
cloudcafe/meniscus/coordinator_api/models/status.py
Normal file
32
cloudcafe/meniscus/coordinator_api/models/status.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
from json import dumps as dict_to_str
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class UpdateStatus(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, status):
|
||||
super(UpdateStatus, self).__init__()
|
||||
self.worker_status = status
|
||||
|
||||
def _obj_to_json(self):
|
||||
return dict_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {
|
||||
'worker_status': self.worker_status
|
||||
}
|
||||
@@ -19,25 +19,45 @@ from cloudcafe.meniscus.common.tools import RequestUtilities
|
||||
|
||||
class TenantBehaviors(object):
|
||||
|
||||
def __init__(self, tenant_client, tenant_config):
|
||||
def __init__(self, tenant_client, db_client, tenant_config):
|
||||
self.tenant_client = tenant_client
|
||||
self.db_client = db_client
|
||||
self.tenant_config = tenant_config
|
||||
self.tenant_ids = []
|
||||
|
||||
def create_tenant(self):
|
||||
def remove_created_tenants(self):
|
||||
self.db_client.connect()
|
||||
self.db_client.auth()
|
||||
for tenant_id in self.tenant_ids:
|
||||
self.db_client.remove_tenant(tenant_id)
|
||||
self.db_client.disconnect()
|
||||
self.tenant_ids = []
|
||||
|
||||
def create_tenant(self, use_alternate=False):
|
||||
"""
|
||||
Helper function for creating a tenant on a fixture
|
||||
@param self:
|
||||
@return: Returns tuple with tenant_id and response object
|
||||
"""
|
||||
tenant_id = random_int(1, 100000)
|
||||
tenant_id = str(random_int(1, 100000))
|
||||
self.tenant_ids.append(tenant_id)
|
||||
|
||||
if use_alternate:
|
||||
self.tenant_client.use_alternate = use_alternate
|
||||
|
||||
resp = self.tenant_client.create_tenant(tenant_id)
|
||||
return str(tenant_id), resp
|
||||
|
||||
if use_alternate:
|
||||
self.tenant_client.use_alternate = False
|
||||
return tenant_id, resp
|
||||
|
||||
|
||||
class ProducerBehaviors(TenantBehaviors):
|
||||
|
||||
def __init__(self, tenant_client, producer_client, tenant_config):
|
||||
def __init__(self, tenant_client, producer_client, db_client,
|
||||
tenant_config):
|
||||
super(ProducerBehaviors, self).__init__(tenant_client=tenant_client,
|
||||
db_client=db_client,
|
||||
tenant_config=tenant_config)
|
||||
self.producer_client = producer_client
|
||||
self.producers_created = []
|
||||
@@ -81,10 +101,11 @@ class ProducerBehaviors(TenantBehaviors):
|
||||
class ProfileBehaviors(ProducerBehaviors):
|
||||
|
||||
def __init__(self, tenant_client, producer_client, profile_client,
|
||||
tenant_config):
|
||||
db_client, tenant_config):
|
||||
super(ProfileBehaviors, self).__init__(
|
||||
tenant_client=tenant_client,
|
||||
producer_client=producer_client,
|
||||
db_client=db_client,
|
||||
tenant_config=tenant_config)
|
||||
self.profile_client = profile_client
|
||||
self.profiles_created = []
|
||||
@@ -116,11 +137,12 @@ class ProfileBehaviors(ProducerBehaviors):
|
||||
class HostBehaviors(ProfileBehaviors):
|
||||
|
||||
def __init__(self, tenant_client, producer_client, profile_client,
|
||||
host_client, tenant_config):
|
||||
host_client, db_client, tenant_config):
|
||||
super(HostBehaviors, self).__init__(
|
||||
tenant_client=tenant_client,
|
||||
producer_client=producer_client,
|
||||
profile_client=profile_client,
|
||||
db_client=db_client,
|
||||
tenant_config=tenant_config)
|
||||
self.host_client = host_client
|
||||
self.hosts_created = []
|
||||
|
||||
@@ -24,26 +24,34 @@ from cloudcafe.meniscus.tenant_api.models.host import \
|
||||
CreateHost, UpdateHost, AllHosts, Host
|
||||
|
||||
|
||||
class TenantClient(AutoMarshallingRestClient):
|
||||
def __init__(self, url, api_version, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
"""
|
||||
@param url: Base URL of meniscus api
|
||||
@type url: String
|
||||
"""
|
||||
super(TenantClient, self).__init__(serialize_format,
|
||||
deserialize_format)
|
||||
class MeniscusClient(AutoMarshallingRestClient):
|
||||
|
||||
def __init__(self, url, api_version, use_alternate=False,
|
||||
serialize_format=None, deserialize_format=None):
|
||||
super(MeniscusClient, self).__init__(serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url
|
||||
self.api_version = api_version
|
||||
self.use_alternate = use_alternate
|
||||
|
||||
def _get_base_url(self):
|
||||
if not self.use_alternate:
|
||||
url = '{base}/{version}/tenant'.format(base=self.url,
|
||||
version=self.api_version)
|
||||
else:
|
||||
url = '{base}/{version}'.format(base=self.url,
|
||||
version=self.api_version)
|
||||
return url
|
||||
|
||||
|
||||
class TenantClient(MeniscusClient):
|
||||
|
||||
def create_tenant(self, tenant_id):
|
||||
"""
|
||||
@summary: Creates a tenant with the given id
|
||||
@param tenant_id:
|
||||
"""
|
||||
url = '{base}/{version}'.format(base=self.url,
|
||||
version=self.api_version)
|
||||
|
||||
url = self._get_base_url()
|
||||
resp = self.request('POST', url,
|
||||
request_entity=CreateTenant(tenant_id))
|
||||
return resp
|
||||
@@ -52,28 +60,23 @@ class TenantClient(AutoMarshallingRestClient):
|
||||
"""
|
||||
@summary: Retrieves the version information from the API
|
||||
"""
|
||||
url = '{base}/{version}/{tenant_id}'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
tenant_id=tenant_id)
|
||||
|
||||
url = '{base}/{tenant_id}'.format(base=self._get_base_url(),
|
||||
tenant_id=tenant_id)
|
||||
resp = self.request('GET', url, response_entity_type=Tenant)
|
||||
return resp
|
||||
|
||||
|
||||
class ProducerClient(AutoMarshallingRestClient):
|
||||
def __init__(self, url, api_version, tenant_id, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(ProducerClient, self).__init__(serialize_format,
|
||||
class ProducerClient(MeniscusClient):
|
||||
def __init__(self, url, api_version, tenant_id, use_alternate=False,
|
||||
serialize_format=None, deserialize_format=None):
|
||||
super(ProducerClient, self).__init__(url, api_version,
|
||||
use_alternate, serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url
|
||||
self.api_version = api_version
|
||||
self.tenant_id = tenant_id
|
||||
|
||||
def _generate_producer_url(self, producer_id):
|
||||
remote_url = '{base}/{version}/{tenant_id}/producers/{producer_id}'\
|
||||
.format(base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/producers/{producer_id}'\
|
||||
.format(base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id,
|
||||
producer_id=producer_id)
|
||||
return remote_url
|
||||
@@ -91,8 +94,8 @@ class ProducerClient(AutoMarshallingRestClient):
|
||||
producer_durable=durable,
|
||||
producer_encrypted=encrypted)
|
||||
|
||||
url = '{base}/{version}/{tenant_id}/producers'.format(
|
||||
base=self.url,
|
||||
url = '{base}/{tenant_id}/producers'.format(
|
||||
base=self._get_base_url(),
|
||||
version=self.api_version,
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
@@ -140,9 +143,8 @@ class ProducerClient(AutoMarshallingRestClient):
|
||||
GET /{app_version}/{tenant_id}/producers
|
||||
@summary: Retrieves all producers on a given tenants
|
||||
"""
|
||||
remote_url = '{base}/{version}/{tenant_id}/producers'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/producers'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
response = self.request('GET', remote_url,
|
||||
@@ -150,21 +152,20 @@ class ProducerClient(AutoMarshallingRestClient):
|
||||
return response
|
||||
|
||||
|
||||
class ProfileClient(AutoMarshallingRestClient):
|
||||
class ProfileClient(MeniscusClient):
|
||||
|
||||
def __init__(self, url, api_version, tenant_id, producer_id,
|
||||
serialize_format=None, deserialize_format=None):
|
||||
super(ProfileClient, self).__init__(serialize_format,
|
||||
use_alternate=False, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(ProfileClient, self).__init__(url, api_version,
|
||||
use_alternate, serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url
|
||||
self.api_version = api_version
|
||||
self.tenant_id = tenant_id
|
||||
self.producer_id = producer_id
|
||||
|
||||
def _generate_profile_url(self, profile_id):
|
||||
remote_url = '{base}/{version}/{tenant_id}/profiles/{profile_id}'\
|
||||
.format(base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/profiles/{profile_id}'\
|
||||
.format(base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id,
|
||||
profile_id=profile_id)
|
||||
return remote_url
|
||||
@@ -177,9 +178,8 @@ class ProfileClient(AutoMarshallingRestClient):
|
||||
|
||||
request_profile = CreateProfile(name=name,
|
||||
producer_ids=producer_ids)
|
||||
url = '{base}/{version}/{tenant_id}/profiles'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
url = '{base}/{tenant_id}/profiles'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
profile_request = self.post(url, request_entity=request_profile)
|
||||
@@ -200,9 +200,8 @@ class ProfileClient(AutoMarshallingRestClient):
|
||||
GET /{app_version}/{tenant_id}/profiles
|
||||
@summary: Retrieves all profiles from a tenant
|
||||
"""
|
||||
remote_url = '{base}/{version}/{tenant_id}/profiles'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/profiles'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
response = self.request('GET', remote_url,
|
||||
@@ -231,11 +230,13 @@ class ProfileClient(AutoMarshallingRestClient):
|
||||
return response
|
||||
|
||||
|
||||
class HostClient(AutoMarshallingRestClient):
|
||||
class HostClient(MeniscusClient):
|
||||
|
||||
def __init__(self, url, api_version, tenant_id, profile_id,
|
||||
serialize_format=None, deserialize_format=None):
|
||||
super(HostClient, self).__init__(serialize_format,
|
||||
use_alternate=False, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(HostClient, self).__init__(url, api_version,
|
||||
use_alternate, serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url
|
||||
self.api_version = api_version
|
||||
@@ -243,9 +244,8 @@ class HostClient(AutoMarshallingRestClient):
|
||||
self.profile_id = profile_id
|
||||
|
||||
def _generate_host_url(self, host_id):
|
||||
remote_url = '{base}/{version}/{tenant_id}/hosts/{host_id}'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/hosts/{host_id}'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id,
|
||||
host_id=host_id)
|
||||
return remote_url
|
||||
@@ -255,9 +255,8 @@ class HostClient(AutoMarshallingRestClient):
|
||||
POST /{app_version}/{tenant_id}/hosts
|
||||
@summary: Creates a new host on a tenant
|
||||
"""
|
||||
remote_url = '{base}/{version}/{tenant_id}/hosts'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/hosts'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
host = CreateHost(hostname, profile_id, ip_v4, ip_v6)
|
||||
@@ -280,9 +279,8 @@ class HostClient(AutoMarshallingRestClient):
|
||||
GET /{app_version}/{tenant_id}/hosts
|
||||
@summary: Retrieves all hosts from a tenant
|
||||
"""
|
||||
remote_url = '{base}/{version}/{tenant_id}/hosts'.format(
|
||||
base=self.url,
|
||||
version=self.api_version,
|
||||
remote_url = '{base}/{tenant_id}/hosts'.format(
|
||||
base=self._get_base_url(),
|
||||
tenant_id=self.tenant_id)
|
||||
|
||||
response = self.request('GET', remote_url,
|
||||
|
||||
@@ -28,8 +28,15 @@ class UpdateHost(AutoMarshallingModel):
|
||||
self.profile_id = profile_id
|
||||
|
||||
def _obj_to_json(self):
|
||||
body = self._auto_to_dict()
|
||||
return json_to_str(body)
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {
|
||||
'hostname': self.hostname,
|
||||
'ip_address_v4': self.ip_address_v4,
|
||||
'ip_address_v6': self.ip_address_v6,
|
||||
'profile_id': self.profile_id
|
||||
}
|
||||
|
||||
|
||||
# Create requires all parameters, whereas update they are optional
|
||||
|
||||
@@ -23,7 +23,7 @@ class UpdateProducer(AutoMarshallingModel):
|
||||
producer_durable=None, producer_encrypted=None):
|
||||
super(UpdateProducer, self).__init__()
|
||||
|
||||
# Making all of these conditional for _auto_to_dict()
|
||||
# Making all of these optional
|
||||
if producer_name is not None:
|
||||
self.name = producer_name
|
||||
if producer_pattern is not None:
|
||||
@@ -34,8 +34,20 @@ class UpdateProducer(AutoMarshallingModel):
|
||||
self.encrypted = producer_encrypted
|
||||
|
||||
def _obj_to_json(self):
|
||||
body = self._auto_to_dict()
|
||||
return json_to_str(body)
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
# All of these elements are optional
|
||||
converted = {}
|
||||
if hasattr(self, 'name'):
|
||||
converted['name'] = self.name
|
||||
if hasattr(self, 'pattern'):
|
||||
converted['pattern'] = self.pattern
|
||||
if hasattr(self, 'durable'):
|
||||
converted['durable'] = self.durable
|
||||
if hasattr(self, 'encrypted'):
|
||||
converted['encrypted'] = self.encrypted
|
||||
return converted
|
||||
|
||||
|
||||
# Create requires all parameters, whereas update they are optional
|
||||
|
||||
@@ -28,8 +28,16 @@ class UpdateProfile(AutoMarshallingModel):
|
||||
self.producer_ids = producer_ids
|
||||
|
||||
def _obj_to_json(self):
|
||||
body = self._auto_to_dict()
|
||||
return json_to_str(body)
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
converted = {}
|
||||
if hasattr(self, 'name'):
|
||||
converted['name'] = self.name
|
||||
if hasattr(self, 'producer_ids'):
|
||||
converted['producer_ids'] = self.producer_ids
|
||||
|
||||
return converted
|
||||
|
||||
|
||||
# Create requires all parameters, whereas update they are optional
|
||||
|
||||
@@ -26,8 +26,10 @@ class CreateTenant(AutoMarshallingModel):
|
||||
self.tenant_id = tenant_id
|
||||
|
||||
def _obj_to_json(self):
|
||||
body = self._auto_to_dict()
|
||||
return json_to_str(body)
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {'tenant_id': self.tenant_id}
|
||||
|
||||
|
||||
class Tenant(AutoMarshallingModel):
|
||||
@@ -91,7 +93,14 @@ class TenantToken(AutoMarshallingModel):
|
||||
self.last_changed = last_changed
|
||||
|
||||
def _obj_to_json(self):
|
||||
return json_to_str(self._auto_to_dict())
|
||||
return json_to_str(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {
|
||||
'valid': self.valid,
|
||||
'previous': self.previous,
|
||||
'last_changed': self.last_changed
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
|
||||
@@ -3,7 +3,7 @@ serializer=json
|
||||
deserializer=json
|
||||
|
||||
[meniscus]
|
||||
base_url=http://localhost:8080
|
||||
base_url=<base_url>
|
||||
api_version=v1
|
||||
db_host=<db_address>
|
||||
db_name=<db_name>
|
||||
@@ -21,16 +21,23 @@ producer_encrypted=false
|
||||
profile_name=appservers-1
|
||||
|
||||
[meniscus-pairing]
|
||||
coordinator_base_url=http://192.168.1.2:8080
|
||||
callback=192.168.1.2:8080/v1/configuration
|
||||
hostname=testhost
|
||||
coordinator_base_url=<coordinator_base_url>
|
||||
worker_base_url=<worker_base_url>
|
||||
callback=<callback_url>
|
||||
ip_address_v4=127.0.0.1
|
||||
ip_address_v6=::1
|
||||
os_type=Linux
|
||||
memory_mb=1024
|
||||
arch=x86_64
|
||||
worker_base_url=http://192.168.1.3:8080
|
||||
api_secret=87188ab51cdhg6efeeee
|
||||
api_secret=<api_secret>
|
||||
personality=correlation
|
||||
disk_path=/dev/sda1
|
||||
disk_total=313764528
|
||||
disk_used=112512436
|
||||
cpu_cores=4
|
||||
load_average=0.234353456
|
||||
load_average={"1": 0.2,"5": 1,"15": 0.9}
|
||||
disks={"/dev/sda1": {"total": 313764528,"used": 112512436}}
|
||||
|
||||
[meniscus-correlation]
|
||||
host=sample.projectmeniscus.org
|
||||
pname=webapp-1.0
|
||||
time=2013-03-20T23:01:43.425602-05:00
|
||||
native={"my_field":"my_value","my_value":12345,"extended":{"customer":"54789"}}
|
||||
|
||||
Reference in New Issue
Block a user