Source code for chaosmonkey.api.plans_blueprint

"""
**Base path**: /api/1/plans

Plans receive a planner and an attack and create executors calling the corresponding planner with the given
attack.

Each plan creates N executors related to an attack to be executed in the future.

Plans has the following properties

* **id**: unique identifier for a plan
* **created**: creation date
* **next_execution**: execution date for the next executor
* **name**: plan name
* **executors_count**: number of executors in the plan
* **executed**: if all the executors in the plan has been executed

"""
from flask import Blueprint, json, request
from chaosmonkey.api.hal import Document
from chaosmonkey.api.request_validator import validate_payload
from chaosmonkey.engine.cme_manager import manager
from chaosmonkey.api.utils import get_boolean


plans = Blueprint("plans", __name__)

plan_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "attack": {
            "type": "object",
            "properties": {
                "ref": {"type": "string"},
                "args": {"type": "object"},
            },
            "required": ["ref", "args"]
        },
        "planner": {
            "type": "object",
            "properties": {
                "ref": {"type": "string"},
                "args": {"type": "object"},
            },
            "required": ["ref", "args"]
        }
    },
    "required": ["name", "attack", "planner"]
}


@plans.route("/", methods=["POST"])
[docs]def add_plan(): """ Add a plan. Example request:: PUT /api/1/executors/3b373155577b4d1bbc62216ffea013a4 Body: { "name": "Terminate instances in Playground", "attack": { "args": { "region": "eu-west-1", "filters": { "tag:Name": "playground-asg" } }, "ref": "terminate_ec2_instance:TerminateEC2Instance" }, "planner": { "ref": "simple_planner:SimplePlanner", "args": { "min_time" : "10:00", "max_time" : "19:00", "times": 4 } } } """ assert validate_payload(request, plan_schema) req_json = request.get_json() name = req_json["name"] planner_config = req_json["planner"] attack_config = req_json["attack"] manager.execute_plan(name, planner_config, attack_config) return json.jsonify({"msg": "ok"})
@plans.route("/", methods=["GET"])
[docs]def list_plans(): """ List all plans created Example request:: GET /api/1/plans/?all=true Example response:: { "_links": { "self": { "href": "/api/1/plans/" } }, "plans": [ { "id": "6890192d8b6c40e5af16f13aa036c7dc", "created": "2017-01-26T10:41:1485427282", "next_execution": "2017-01-26 13:14:07.583372", "name": "Terminate instances in Playground", "executors_count": 2, "_links": { "self": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc" }, "update": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc" }, "delete": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc" } } } ] } :param: all. Control when to show all plans (true) or only not executed (false). Defaults to false :return: :meth:`chaosmonkey.api.hal.document` """ show_all_query = request.args.get("all", False) show_all = get_boolean(show_all_query) plan_list = [plan.to_dict() for plan in manager.get_plans(show_all=show_all)] return Document(data={"plans": plan_list})
@plans.route("/<string:plan_id>", methods=["GET"])
[docs]def get_plan(plan_id): """ Get a plan with all related executors Example request:: GET /api/1/plans/6890192d8b6c40e5af16f13aa036c7dc Example response:: { "id": "6890192d8b6c40e5af16f13aa036c7dc", "_embedded": { "executors": [ { "plan_id": "6890192d8b6c40e5af16f13aa036c7dc", "_links": { "self": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dcdd2530572fd04c5aa061f261f82743d3" }, "update": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dcdd2530572fd04c5aa061f261f82743d3" }, "delete": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dcdd2530572fd04c5aa061f261f82743d3" } }, "next_run_time": "2017-01-26T13:14:1485436447", "id": "dd2530572fd04c5aa061f261f82743d3" }, { "plan_id": "6890192d8b6c40e5af16f13aa036c7dc", "_links": { "self": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc1dd3f0d392e545808edb74852213c1ae" }, "update": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc1dd3f0d392e545808edb74852213c1ae" }, "delete": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc1dd3f0d392e545808edb74852213c1ae" } }, "next_run_time": "2017-01-26T18:24:1485455082", "id": "1dd3f0d392e545808edb74852213c1ae" } ] }, "created": "2017-01-26T10:41:1485427282", "next_execution": null, "name": "Terminate instances in Playground", "executors_count": null, "_links": { "self": { "href": "/api/1/plans/6890192d8b6c40e5af16f13aa036c7dc" } } } :return: :meth:`chaosmonkey.api.hal.document` """ plan = manager.get_plan(plan_id) executor_list = [executor.to_dict() for executor in manager.get_executors_for_plan(plan_id)] return Document(data=plan.to_dict(), embedded={"executors": executor_list})
@plans.route("/<string:plan_id>", methods=["DELETE"])
[docs]def delete_plan(plan_id): """ Delete a plan Example request:: DEL /api/1/plans/6890192d8b6c40e5af16f13aa036c7dc """ manager.delete_plan(plan_id) return json.jsonify({ "msg": "Plan %s successfully deleted" % plan_id })