Skip to content

Commit

Permalink
completed and tested API for getting and deleting an appliance
Browse files Browse the repository at this point in the history
  • Loading branch information
dcvan24 committed Mar 16, 2018
1 parent 7357367 commit 9ee7155
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 276 deletions.
144 changes: 0 additions & 144 deletions appliance.py

This file was deleted.

6 changes: 2 additions & 4 deletions appliance/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def __init__(self, id, containers=[], pending=[], **kwargs):

@property
def id(self):
return self.__id
return self.__id

@property
def containers(self):
Expand All @@ -36,6 +36,4 @@ def to_render(self):
for c in self.containers])

def to_save(self):
return dict(id=self.id,
containers=[c if isinstance(c, str) else c.id for c in self.containers],
pending=self.pending)
return dict(id=self.id, pending=self.pending)
22 changes: 6 additions & 16 deletions appliance/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from appliance.manager import ApplianceManager
from container.manager import ContainerManager
from util import message, error
from util import Loggable


Expand All @@ -14,12 +15,7 @@ def initialize(self, config):
self.__contr_mgr = ContainerManager(config)

async def post(self):
status, app = await self.__app_mgr.create_appliance(json.loads(self.request.body))
self.set_status(status)
self.write(json.dumps(app.to_render()) if status == 201 else app)
self.finish()
if status == 201:
await self.__app_mgr.process_next_pending_container(app)
raise NotImplemented


class ApplianceHandler(RequestHandler, Loggable):
Expand All @@ -29,18 +25,12 @@ def initialize(self, config):
self.__contr_mgr = ContainerManager(config)

async def get(self, app_id):
status, resp = await self.__app_mgr.get_appliance(app_id)
status, app, err = await self.__app_mgr.get_appliance(app_id)
self.set_status(status)
self.write(resp)
# self.write(json.dumps(resp.to_render()) if status == 200 else resp)
self.write(json.dumps(app.to_render() if status == 200 else error(err)))

async def delete(self, app_id):
status, app, resp = await self.__app_mgr.delete_appliance(app_id)
status, msg, err = await self.__app_mgr.delete_appliance(app_id)
self.set_status(status)
self.write(resp)
if app:
await self._deprovision_containers(app.containers)
self.write(json.dumps(message(msg) if status == 200 else error(err)))

async def _deprovision_containers(self, contrs):
for c in contrs:
await self.__contr_mgr.deprovision_container(c)
58 changes: 51 additions & 7 deletions appliance/manager.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,66 @@
from util import Singleton, Loggable, MotorClient, SecureAsyncHttpClient
from appliance.base import Appliance
from container.manager import ContainerManager


class ApplianceManager(Loggable, metaclass=Singleton):

def __init__(self):
def __init__(self, config):
self.__config = config
self.__app_col = MotorClient().requester.appliance
self.__contr_mgr = ContainerManager()
self.__http_cli = SecureAsyncHttpClient()

async def get_appliance(self, app_id, verbose=True):
pass
self.__contr_mgr = ContainerManager(config)
self.__http_cli = SecureAsyncHttpClient(config)

async def get_appliance(self, app_id):
status, app, err = await self._get_appliance_from_db(app_id)
if status != 200:
return status, app, err
app = Appliance(**app)
_, app.containers, _ = await self.__contr_mgr.get_containers(app_id)
return 200, app, None

async def create_appliance(self, app):
pass

async def delete_appliance(self, app_id):
pass
status, app, err = await self._get_appliance_from_db(app_id)
if err:
self.logger.error(err)
return status, None, err
status, msg, err = await self.__contr_mgr.delete_containers(appliance=app_id)
if err:
self.logger.error(err)
return 400, None, "Failed to deprovision containers of appliance '%s'"%app_id
self.logger.info(msg)
status, msg, err = await self._deprovision_group(app_id)
if err:
self.logger.error(err)
return 400, None, "Failed to deprovision group of appliance '%s'"%app_id
self.logger.info(msg)
status, msg, err = await self._delete_appliance_from_db(app_id)
if err:
self.logger.error(err)
return status, None, err
self.logger.info(msg)
return status, msg, None

async def save_appliance(self, app, upsert=True):
await self.__app_col.replace_one(dict(id=app.id), app.to_save(), upsert=upsert)

async def _get_appliance_from_db(self, app_id):
app = await self.__app_col.find_one(dict(id=app_id))
if not app:
return 404, None, "Appliance '%s' is not found"%app_id
return 200, app, None

async def _delete_appliance_from_db(self, app_id):
await self.__app_col.delete_one(dict(id=app_id))
return 200, "Appliance '%s' has been deleted"%app_id, None

async def _deprovision_group(self, app_id):
url = '%s/groups/%s?force=true'%(self.__config.url.service_scheduler, app_id)
status, msg, err = await self.__http_cli.delete(url)
if err:
return status, None, err
return 200, "Services of appliance '%s' have been deprovisioned"%app_id, None

4 changes: 1 addition & 3 deletions cluster/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ class Cluster(Loggable, metaclass=Singleton):
MONITOR_INTERVAL = 30000 # query cluster info every minute

def __init__(self, config):
self.__master_url_base = '%s/%s'%(config['dcos']['master_url'],
config['dcos']['mesos_master_route'])
self.__config = config
self.__http_cli = SecureAsyncHttpClient(config)
self.__hosts = []
Expand All @@ -40,7 +38,7 @@ def find_host_by_attribute(self, key, val):

async def monitor(self):
async def query_mesos():
status, body, err = await self.__http_cli.get('%s/slaves'%self.__master_url_base)
status, body, err = await self.__http_cli.get('%s/slaves'%self.__config.url.mesos_master)
if status != 200:
self.logger.debug(err)
return
Expand Down
9 changes: 4 additions & 5 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"dcos": {
"master_url": "http://18.188.11.136",
"mesos_master_route": "mesos/master",
"service_scheduler_route": "service/marathon/v2",
"job_scheduler_route": "service/chronos/v1/scheduler",
"mesos_master_endpoint": "mesos/master",
"service_scheduler_endpoint": "service/marathon/v2",
"job_scheduler_endpoint": "service/chronos/v1/scheduler",
"token_file_path": "/Users/fanjiang/.dcos_token"
},
"port": 9090,
"n_parallel": 1,
"vnet_cidr": "172.16.0.0/16"
"n_parallel": 1
}
12 changes: 9 additions & 3 deletions container/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from enum import Enum


class ContainerType(Enum):

SERVICE = 'service'
JOB = 'job'


class ContainerState(Enum):

SUBMITTED = 'submitted'
Expand Down Expand Up @@ -202,7 +208,7 @@ def __init__(self, id, appliance, type, image, resources, cmd=None, args=[], env
dependencies=[], rack=None, host=None, last_update=None, **kwargs):
self.__id = id
self.__appliance = appliance
self.__type = type
self.__type = type if isinstance(type, ContainerType) else ContainerType(type)
self.__image = image
self.__resources = Resources(**resources)
self.__cmd = cmd
Expand Down Expand Up @@ -336,7 +342,7 @@ def add_dependency(self, dep):
self.__dependencies.append(dep)

def to_render(self):
return dict(id=self.id, appliance=self.appliance, type=self.type,
return dict(id=self.id, appliance=self.appliance, type=self.type.value,
image=self.image, resources=self.resources.to_render(),
cmd=self.cmd, args=self.args, env=self.env,
volumes=[v.to_render() for v in self.volumes],
Expand All @@ -348,7 +354,7 @@ def to_render(self):
rack=self.rack, host=self.host, last_update=self.last_update)

def to_save(self):
return dict(id=self.id, appliance=self.appliance, type=self.type,
return dict(id=self.id, appliance=self.appliance, type=self.type.value,
image=self.image, resources=self.resources.to_save(),
cmd=self.cmd, args=self.args, env=self.env,
volumes=[v.to_save() for v in self.volumes],
Expand Down
Loading

0 comments on commit 9ee7155

Please sign in to comment.