diff options
author | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-07-26 09:37:02 +0200 |
---|---|---|
committer | Z.J. van de Weg <zegerjan@gitlab.com> | 2016-07-29 13:54:45 +0200 |
commit | 84cd2120952e7ee4095cb4b5d7c959f2c11610c5 (patch) | |
tree | 3f4f3498543311c4291f88285778c9d71c9cc21e | |
parent | be9aa7f19474424991923f128053e2523fa166d8 (diff) | |
download | gitlab-ce-84cd2120952e7ee4095cb4b5d7c959f2c11610c5.tar.gz |
Add API support for environments
-rw-r--r-- | doc/api/enviroments.md | 118 | ||||
-rw-r--r-- | lib/api/api.rb | 1 | ||||
-rw-r--r-- | lib/api/entities.rb | 4 | ||||
-rw-r--r-- | lib/api/environments.rb | 87 | ||||
-rw-r--r-- | spec/requests/api/environments_spec.rb | 103 |
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 |