Merge "Adding meniscus coordinator api support classes"

This commit is contained in:
Jenkins
2013-05-16 23:35:58 +00:00
committed by Gerrit Code Review
16 changed files with 617 additions and 100 deletions

View File

@@ -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'],

View File

@@ -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')

View 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.
"""

View 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

View 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

View 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.
"""

View 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)

View 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)

View 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
}

View File

@@ -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 = []

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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):

View File

@@ -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"}}