Adding registry endpoint authorization

This commit is contained in:
Andre Guedes 2016-12-13 23:42:43 -02:00
parent eed0b85ad0
commit 246df2bd11
12 changed files with 133 additions and 17 deletions

View file

@ -29,6 +29,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_to :back
end
def reset_container_registry_token
@application_setting.reset_container_registry_access_token!
flash[:notice] = 'New container registry access token has been generated!'
redirect_to :back
end
def clear_repository_check_states
RepositoryCheck::ClearWorker.perform_async

View file

@ -0,0 +1,11 @@
class Admin::ContainerRegistryController < Admin::ApplicationController
def show
@access_token = container_registry_access_token
end
private
def container_registry_access_token
current_application_settings.container_registry_access_token
end
end

View file

@ -4,6 +4,7 @@ class ApplicationSetting < ActiveRecord::Base
add_authentication_token_field :runners_registration_token
add_authentication_token_field :health_check_access_token
add_authentication_token_field :container_registry_access_token
CACHE_KEY = 'application_setting.last'
DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
@ -141,6 +142,7 @@ class ApplicationSetting < ActiveRecord::Base
before_save :ensure_runners_registration_token
before_save :ensure_health_check_access_token
before_save :ensure_container_registry_access_token
after_commit do
Rails.cache.write(CACHE_KEY, self)
@ -276,6 +278,10 @@ class ApplicationSetting < ActiveRecord::Base
ensure_health_check_access_token!
end
def container_registry_access_token
ensure_container_registry_access_token!
end
def sidekiq_throttling_enabled?
return false unless sidekiq_throttling_column_exists?

View file

@ -0,0 +1,31 @@
- @no_container = true
= render "admin/dashboard/head"
%div{ class: container_class }
%p.prepend-top-default
%span
To properly configure the Container Registry you should add the following
access token to the Docker Registry config.yml as follows:
%pre
%code
:plain
notifications:
endpoints:
- ...
headers:
X-Registry-Token: [#{@access_token}]
%br
Access token is
%code{ id: 'registry-token' } #{@access_token}
.bs-callout.clearfix
.pull-left
%p
You can reset container registry access token by pressing the button below.
%p
= button_to reset_container_registry_token_admin_application_settings_path,
method: :put, class: 'btn btn-default',
data: { confirm: 'Are you sure you want to reset container registry token?' } do
= icon('refresh')
Reset container registry access token

View file

@ -27,3 +27,7 @@
= link_to admin_runners_path, title: 'Runners' do
%span
Runners
= nav_link path: 'container_registry#show' do
= link_to admin_container_registry_path, title: 'Registry' do
%span
Registry

View file

@ -58,6 +58,7 @@ namespace :admin do
resource :background_jobs, controller: 'background_jobs', only: [:show]
resource :system_info, controller: 'system_info', only: [:show]
resources :requests_profiles, only: [:index, :show], param: :name, constraints: { name: /.+\.html/ }
resource :container_registry, controller: 'container_registry', only: [:show]
resources :projects, only: [:index]
@ -88,6 +89,7 @@ namespace :admin do
resources :services, only: [:index, :edit, :update]
put :reset_runners_token
put :reset_health_check_token
put :reset_container_registry_token
put :clear_repository_check_states
end

View file

@ -0,0 +1,29 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddContainerRegistryAccessTokenToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
add_column :application_settings, :container_registry_access_token, :string
end
end

View file

@ -76,7 +76,7 @@ you modify its settings. Read the upstream documentation on how to achieve that.
At the absolute minimum, make sure your [Registry configuration][registry-auth]
has `container_registry` as the service and `https://gitlab.example.com/jwt/auth`
as the realm:
as the realm.
```
auth:
@ -87,6 +87,23 @@ auth:
rootcertbundle: /root/certs/certbundle
```
Also a notification endpoint must be configured with the token from
Admin Area -> Overview -> Registry (`/admin/container_registry`) like in the following sample:
```
notifications:
endpoints:
- name: listener
url: https://gitlab.example.com/api/v3/registry_events
headers:
X-Registry-Token: [57Cx95fc2zHFh93VTiGD]
timeout: 500ms
threshold: 5
backoff: 1s
```
Check the [Registry endpoint configuration][registry-endpoint] for details.
## Container Registry domain configuration
There are two ways you can configure the Registry's external domain.
@ -477,7 +494,7 @@ configurable in future releases.
**GitLab 8.8 ([source docs][8-8-docs])**
- GitLab Container Registry feature was introduced.
i
[reconfigure gitlab]: restart_gitlab.md#omnibus-gitlab-reconfigure
[restart gitlab]: restart_gitlab.md#installations-from-source
[wildcard certificate]: https://en.wikipedia.org/wiki/Wildcard_certificate
@ -487,6 +504,7 @@ configurable in future releases.
[storage-config]: https://docs.docker.com/registry/configuration/#storage
[registry-http-config]: https://docs.docker.com/registry/configuration/#http
[registry-auth]: https://docs.docker.com/registry/configuration/#auth
[registry-endpoint]: https://docs.docker.com/registry/notifications/#/configuration
[token-config]: https://docs.docker.com/registry/configuration/#token
[8-8-docs]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-8-stable/doc/administration/container_registry.md
[registry-ssl]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/support/nginx/registry-ssl

View file

@ -299,8 +299,8 @@ could look like:
stage: build
script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.example.com
- docker build -t registry.example.com/group/project:latest .
- docker push registry.example.com/group/project:latest
- docker build -t registry.example.com/group/project/image:latest .
- docker push registry.example.com/group/project/image:latest
```
You have to use the special `gitlab-ci-token` user created for you in order to
@ -350,8 +350,8 @@ stages:
- deploy
variables:
CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project:$CI_BUILD_REF_NAME
CONTAINER_RELEASE_IMAGE: registry.example.com/my-group/my-project:latest
CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project/my-image:$CI_BUILD_REF_NAME
CONTAINER_RELEASE_IMAGE: registry.example.com/my-group/my-project/my-image:latest
before_script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.example.com

View file

@ -10,6 +10,7 @@
- Starting from GitLab 8.12, if you have 2FA enabled in your account, you need
to pass a personal access token instead of your password in order to login to
GitLab's Container Registry.
- Multiple level image names support was added in GitLab ?8.15?
With the Docker Container Registry integrated into GitLab, every project can
have its own space to store its Docker images.
@ -54,26 +55,23 @@ sure that you are using the Registry URL with the namespace and project name
that is hosted on GitLab:
```
docker build -t registry.example.com/group/project .
docker push registry.example.com/group/project
docker build -t registry.example.com/group/project/image .
docker push registry.example.com/group/project/image
```
Your image will be named after the following scheme:
```
<registry URL>/<namespace>/<project>
<registry URL>/<namespace>/<project>/<image>
```
As such, the name of the image is unique, but you can differentiate the images
using tags.
## Use images from GitLab Container Registry
To download and run a container from images hosted in GitLab Container Registry,
use `docker run`:
```
docker run [options] registry.example.com/group/project [arguments]
docker run [options] registry.example.com/group/project/image [arguments]
```
For more information on running Docker containers, visit the
@ -87,7 +85,8 @@ and click **Registry** in the project menu.
This view will show you all tags in your project and will easily allow you to
delete them.
![Container Registry panel](img/container_registry_panel.png)
![Container Registry panel](image-needs-update)
[//]: # (img/container_registry_panel.png)
## Build and push images using GitLab CI
@ -136,7 +135,7 @@ A user attempted to enable an S3-backed Registry. The `docker login` step went
fine. However, when pushing an image, the output showed:
```
The push refers to a repository [s3-testing.myregistry.com:4567/root/docker-test]
The push refers to a repository [s3-testing.myregistry.com:4567/root/docker-test/docker-image]
dc5e59c14160: Pushing [==================================================>] 14.85 kB
03c20c1a019a: Pushing [==================================================>] 2.048 kB
a08f14ef632e: Pushing [==================================================>] 2.048 kB
@ -229,7 +228,7 @@ a container image. You may need to run as root to do this. For example:
```sh
docker login s3-testing.myregistry.com:4567
docker push s3-testing.myregistry.com:4567/root/docker-test
docker push s3-testing.myregistry.com:4567/root/docker-test/docker-image
```
In the example above, we see the following trace on the mitmproxy window:

View file

@ -111,6 +111,16 @@ module API
end
end
def authenticate_container_registry_access_token!
token = request.headers['X-Registry-Token']
unless token.present? && ActiveSupport::SecurityUtils.variable_size_secure_compare(
token,
current_application_settings.container_registry_access_token
)
unauthorized!
end
end
def authenticated_as_admin!
authenticate!
forbidden! unless current_user.is_admin?

View file

@ -1,7 +1,7 @@
module API
# RegistryEvents API
class RegistryEvents < Grape::API
# before { authenticate! }
before { authenticate_container_registry_access_token! }
content_type :json, 'application/vnd.docker.distribution.events.v1+json'