aboutsummaryrefslogtreecommitdiffstats
path: root/laas/sensors/laas.py
diff options
context:
space:
mode:
Diffstat (limited to 'laas/sensors/laas.py')
-rw-r--r--[-rwxr-xr-x]laas/sensors/laas.py225
1 files changed, 29 insertions, 196 deletions
diff --git a/laas/sensors/laas.py b/laas/sensors/laas.py
index 5d17fb2..29ce505 100755..100644
--- a/laas/sensors/laas.py
+++ b/laas/sensors/laas.py
@@ -1,5 +1,5 @@
##############################################################################
-# Copyright 2017 Parker Berberian and Others #
+# Copyright 2018 Parker Berberian and Others #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -13,214 +13,47 @@
# See the License for the specific language governing permissions and #
# limitations under the License. #
##############################################################################
-
import requests
-import time
-import calendar
import json
from st2reactor.sensor.base import PollingSensor
-class Laas_api(PollingSensor):
- """
- This class listens to the dashboard and starts/stops bookings accordingly.
- """
-
- def getBookingList(self):
- return json.loads(
- self.sensor_service.get_value(name='bookings', local=False)
- )
-
- def updateBookingList(self, blist):
- self.sensor_service.set_value(
- name='bookings',
- value=json.dumps(blist),
- local=False
- )
-
- def AddBooking(self, new_booking):
- """
- checks if booking is in the database, and adds it if it isnt
- """
- # first, check if booking is already expired
- if time.time() > new_booking['end']:
- return
- # check if booking already in db
- booking_list = self.getBookingList()
- if new_booking['id'] in booking_list:
- return
- new_booking['status'] = 0 # add status code
- booking_list.append(new_booking['id'])
- name = "booking_" + str(new_booking['id'])
- self.sensor_service.set_value(
- name=name,
- value=json.dumps(new_booking),
- local=False
- )
- self.updateBookingList(booking_list)
-
- def convertTimes(self, booking):
- """
- this method will take the time reported by Laas in the
- format yyyy-mm-ddThh:mm:ssZ
- and convert it into seconds since the epoch,
- for easier management
- """
- booking['start'] = self.laasToEpoch(booking['start'])
- booking['end'] = self.laasToEpoch(booking['end'])
-
- def laasToEpoch(self, timeStr):
- """
- Converts the dates from the dashboard to epoch time.
- """
- time_struct = time.strptime(timeStr, '%Y-%m-%dT%H:%M:%SZ')
- epoch_time = calendar.timegm(time_struct)
- return epoch_time
-
- def checkBookings(self):
- """
- This method checks all the bookings in our database to see if any
- action is required.
- """
-
- # get all active bookings from database into a usable form
- booking_list = self.getBookingList()
- for booking_id in booking_list:
- booking = self.getBooking(booking_id)
- # first, check if booking is over
- if time.time() > booking['end']:
- self.log.info("ending the booking with id %i", booking_id)
- self.endBooking(booking)
- # Then check if booking has begun and the host is still idle
- elif time.time() > booking['start'] and booking['status'] < 1:
- self.log.info("starting the booking with id %i", booking['id'])
- self.startBooking(booking)
-
- def startBooking(self, booking):
- """
- Starts the scheduled booking on the requested host with
- the correct config file.
- The provisioning process gets spun up in a subproccess,
- so the api listener is not interupted.
- """
- host = self.getServer(laas_id=booking['resource_id'])['hostname']
- self.log.info("Detected a new booking started for host %s", host)
- self.setBookingStatus(booking['id'], 1) # mark booking started
- # dispatch trigger into system
- trigger = "laas.start_deployment_trigger"
- payload = {"host": host, "installer": booking['installer_name']}
- payload['scenario'] = booking['scenario_name']
- payload['booking'] = booking['id']
- self.sensor_service.dispatch(trigger=trigger, payload=payload)
-
- def endBooking(self, booking):
- """
- Resets a host once its booking has ended.
- """
- host = self.getServer(laas_id=booking['resource_id'])['hostname']
- self.log.info('Lease expired. Resetting host %s', host)
- self.setBookingStatus(booking['id'], 3)
- self.removeBooking(booking['id'])
- # dispatch trigger to clean
- host = self.getServer(laas_id=booking['resource_id'])['hostname']
- trigger = "laas.end_deployment_trigger"
- payload = {"host": host, "booking": booking['id']}
- if 'vpn_key' in booking.keys():
- payload['key'] = booking['vpn_key']
- else:
- payload['key'] = ''
- self.sensor_service.dispatch(trigger=trigger, payload=payload)
+class LaaS_Sensor(PollingSensor):
- def getServer(self, fog_name=None, hostname=None, laas_id=None):
- key = ""
- value = ""
- if fog_name is not None:
- key = "fog_name"
- value = fog_name
- elif hostname is not None:
- key = "hostname"
- value = hostname
- elif laas_id is not None:
- key = "laas_id"
- value = laas_id
- for server in self.servers:
- if server[key] == value:
- return server
+ def setup(self):
+ self.logger = self.sensor_service.get_logger(name=self.__class__.__name__)
+ self.auth_token = self.sensor_service.get_value(name="lab_auth_token", local=False)
+ self.logger.info("got auth token %s", self.auth_token)
- def getBooking(self, booking_id):
- name = "booking_" + str(booking_id)
- return json.loads(
- self.sensor_service.get_value(
- name=name,
+ def poll(self):
+ try:
+ jobs = json.loads(self.sensor_service.get_value("jobs", local=False))
+ dashboard = self._config['dashboard']['address']
+ name = self._config['dashboard']['lab_name']
+ url = dashboard + "/api/labs/" + name + "/jobs/new"
+ self.logger.info("polling at url %s", url)
+ header = {"auth-token": self.auth_token}
+ todo_jobs = requests.get(url, timeout=10, headers=header).json()
+ for job_data in todo_jobs:
+ if job_data['id'] in jobs:
+ continue
+ self.logger.info("doing job %s", str(job_data['id']))
+ # put job into datastore for workflow
+ self.sensor_service.set_value(
+ "job_" + str(job_data['id']),
+ json.dumps(job_data['payload']),
local=False
- )
)
-
- def setBookingStatus(self, booking_id, status):
- booking = self.getBooking(booking_id)
- booking['status'] = status
- name = "booking_" + str(booking_id)
- self.sensor_service.set_value(
- name=name,
- value=json.dumps(booking),
- local=False
+ # dispatch trigger
+ self.sensor_service.dispatch(
+ trigger="laas.start_job_trigger",
+ payload={"job_id": job_data['id']}
)
-
- def removeBooking(self, booking_id):
- blist = self.getBookingList()
- blist.remove(booking_id)
- self.updateBookingList(blist)
- name = "booking_" + str(booking_id)
- self.sensor_service.delete_value(name=name, local=False)
+ except Exception as e:
+ self.logger.exception("Failed to poll(): %s", str(e))
# Sensor Interface Methods #
- def setup(self):
- """
- This method is called by stackstorm once to setup this polling sensor.
- Basically __init__, assigns instance variables, etc
- """
- server_names = json.loads(
- self.sensor_service.get_value('hosts', local=False)
- )
- self.servers = []
- for server in server_names:
- self.servers.append(
- json.loads(
- self.sensor_service.get_value(server, local=False)
- )
- )
- self.resource_ids = []
- for host in self.servers:
- self.resource_ids.append(host['laas_id'])
- self.log = self.sensor_service.get_logger(name=self.__class__.__name__)
- self.dashboard = self.sensor_service.get_value(
- name='dashboard_url',
- local=False
- )
- self.log.info("connecting to dashboard at %s", self.dashboard)
- # get token here for when dashboard supports it
-
- def poll(self):
- """
- this method will continuously poll the laas dashboard.
- If a booking is found on our server,
- we will start a deployment in the background with the
- proper config file for the requested
- installer and scenario.
- """
- self.log.debug("%s", "Beginning polling of dashboard")
- try:
- url = self.dashboard+"/api/bookings/"
- bookings = requests.get(url).json()
- for booking in bookings:
- if booking['resource_id'] in self.resource_ids:
- self.convertTimes(booking)
- self.AddBooking(booking)
- self.checkBookings()
- except Exception:
- self.log.exception('%s', "failed to connect to dashboard")
-
def cleanup(self):
# called when st2 goes down
pass