Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
83f304ae
Commit
83f304ae
authored
Sep 16, 2020
by
Tiger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add API endpoints to manage individual Terraform state versions
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42415
parent
f5f1a283
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
284 additions
and
0 deletions
+284
-0
changelogs/unreleased/207347-terraform-versions-api.yml
changelogs/unreleased/207347-terraform-versions-api.yml
+5
-0
lib/api/api.rb
lib/api/api.rb
+1
-0
lib/api/terraform/state_version.rb
lib/api/terraform/state_version.rb
+68
-0
spec/requests/api/terraform/state_version_spec.rb
spec/requests/api/terraform/state_version_spec.rb
+210
-0
No files found.
changelogs/unreleased/207347-terraform-versions-api.yml
0 → 100644
View file @
83f304ae
---
title
:
Add API endpoints to manage individual Terraform state versions
merge_request
:
42415
author
:
type
:
added
lib/api/api.rb
View file @
83f304ae
...
@@ -216,6 +216,7 @@ module API
...
@@ -216,6 +216,7 @@ module API
mount
::
API
::
ProjectStatistics
mount
::
API
::
ProjectStatistics
mount
::
API
::
ProjectTemplates
mount
::
API
::
ProjectTemplates
mount
::
API
::
Terraform
::
State
mount
::
API
::
Terraform
::
State
mount
::
API
::
Terraform
::
StateVersion
mount
::
API
::
ProtectedBranches
mount
::
API
::
ProtectedBranches
mount
::
API
::
ProtectedTags
mount
::
API
::
ProtectedTags
mount
::
API
::
Releases
mount
::
API
::
Releases
...
...
lib/api/terraform/state_version.rb
0 → 100644
View file @
83f304ae
# frozen_string_literal: true
module
API
module
Terraform
class
StateVersion
<
Grape
::
API
::
Instance
default_format
:json
before
do
authenticate!
authorize!
:read_terraform_state
,
user_project
end
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
namespace
':id/terraform/state/:name/versions/:serial'
do
params
do
requires
:name
,
type:
String
,
desc:
'The name of a Terraform state'
requires
:serial
,
type:
Integer
,
desc:
'The version number of the state'
end
helpers
do
def
remote_state_handler
::
Terraform
::
RemoteStateHandler
.
new
(
user_project
,
current_user
,
name:
params
[
:name
])
end
def
find_version
(
serial
)
remote_state_handler
.
find_with_lock
do
|
state
|
version
=
state
.
versions
.
find_by_version
(
serial
)
if
version
.
present?
yield
version
else
not_found!
end
end
end
end
desc
'Get a terraform state version'
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed: :basic_auth
get
do
find_version
(
params
[
:serial
])
do
|
version
|
env
[
'api.format'
]
=
:binary
# Bypass json serialization
body
version
.
file
.
read
status
:ok
end
end
desc
'Delete a terraform state version'
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed: :basic_auth
delete
do
authorize!
:admin_terraform_state
,
user_project
find_version
(
params
[
:serial
])
do
|
version
|
version
.
destroy!
body
false
status
:no_content
end
end
end
end
end
end
end
spec/requests/api/terraform/state_version_spec.rb
0 → 100644
View file @
83f304ae
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
API
::
Terraform
::
StateVersion
do
include
HttpBasicAuthHelpers
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:developer
)
{
create
(
:user
,
developer_projects:
[
project
])
}
let_it_be
(
:maintainer
)
{
create
(
:user
,
maintainer_projects:
[
project
])
}
let_it_be
(
:user_without_access
)
{
create
(
:user
)
}
let_it_be
(
:state
)
{
create
(
:terraform_state
,
project:
project
)
}
let!
(
:versions
)
{
create_list
(
:terraform_state_version
,
3
,
terraform_state:
state
)
}
let
(
:current_user
)
{
maintainer
}
let
(
:auth_header
)
{
user_basic_auth_header
(
current_user
)
}
let
(
:project_id
)
{
project
.
id
}
let
(
:state_name
)
{
state
.
name
}
let
(
:version
)
{
versions
.
last
}
let
(
:version_serial
)
{
version
.
version
}
let
(
:state_version_path
)
{
"/projects/
#{
project_id
}
/terraform/state/
#{
state_name
}
/versions/
#{
version_serial
}
"
}
describe
'GET /projects/:id/terraform/state/:name/versions/:serial'
do
subject
(
:request
)
{
get
api
(
state_version_path
),
headers:
auth_header
}
context
'with invalid authentication'
do
let
(
:auth_header
)
{
basic_auth_header
(
'bad'
,
'token'
)
}
it
'returns unauthorized status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
context
'with no authentication'
do
let
(
:auth_header
)
{
nil
}
it
'returns unauthorized status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
context
'personal acceess token authentication'
do
context
'with maintainer permissions'
do
let
(
:current_user
)
{
maintainer
}
it
'returns the state contents at the given version'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
.
body
).
to
eq
(
version
.
file
.
read
)
end
context
'for a project that does not exist'
do
let
(
:project_id
)
{
'0000'
}
it
'returns not found status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'with developer permissions'
do
let
(
:current_user
)
{
developer
}
it
'returns the state contents at the given version'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
.
body
).
to
eq
(
version
.
file
.
read
)
end
end
context
'with no permissions'
do
let
(
:current_user
)
{
user_without_access
}
it
'returns not found status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'job token authentication'
do
let
(
:auth_header
)
{
job_basic_auth_header
(
job
)
}
context
'with maintainer permissions'
do
let
(
:job
)
{
create
(
:ci_build
,
status: :running
,
project:
project
,
user:
maintainer
)
}
it
'returns the state contents at the given version'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
.
body
).
to
eq
(
version
.
file
.
read
)
end
it
'returns unauthorized status if the the job is not running'
do
job
.
update!
(
status: :failed
)
request
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
context
'for a project that does not exist'
do
let
(
:project_id
)
{
'0000'
}
it
'returns not found status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'with developer permissions'
do
let
(
:job
)
{
create
(
:ci_build
,
status: :running
,
project:
project
,
user:
developer
)
}
it
'returns the state contents at the given version'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
.
body
).
to
eq
(
version
.
file
.
read
)
end
end
context
'with no permissions'
do
let
(
:current_user
)
{
user_without_access
}
let
(
:job
)
{
create
(
:ci_build
,
status: :running
,
user:
current_user
)
}
it
'returns not found status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
describe
'DELETE /projects/:id/terraform/state/:name/versions/:serial'
do
subject
(
:request
)
{
delete
api
(
state_version_path
),
headers:
auth_header
}
context
'with invalid authentication'
do
let
(
:auth_header
)
{
basic_auth_header
(
'bad'
,
'token'
)
}
it
'returns unauthorized status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
context
'with no authentication'
do
let
(
:auth_header
)
{
nil
}
it
'returns unauthorized status'
do
request
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
context
'with maintainer permissions'
do
let
(
:current_user
)
{
maintainer
}
it
'deletes the version'
do
expect
{
request
}.
to
change
{
Terraform
::
StateVersion
.
count
}.
by
(
-
1
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
context
'version does not exist'
do
let
(
:version_serial
)
{
-
1
}
it
'does not delete a version'
do
expect
{
request
}.
to
change
{
Terraform
::
StateVersion
.
count
}.
by
(
0
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'with developer permissions'
do
let
(
:current_user
)
{
developer
}
it
'returns forbidden status'
do
expect
{
request
}.
to
change
{
Terraform
::
StateVersion
.
count
}.
by
(
0
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'with no permissions'
do
let
(
:current_user
)
{
user_without_access
}
it
'returns not found status'
do
expect
{
request
}.
to
change
{
Terraform
::
StateVersion
.
count
}.
by
(
0
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment