Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
redvox committed Dec 8, 2016
1 parent 49385dc commit aeec841
Show file tree
Hide file tree
Showing 8 changed files with 15 additions and 407 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [2.0.0] - 2016-12-08

### Changed
- Remove legacy support.

## [1.0.2] - 2016-05-09

### Fixed
- Add environment check.
- Pinned python2 as venv version ([thanks@qeqar](https://github.com/qeqar)).

## [1.0.1] - 2016-05-09

### Fixed
Expand All @@ -21,6 +32,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fixed ghost tickets

This changelog is inspired by [keepachangelog.com](http://http://keepachangelog.com/de/)
[Unreleased]: https://github.com/otto-de/gatekeeper/compare/1.0.1...HEAD
[Unreleased]: https://github.com/otto-de/gatekeeper/compare/1.0.2...HEAD
[1.0.1]: https://github.com/otto-de/gatekeeper/compare/1.0.0...1.0.1
[1.0.0]: https://github.com/otto-de/gatekeeper/compare/950359a01244904fa169492e4391e402398f2b17...1.0.0
[1.0.2]: https://github.com/otto-de/gatekeeper/compare/1.0.1...1.0.2
[2.0.0]: https://github.com/otto-de/gatekeeper/compare/1.0.1...2.0.0
57 changes: 0 additions & 57 deletions app/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,63 +83,6 @@ def api_test_and_set():
return error_response(error)


@blueprint.route('/api/services', methods=['PUT'])
def api_legacy_test_and_set():
try:
status = "ok"
data = util.data_from_request()
ticket_id = (data["ticket"] if "ticket" in data else None)
ticket = (blueprint.mongo.get_ticket(ticket_id) if ticket_id else None)

if ticket_id and not ticket:
raise TicketNotFound

if "services" not in data:
raise JsonStructureError("Could not find services") # TODO extract string into errors

for service in data['services']:
entry = blueprint.mongo.legacy_get_gate(service)
for environment in as_list(data['services'][service]):
if gate_is_closed(entry, environment, ticket_id):
if not gate_is_manually_closed(entry, environment) and request.args and request.args['queue']:
status = "queued"
break
return Response('{"status": "denied"}', status=200, mimetype='application/json')
if status == "queued":
expiration_date = blueprint.mongo.get_expiration_date(config.QUEUED_TICKET_LIFETIME)
else:
expiration_date = blueprint.mongo.get_expiration_date(
config.CURRENT_TICKET_LIFETIME) if config.CURRENT_TICKET_LIFETIME != 0 else 0

if not ticket:
ticket_id = str(uuid.uuid4())
ticket = {"id": ticket_id,
"updated": get_now_timestamp(),
"expiration_date": expiration_date,
"link": data["link"] if "link" in data else None}

for service in data['services']:
for environment in as_list(data['services'][service]):
blueprint.mongo.legacy_add_ticket_link(service, environment, ticket_id)

blueprint.mongo.add_ticket(ticket_id, ticket)

else:
ticket.update({"expiration_date": expiration_date})
ticket.update({"updated": get_now_timestamp()})
blueprint.mongo.update_ticket(ticket["id"], ticket)

response = {
"status": status,
"ticket": ticket
}
return Response(json.dumps(response), status=200, mimetype='application/json')
except (NotFound, NotMasterError, ServiceAlreadyExists, ServiceNameNotValid, JsonValidationError,
JsonStructureError,
TicketNotFound) as error:
return error_response(error)


def as_list(environments):
if type(environments) != type(list()):
environments = [environments]
Expand Down
26 changes: 0 additions & 26 deletions app/mongo_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,6 @@ def get_gate(self, group, name):
entry['environments'][env]['queue'] = tickets
return entry

def legacy_get_gate(self, name):
entry = self.legacy_check_existence(name)
if not entry:
raise NotFound
for env, info in entry['environments'].iteritems():
tickets = []
for ticket_id in info['queue']:
ticket = self.get_ticket(ticket_id)
if ticket:
tickets.append(ticket)
else:
self.legacy_remove_ticket_link(name, env, ticket_id)
entry['environments'][env]['queue'] = tickets
return entry

def set_gate(self, group, name, environment, state):
entry = self.check_existence(group, name)
self.validate_environment_state(entry, environment, state)
Expand All @@ -132,18 +117,10 @@ def add_ticket_link(self, group, name, environment, ticket_id):
self.collection.update({'name': name, 'group': group},
{'$push': {"environments." + environment + ".queue": ticket_id}})

def legacy_add_ticket_link(self, name, environment, ticket_id):
self.collection.update({'name': name},
{'$push': {"environments." + environment + ".queue": ticket_id}})

def remove_ticket_link(self, group, name, environment, ticket_id):
self.collection.update({'name': name, 'group': group},
{'$pull': {"environments." + environment + ".queue": ticket_id}})

def legacy_remove_ticket_link(self, name, environment, ticket_id):
self.collection.update({'name': name},
{'$pull': {"environments." + environment + ".queue": ticket_id}})

def add_ticket(self, ticket_id, ticket):
try:
self.tickets.update({"_id": ticket_id}, ticket, upsert=True)
Expand Down Expand Up @@ -192,9 +169,6 @@ def set_message(self, group, name, environment, message):
def check_existence(self, group, name):
return self.collection.find_one({"name": name, "group": group}, {'_id': False})

def legacy_check_existence(self, name):
return self.collection.find_one({"name": name}, {'_id': False})

def get_groups(self):
return self.collection.distinct('group')

Expand Down
151 changes: 0 additions & 151 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -399,157 +399,6 @@ PUT
:statuscode 404: Gate not found
:statuscode 500: Can not write to database

api/services (legacy)
----------------------------------------------------------------

PUT
~~~~
.. http:put:: api/services
With this you can close multiple gates at once and its provides a test-and-set functionality, which means that you only get a
positive response if none of the gates you asking for is already closed.

This is useful if you want two gates to be mutually exclusive. As example we do not want to deploy our pipeline, if the pipeline is involved in an live deployment of an other service.

**Example request**:

.. sourcecode:: http

PUT api/services HTTP/1.1
Content-Type: application/json

{
"services": {
"service12": ["myservicename"],
"pipeline": ["meta"]
}
}

**Positiv response**:

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "ok",
"ticket": {
"expiration_date": 0,
"updated": "2016-01-26 09:35:18+0100",
"link": "https://github.com/otto-de/gatekeeper",
"id": "4ca72ee9-82b9-48c5-bf66-994ac907386b"
}
}

**Negativ response**:

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "denied"
}

**Queued response**:

If the ``queue=true`` query is used and the gate is closed, you receive "queued" as response.

The ticket you get will be valid for 2 minutes. With every subsequent requests that includes the ticket id the tickets
expiration date will be refreshed.

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "queue",
"ticket": {
"expiration_date": 1453799405.26424,
"updated": "2016-01-26 09:35:18+0100",
"link": "https://github.com/otto-de/gatekeeper",
"id": "4ca72ee9-82b9-48c5-bf66-994ac907386b"
}
}

**Example request with queued ticket**:

To include your ticket id use the following request structure:

.. sourcecode:: http

PUT api/services HTTP/1.1
Content-Type: application/json

{
"services": {
"service12": ["myservicename"],
"pipeline": ["meta"]
},
"ticket": "4ca72ee9-82b9-48c5-bf66-994ac907386b"
}

**Positiv Queued response**:

The ticket expiration_date will be set to 0.

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "ok",
"ticket": {
"expiration_date": 0,
"updated": "2016-01-26 09:35:18+0100",
"link": "https://github.com/otto-de/gatekeeper",
"id": "4ca72ee9-82b9-48c5-bf66-994ac907386b"
}
}

**Negativ Queued response**:

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "denied"
}

**Still Queued response**:

If its not yet your turn, the status will remain as ``queue``.

.. sourcecode:: http

HTTP/1.1 200 OK
Content-Type: application/json

{
"status": "queue",
"ticket": {
"expiration_date": 1453799405.26424,
"updated": "2016-01-26 09:35:18+0100",
"link": "https://github.com/otto-de/gatekeeper",
"id": "4ca72ee9-82b9-48c5-bf66-994ac907386b"
}
}

:query queue=true: creates a ticket and uses queueing
:reqheader Accept: application/json
:resheader Content-Type: application/json
:statuscode 200: no error
:statuscode 400: Json was not valid
:statuscode 400: state must be open or closed
:statuscode 404: Gate not found
:statuscode 500: Can not write to database

api/tickets/<ticket_id>
-----------------------

Expand Down
10 changes: 0 additions & 10 deletions tests/helpers/api_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,11 @@ def set_gate(self, data):
headers=self.content_json,
data=json.dumps(data)).data)

def legacy_set_gate(self, data):
return load_json(self.api.put('/api/services',
headers=self.content_json,
data=json.dumps(data)).data)

def set_gate_or_queue_ticket(self, data):
return load_json(self.api.put('/api/gates?queue=true',
headers=self.content_json,
data=json.dumps(data)).data)

def legacy_set_gate_or_queue_ticket(self, data):
return load_json(self.api.put('/api/services?queue=true',
headers=self.content_json,
data=json.dumps(data)).data)

def delete_ticket(self, ticket_id):
return load_json(self.api.delete('/api/tickets/' + ticket_id,
headers=self.content_json).data)
Expand Down
11 changes: 0 additions & 11 deletions tests/helpers/testdata_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ def prepare_test_and_set_data(self):

return service, group, set_data

def prepare_legacy_test_and_set_data(self):
service, group = self.create_default_gate()

set_data = {
"services": {
service: ['develop']
}
}

return service, group, set_data

def create_service_name(self):
return 'test-gate_' + str(uuid.uuid4())

Expand Down
Loading

0 comments on commit aeec841

Please sign in to comment.