Skip to content

Commit

Permalink
Add security service and fake data
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Skripnick committed Dec 16, 2016
1 parent 84d13c3 commit 7a50ebe
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 6 deletions.
14 changes: 13 additions & 1 deletion ceagle/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@

import requests

from ceagle.api_fake_data import fake_security
from ceagle import config

FAKE_CLIENT_MAP = {
"security": fake_security.Client,
}


class UnknownService(Exception):
pass
Expand Down Expand Up @@ -55,12 +60,19 @@ def get(self, uri="/", **kwargs):


def get_client(service_name):
"""Return client for given service anme, if possible.
"""Return client for given service name, if possible.
:param service_name: str name of microservice
:returns: Client
"""

if config.get_config().get("use_fake_api_data", True):
fake_client_class = FAKE_CLIENT_MAP.get(service_name)
if fake_client_class:
return fake_client_class(name=service_name, endpoint="_fake_")

endpoint = config.get_config().get("services", {}).get(service_name)

if endpoint:
return Client(name=service_name, endpoint=endpoint)
raise UnknownService("Unknown service '%s'" % service_name)
13 changes: 9 additions & 4 deletions ceagle/api/v1/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@
# under the License.

import flask
from flask import request # noqa

from ceagle.api import client

security = flask.Blueprint("security", __name__)

client = client.get_client("security")

@security.route("/")
def get_security():
return flask.jsonify({"result": {"security": "dummy"}})

@security.route("/<region>/security/issues/<period>", methods=["GET"])
def get_issues(region, period):
body, status = client.get("%s/security/issues/%s" % (region, period))
return flask.jsonify(body), status


def get_blueprints():
return [["/security", security]]
return [["/region", security]]
78 changes: 78 additions & 0 deletions ceagle/api_fake_data/fake_security.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# 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.

import datetime


def _get_fake_issue(region, issue_type, days):
now = datetime.datetime.now()
discovered = now - datetime.timedelta(days=days)
confirmed = now
return {
"type": issue_type,
"description": "Sample issue " + issue_type,
"discovered_at": discovered.isoformat(),
"confirmed_at": confirmed.isoformat(),
"object_id": "test-id-%s-%d" % (issue_type, days),
"region": region,
}

FAKE_ISSUES = {
"Region1": [
_get_fake_issue("Region1", "IssueType1", 2),
_get_fake_issue("Region1", "IssueType2", 8),
],
"north-2.piedpiper.net": [
_get_fake_issue("north-2.piedpiper.net", "IssueType1", 0),
_get_fake_issue("north-2.piedpiper.net", "IssueType2", 2),
_get_fake_issue("north-2.piedpiper.net", "IssueType2", 8),
],
}

PERIOD_MAP = {
"day": 1,
"week": 7,
"month": 30,
}


class Client(object):

def __init__(self, name, endpoint):
self.name = name
self.endpoint = endpoint

def get(self, uri="/", **kwargs):
"""Make GET request and decode JSON data.
:param uri: resource URI
:param kwargs: query parameters
:returns: dict response data
"""
region, security, issues, period = uri.split("/")
if issues != "issues":
return "Not found", 404
issues = []
all_issues = FAKE_ISSUES.get(region)
if all_issues:
now = datetime.datetime.now()
discovered_before = (now - datetime.timedelta(
days=PERIOD_MAP[period])).isoformat("T")
for issue in all_issues:
if issue["discovered_at"] >= discovered_before:
issues.append(issue)
else:
return "Region not found", 404
return {"issues": issues}, 200
10 changes: 10 additions & 0 deletions raml/abao_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ hooks.before('GET /api/{version}/region/{region}/infra -> 404', function (test,
done();
});

hooks.before('GET /api/{version}/region/{region}/security/issues/{period} -> 200', function (test, done) {
test.request.params = params;
done();
});

hooks.before('GET /api/{version}/region/{region}/security/issues/{period} -> 404', function (test, done) {
test.request.params = paramsBadRegion;
done();
});

hooks.before('GET /api/{version}/status/{period} -> 200', function (test, done) {
test.request.params = params;
done();
Expand Down
13 changes: 13 additions & 0 deletions raml/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ mediaType: application/json
schema: !include schemas/404.json
example: !include response_examples/404/region.json

/security/issues/{period}:
uriParameters:
period:
description: "Return issues discovered at specific period"
enum: ["day", "week", "month"]
get:
description: "Return list of Issue objects"
responses:
200:
body:
schema: !include schemas/200.json
example: !include response_examples/200/security_issues.json

/status/health/{period}:
uriParameters:
period:
Expand Down
28 changes: 28 additions & 0 deletions raml/response_examples/200/security_issues.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[
{
"issueType": "securityGroup",
"regionId": "Region1",
"description": "Security group too open",
"discoveredAt": "2016-02-28T16:41:41.090Z",
"confirmedAt": "2016-03-28T16:41:41.090Z",
"subject": {
"id": "d8b0be7c-2ad7-4083-8d5a-a7a9a56fdd14",
"type": "securityGroup",
"tenantId": "demo",
"userId": "demo"
}
}, {
"issueType": "securityGroup",
"regionId": "Region1",
"description": "Security group too open",
"discoveredAt": "2016-02-28T16:21:41.090Z",
"confirmedAt": "2016-03-28T16:31:41.090Z",
"resolvedAt": "2016-04-28T16:31:41.090Z",
"subject": {
"id": "d8b0be7c-2ad7-4083-8d5a-a7a9a56fdd15",
"type": "securityGroup",
"tenantId": "demo",
"userId": "demo"
}
}
]
4 changes: 4 additions & 0 deletions raml/response_examples/200/security_regions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
"Region1",
"Region2"
]
3 changes: 2 additions & 1 deletion tests/unit/api/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def test_get_config(self, mock_config):
mock_config.get_config.return_value = {"services": {"foo": ""}}
self.assertRaises(client.UnknownService, client.get_client, "foo")

cfg = {"services": {"foo": "http://foo_ep"}}
cfg = {"services": {"foo": "http://foo_ep"},
"use_fake_api_data": False}
mock_config.get_config.return_value = cfg
ct = client.get_client("foo")
self.assertIsInstance(ct, client.Client)
Expand Down
48 changes: 48 additions & 0 deletions tests/unit/api/v1/test_security.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# 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 tests.unit import test


class SecurityTestCase(test.TestCase):

def test_get_issues_month(self):
resp = self.get("/api/v1/region/Region1/security/issues/month")
self.assertEqual(200, resp[0])
self.assertEqual(2, len(resp[1]["issues"]))

def test_get_issues_week(self):
resp = self.get(
"/api/v1/region/north-2.piedpiper.net/security/issues/week")
self.assertEqual(200, resp[0])
self.assertEqual(2, len(resp[1]["issues"]))

def test_get_issues_day(self):
resp = self.get(
"/api/v1/region/north-2.piedpiper.net/security/issues/day")
self.assertEqual(200, resp[0])
self.assertEqual(1, len(resp[1]["issues"]))

def test_get_issues_empty(self):
resp = self.get("/api/v1/region/Region1/security/issues/day")
self.assertEqual((200, {"issues": []}), resp)

def test_get_issues_unknown_region(self):
resp = self.get("/api/v1/region/Region3/security/issues/day")
self.assertEqual(404, resp[0])

def test_get_issues_404(self):
resp = self.get("/api/v1/region/Region3/day")
self.assertEqual(404, resp[0])

0 comments on commit 7a50ebe

Please sign in to comment.