summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZ.J. van de Weg <zegerjan@gitlab.com>2016-07-26 09:37:02 +0200
committerZ.J. van de Weg <zegerjan@gitlab.com>2016-07-29 13:54:45 +0200
commit84cd2120952e7ee4095cb4b5d7c959f2c11610c5 (patch)
tree3f4f3498543311c4291f88285778c9d71c9cc21e
parentbe9aa7f19474424991923f128053e2523fa166d8 (diff)
downloadgitlab-ce-84cd2120952e7ee4095cb4b5d7c959f2c11610c5.tar.gz
Add API support for environments
-rw-r--r--doc/api/enviroments.md118
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/environments.rb87
-rw-r--r--spec/requests/api/environments_spec.rb103
5 files changed, 313 insertions, 0 deletions
diff --git a/doc/api/enviroments.md b/doc/api/enviroments.md
new file mode 100644
index 00000000000..c4b844fe77e
--- /dev/null
+++ b/doc/api/enviroments.md
@@ -0,0 +1,118 @@
+# Environments
+
+## List environments
+
+Get all environments for a given project.
+
+```
+GET /projects/:id/environments
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID of the project |
+
+```bash
+curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/1/environments
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "name": "Env1",
+ "external_url": "https://env1.example.gitlab.com"
+ }
+]
+```
+
+## Create a new environment
+
+Creates a new environment with the given name and external_url.
+
+It returns 200 if the environment was successfully created, 400 for wrong parameters
+and 409 if the environment already exists.
+
+```
+POST /projects/:id/environment
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | ------- | -------- | ---------------------------- |
+| `id` | integer | yes | The ID of the project |
+| `name` | string | yes | The name of the environment |
+| `external_url` | string | yes | Place to link to for this environment |
+
+```bash
+curl --data "name=deploy&external_url=https://deploy.example.gitlab.com" -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/environments"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "deploy",
+ "external_url": "https://deploy.example.gitlab.com"
+}
+```
+
+## Delete an environment
+
+It returns 200 if the environment was successfully deleted, and 404 if the environment does not exist.
+
+```
+DELETE /projects/:id/environments/:environment_id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ------- | -------- | --------------------- |
+| `id` | integer | yes | The ID of the project |
+| `environment_id` | integer | yes | The ID of the environment |
+
+```bash
+curl -X DELETE -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/environment/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "deploy",
+ "external_url": "https://deploy.example.gitlab.com"
+}
+```
+
+## Edit an existing environment
+
+Updates an existing environments name and/or external_url.
+
+It returns 200 if the label was successfully updated, In case of an error, an additional error message is returned.
+
+```
+PUT /projects/:id/environments/:environments_id
+```
+
+| Attribute | Type | Required | Description |
+| --------------- | ------- | --------------------------------- | ------------------------------- |
+| `id` | integer | yes | The ID of the project |
+| `environment_id` | integer | yes | The ID of the environment | The ID of the environment |
+| `name` | string | no | The new name of the environment |
+| `external_url` | string | no | The new external_url |
+
+```bash
+curl -X PUT --data "name=staging&external_url=https://staging.example.gitlab.com" -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/environment/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "staging",
+ "external_url": "https://staging.example.gitlab.com"
+}
+```
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 3d7d67510a8..9c960d74495 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -32,6 +32,7 @@ module API
mount ::API::CommitStatuses
mount ::API::Commits
mount ::API::DeployKeys
+ mount ::API::Environments
mount ::API::Files
mount ::API::GroupMembers
mount ::API::Groups
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 4eb95d8a215..3e21b7a0b8a 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -496,6 +496,10 @@ module API
expose :key, :value
end
+ class Environment < Grape::Entity
+ expose :id, :name, :external_url
+ end
+
class RepoLicense < Grape::Entity
expose :key, :name, :nickname
expose :featured, as: :popular
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
new file mode 100644
index 00000000000..66a047f72fc
--- /dev/null
+++ b/lib/api/environments.rb
@@ -0,0 +1,87 @@
+module API
+ # Environments RESTfull API endpoints
+ class Environments < Grape::API
+ before { authenticate! }
+
+ resource :projects do
+ # Get all labels of the project
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # Example Request:
+ # GET /projects/:id/environments
+ get ':id/environments' do
+ authorize! :read_environment, user_project
+
+ present paginate(user_project.environments), with: Entities::Environment
+ end
+
+ # Creates a new environment
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # name (required) - The name of the environment to be created
+ # external_url (optional) - URL on which this deployment is viewable
+ #
+ # Example Request:
+ # POST /projects/:id/labels
+ post ':id/environments' do
+ authorize! :create_environment, user_project
+ required_attributes! [:name]
+
+ attrs = attributes_for_keys [:name, :external_url]
+ environment = user_project.environments.find_by(name: attrs[:name])
+
+ conflict!('Environment already exists') if environment
+
+ environment = user_project.environments.create(attrs)
+
+ if environment.valid?
+ present environment, with: Entities::Environment
+ else
+ render_validation_error!(environment)
+ end
+ end
+
+ # Deletes an existing environment
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # environment_id (required) - The name of the environment to be deleted
+ #
+ # Example Request:
+ # DELETE /projects/:id/environments/:environment_id
+ delete ':id/environments/:environment_id' do
+ authorize! :admin_environment, user_project
+
+ environment = user_project.environments.find(params[:environment_id])
+
+ present environment.destroy, with: Entities::Environment
+ end
+
+ # Updates an existing environment
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # environment_id (required) - The ID of the environment
+ # name (optional) - The name of the label to be deleted
+ # external_url (optional) - The new name of the label
+ #
+ # Example Request:
+ # PUT /projects/:id/environments/:environment_id
+ put ':id/environments/:environment_id' do
+ authorize! :update_environment, user_project
+
+ environment = user_project.environments.find(params[:environment_id])
+
+ attrs = attributes_for_keys [:name, :external_url]
+
+ if environment.update(attrs)
+ present environment, with: Entities::Environment
+ else
+ render_validation_error!(environment)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
new file mode 100644
index 00000000000..822139dbf3b
--- /dev/null
+++ b/spec/requests/api/environments_spec.rb
@@ -0,0 +1,103 @@
+require 'spec_helper'
+
+describe API::API, api: true do
+ include ApiHelpers
+
+ let(:user) { create(:user) }
+ let(:non_member) { create(:user) }
+ let(:project) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
+ let!(:environment) { create(:environment, project: project) }
+
+ before do
+ project.team << [user, :master]
+ end
+
+ describe 'GET /projects/:id/environments' do
+ context 'as member of the project' do
+ it 'should return project labels' do
+ get api("/projects/#{project.id}/environments", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['name']).to eq(environment.name)
+ expect(json_response.first['external_url']).to eq(environment.external_url)
+ end
+ end
+
+ context 'as non member' do
+ it 'should return a 404 status code' do
+ get api("/projects/#{project.id}/environments", non_member)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/labels' do
+ context 'as a member' do
+ it 'creates a environment with valid params' do
+ post api("/projects/#{project.id}/environments", user), name: "mepmep"
+
+ expect(response).to have_http_status(201)
+ expect(json_response['name']).to eq('mepmep')
+ expect(json_response['external']).to be nil
+ end
+
+ it 'requires name to be passed' do
+ post api("/projects/#{project.id}/environments", user), external_url: 'test.gitlab.com'
+
+ expect(response).to have_http_status(400)
+ end
+
+ it 'should return 409 if environment already exists' do
+ post api("/projects/#{project.id}/environments", user), name: environment.name
+
+ expect(response).to have_http_status(409)
+ expect(json_response['message']).to eq('Environment already exists')
+ end
+ end
+
+ context 'a non member' do
+ it 'rejects the request' do
+ post api("/projects/#{project.id}/environments", non_member)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe 'DELETE /projects/:id/environments/:environment_id' do
+ context 'as a master' do
+ it 'should return 200 for an existing environment' do
+ delete api("/projects/#{project.id}/environments/#{environment.id}", user)
+
+ expect(response).to have_http_status(200)
+ end
+
+ it 'should return 404 for non existing id' do
+ delete api("/projects/#{project.id}/environments/12345", user)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq('404 Not found')
+ end
+ end
+ end
+
+ describe 'PUT /projects/:id/environments/:environment_id' do
+ it 'should return 200 if name and external_url are changed' do
+ put api("/projects/#{project.id}/environments/#{environment.id}", user),
+ name: 'Mepmep', external_url: 'mepmep.whatever.ninja'
+
+ expect(response).to have_http_status(200)
+ expect(json_response['name']).to eq('Mepmep')
+ expect(json_response['external_url']).to eq('mepmep.whatever.ninja')
+ end
+
+ it 'should return 404 if the environment does not exist' do
+ put api("/projects/#{project.id}/environments/12345", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+end