Browse Source

new: [docker-registry,docker-registry-auth] new charm

framadate
Valentin Lab 5 years ago
parent
commit
c08e2df39e
  1. 72
      docker-registry-auth/hooks/init
  2. 20
      docker-registry-auth/hooks/pre_deploy
  3. 50
      docker-registry-auth/hooks/registry_auth-relation-joined
  4. 12
      docker-registry-auth/hooks/web_proxy-relation-joined
  5. 55
      docker-registry-auth/lib/common
  6. 30
      docker-registry-auth/metadata.yaml
  7. 0
      docker-registry-auth/src/etc/default/docker-registry
  8. 0
      docker-registry-auth/src/etc/init.d/docker-registry
  9. 80
      docker-registry/hooks/init
  10. 0
      docker-registry/hooks/install
  11. 8
      docker-registry/hooks/pre_deploy
  12. 13
      docker-registry/hooks/registry_auth-relation-joined
  13. 22
      docker-registry/hooks/web_proxy-relation-joined
  14. 39
      docker-registry/lib/common
  15. 95
      docker-registry/metadata.yaml
  16. 8
      precise/docker-registry/metadata.yaml

72
docker-registry-auth/hooks/init

@ -0,0 +1,72 @@
#!/bin/bash
## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.
## Accessible variables are:
## - SERVICE_NAME Name of current service
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
. lib/common
set -e
if [ -e "$HOST_CONFIG_FILE" ]; then
echo > "$HOST_CONFIG_FILE"
else
mkdir -p "$(dirname "$HOST_CONFIG_FILE")"
touch "$HOST_CONFIG_FILE"
fi
init-config-add "
$SERVICE_NAME:
volumes:
- $HOST_CONFIG_FILE:$CONFIG_FILE
"
##
## Merge compose options
##
service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1
options=$(e "$service_def" | shyaml -y get-value "options") || true
if [ "$options" ]; then
while read-0 key value; do
case "$key" in
users)
user_conf=$(make_users_config "$value") || exit 1
e "$user_conf" | ini_merge
;;
acl)
yaml_key_val_str "$key" "$value" | ini_merge
;;
*)
err "Unknown key '$key' in options."
exit 1
;;
esac
done < <(e "$options" | shyaml key-values-0)
fi
## XXXvlab: ports should be not repeated (is repeated in charm metadata, or docker image)
ini_merge <<EOF
server:
addr: ":5001"
EOF
ini_merge <<EOF
token:
issuer: "Acme auth server"
expiration: 900
EOF
## Can be modified by web-proxy relation
echo "http://$SERVICE_NAME:5001" > "$SERVICE_CONFIGSTORE/etc/docker-auth/realm"

20
docker-registry-auth/hooks/pre_deploy

@ -0,0 +1,20 @@
#!/bin/bash
## Should be executable N time in a row with same result.
set -e
. lib/common
if [[ $(cat "$HOST_CONFIG_FILE" | shyaml keys) != *"_auth "* ]] &&
! cat "$HOST_CONFIG_FILE" | shyaml get-value users >/dev/null; then
err "No *_auth configured and no users list provided."
exit 1
fi
if ! cat "$HOST_CONFIG_FILE" | shyaml get-value acl; then
err "No acl configured."
exit 1
fi
registry_config_hash || exit 1

50
docker-registry-auth/hooks/registry_auth-relation-joined

@ -0,0 +1,50 @@
#!/bin/bash
set -e
. lib/common
LOCAL_CERTS_PATH=/etc/docker-auth/certs
certs_path="$SERVICE_CONFIGSTORE$LOCAL_CERTS_PATH"
mkdir -p "$certs_path"
(
cd "$certs_path"
openssl req -x509 -newkey rsa:2048 -new -nodes \
-keyout privkey.pem -out fullchain.pem \
-subj "/C=FR/ST=Paris/L=Paris/O=ACME/OU=IT Department/CN=[domain.tld]"
chmod 600 privkey.pem
)
cat <<EOF | ini_merge
token:
certificate: "$LOCAL_CERTS_PATH/fullchain.pem"
key: "$LOCAL_CERTS_PATH/privkey.pem"
EOF
config-add "\
services:
$TARGET_SERVICE_NAME:
volumes:
- \"$certs_path:$LOCAL_CERTS_PATH:ro\"
$BASE_SERVICE_NAME:
volumes:
- \"$certs_path:$LOCAL_CERTS_PATH:ro\"
"
realm=$(cat "$SERVICE_CONFIGSTORE/etc/docker-auth/realm") || exit 1
relation-set registry-config "\
token:
realm: \"$realm/auth\"
service: \"Docker registry\"
issuer: \"Acme auth server\"
autoredirect: false
rootcertbundle: \"$LOCAL_CERTS_PATH/fullchain.pem\"
"

12
docker-registry-auth/hooks/web_proxy-relation-joined

@ -0,0 +1,12 @@
#!/bin/bash
set -e
. lib/common
DOMAIN=$(relation-get domain) || exit 1
PROTO=$(relation-get protocol) || true
PROTO=${PROTO:-https}
echo "$PROTO://$DOMAIN" > $SERVICE_CONFIGSTORE/etc/docker-auth/realm

55
docker-registry-auth/lib/common

@ -0,0 +1,55 @@
# -*- mode: shell-script -*-
CONFIG_FILE=/etc/docker-auth/config.yml
HOST_CONFIG_FILE="$SERVICE_CONFIGSTORE$CONFIG_FILE"
ini_merge_str() {
local cfg="$1" \
cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(cat "$HOST_CONFIG_FILE")" | md5_compat)" \
result
if [ -z "$cfg" ]; then
return 0
fi
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file" || return 1
return 0
fi
result="$(merge_yaml_str "$(cat "$HOST_CONFIG_FILE")" "$cfg")" || return 1
e "$result" | tee "$cache_file" || return 1
}
ini_merge() {
local result
result=$(ini_merge_str "$(cat -)")
e "$result" > "$HOST_CONFIG_FILE"
}
make_users_config() {
local users_charm_cfg="$1"
echo "users:"
while read-0 user config; do
echo " \"$user\":"
password="$config"
##$(e "$config" | shyaml get-value password) || return 1
bcrypt=$(e "$password" | htpasswd -niB "$user" | cut -f 2 -d ":")
echo " password: \"$bcrypt\""
done < <(e "$users_charm_cfg" | shyaml key-values-0)
}
registry_config_hash() {
debug "Adding config hash to enable recreating upon config change."
config_hash=$(cat "$HOST_CONFIG_FILE" | md5_compat) || exit 1
init-config-add "
$MASTER_BASE_SERVICE_NAME:
labels:
- compose.config_hash=$config_hash
"
}

30
docker-registry-auth/metadata.yaml

@ -0,0 +1,30 @@
summary: "Authentication for docker Registry"
maintainer: "Valentin Lab <valentin.lab@kalysto.org>"
docker-image: docker.0k.io/docker-registry-auth:1.3.1
data-resources:
- /var/log/docker-auth
config-resources:
- /etc/docker-auth/
docker-compose:
command: /etc/docker-auth/config.yml
provides:
registry-auth:
default-options:
# users:
# mylogin: mypasswd
# acl:
# - match: {account: "admin"}
# actions: ["*"]
# comment: "Admin has full access to everything."
# - match: {account: "user"}
# actions: ["pull"]
# comment: "User \"user\" can pull stuff."
uses:
web-proxy:
#constraint: required | recommended | optional
constraint: recommended
solves:
proxy: "Public access"

0
precise/docker-registry/src/etc/default/docker-registry → docker-registry-auth/src/etc/default/docker-registry

0
precise/docker-registry/src/etc/init.d/docker-registry → docker-registry-auth/src/etc/init.d/docker-registry

80
docker-registry/hooks/init

@ -0,0 +1,80 @@
#!/bin/bash
## Init is run on host
## For now it is run every time the script is launched, but
## it should be launched only once after build.
## Accessible variables are:
## - SERVICE_NAME Name of current service
## - DOCKER_BASE_IMAGE Base image from which this service might be built if any
## - SERVICE_DATASTORE Location on host of the DATASTORE of this service
## - SERVICE_CONFIGSTORE Location on host of the CONFIGSTORE of this service
. lib/common
set -e
if [ -e "$HOST_CONFIG_FILE" ]; then
echo > "$HOST_CONFIG_FILE"
else
mkdir -p "$(dirname "$HOST_CONFIG_FILE")"
touch "$HOST_CONFIG_FILE"
fi
init-config-add "
$SERVICE_NAME:
volumes:
- $HOST_CONFIG_FILE:$CONFIG_FILE
"
ini_merge <<EOF || exit 1
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/docker-registry
http:
addr: $SERVICE_NAME:5000
net: tcp
host: http://$SERVICE_NAME:5000
## XXXvlab: not used for now
#secret: asecretforlocaldevelopment
relativeurls: false
# debug:
# addr: localhost:5001
# headers:
# X-Content-Type-Options: [nosniff]
# http2:
# disabled: false
EOF
##
## Merge compose options
##
service_def=$(get_compose_service_def "$SERVICE_NAME") || return 1
options=$(e "$service_def" | shyaml -y get-value "options") || true
if [ "$options" ]; then
while read-0 key value; do
case "$key" in
auth|storage|middleware|reporting|http|redis|version)
err "You should not configure '$key' in this charm."
exit 1
;;
log|loglevel|notifications|health|proxy|compatibility|validation)
continue
;;
*)
err "Unknown key '$key' in options."
exit 1
;;
esac
done < <(e "$options" | shyaml key-values-0)
e "$options" | ini_merge || exit 1
fi

0
precise/docker-registry/hooks/install → docker-registry/hooks/install

8
docker-registry/hooks/pre_deploy

@ -0,0 +1,8 @@
#!/bin/bash
## Should be executable N time in a row with same result.
set -e
. lib/common
registry_config_hash || exit 1

13
docker-registry/hooks/registry_auth-relation-joined

@ -0,0 +1,13 @@
#!/bin/bash
set -e
. lib/common
cfg=$(relation-get registry-config) || {
err "registry-auth $TARGET_SERVICE_NAME is expected to set 'registry-config'"
exit 1
}
yaml_key_val_str "auth" "$cfg" | ini_merge

22
docker-registry/hooks/web_proxy-relation-joined

@ -0,0 +1,22 @@
#!/bin/bash
set -e
. lib/common
DOMAIN=$(relation-get domain) || exit 1
PROTO=$(relation-get protocol) || true
PROTO=${PROTO:-https}
## These are mainly to setup the correct web-hook
if [ "$MASTER_BASE_SERVICE_NAME" == "$DOMAIN" ]; then
## This is because the IP will be the docker container version
PROTO=http
fi
ini_merge <<EOF
http:
host: $PROTO://$DOMAIN
EOF

39
docker-registry/lib/common

@ -0,0 +1,39 @@
# -*- mode: shell-script -*-
CONFIG_FILE=/etc/docker/registry/config.yml
HOST_CONFIG_FILE="$SERVICE_CONFIGSTORE$CONFIG_FILE"
ini_merge_str() {
local cfg="$1" \
cache_file="$CACHEDIR/$FUNCNAME.cache.$(p0 "$@" "$(cat "$HOST_CONFIG_FILE")" | md5_compat)" \
result
if [ -z "$cfg" ]; then
return 0
fi
if [ -e "$cache_file" ]; then
#debug "$FUNCNAME: SESSION cache hit $1"
cat "$cache_file" || return 1
return 0
fi
result="$(merge_yaml_str "$(cat "$HOST_CONFIG_FILE")" "$cfg")" || return 1
e "$result" | tee "$cache_file" || return 1
}
ini_merge() {
local result
result=$(ini_merge_str "$(cat -)")
e "$result" > "$HOST_CONFIG_FILE"
}
registry_config_hash() {
debug "Adding config hash to enable recreating upon config change."
config_hash=$(cat "$HOST_CONFIG_FILE" | md5_compat) || exit 1
init-config-add "
$MASTER_BASE_SERVICE_NAME:
labels:
- compose.config_hash=$config_hash
"
}

95
docker-registry/metadata.yaml

@ -0,0 +1,95 @@
summary: "Docker Registry"
maintainer: "Valentin Lab <valentin.lab@kalysto.org>"
inherit: base-0k
description: |
Docker Registry
docker-image: docker.0k.io/registry:2.0
data-resources:
- /var/lib/docker-registry
default-options:
# log:
# accesslog:
# disabled: true
# level: debug
# formatter: text
# fields:
# service: registry
# environment: staging
# hooks:
# - type: mail
# disabled: true
# levels:
# - panic
# options:
# smtp:
# addr: mail.example.com:25
# username: mailuser
# password: password
# insecure: true
# from: sender@example.com
# to:
# - errors@example.com
# notifications:
# endpoints:
# - name: alistener
# disabled: false
# url: https://my.listener.com/event
# headers: <http.Header>
# timeout: 500
# threshold: 5
# backoff: 1000
# ignoredmediatypes:
# - application/octet-stream
# health:
# storagedriver:
# enabled: true
# interval: 10s
# threshold: 3
# file:
# - file: /path/to/checked/file
# interval: 10s
# http:
# - uri: http://server.to.check/must/return/200
# headers:
# Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==]
# statuscode: 200
# timeout: 3s
# interval: 10s
# threshold: 3
# tcp:
# - addr: redis-server.domain.com:6379
# timeout: 3s
# interval: 10s
# threshold: 3
# proxy:
# remoteurl: https://registry-1.docker.io
# username: [username]
# password: [password]
# compatibility:
# schema1:
# signingkeyfile: /etc/registry/key.json
# validation:
# enabled: true
# manifests:
# urls:
# allow:
# - ^https?://([^/]+\.)*example\.com/
# deny:
# - ^https?://www\.example\.com/
uses:
registry-auth:
#constraint: required | recommended | optional
constraint: recommended
solves:
unmanaged-auth: "Authentication is not managed"
web-proxy:
#constraint: required | recommended | optional
constraint: recommended
solves:
proxy: "Public access"

8
precise/docker-registry/metadata.yaml

@ -1,8 +0,0 @@
name: docker-registry
summary: "Docker Registry"
maintainer: "Valentin Lab <valentin.lab@kalysto.org>"
inherit: base-0k
description: |
Docker Registry
data-resources:
- /var/lib/docker-registry
Loading…
Cancel
Save