Closed shqear93 closed 4 years ago
the following should work.
docker-compose exec portus bundle exec rake portus:create_user[username email password admin]
the following should work.
docker-compose exec portus bundle exec rake portus:create_user[username email password admin]
hi @salzig , I am currently working on that issue, and I have a short question, beforeI give full feddback here :
Did you mean executing that inside the portus
, or the portus background
container ?
I have executed that inside the portus contianers, and apparently bunble
not present in the container, so I guess you build your own portus:development
image, while I used opensuse/portus:2.5
container distributions. Am I right ?
(also did the test based on `opensuse/portus:2.4.3)
Hi @shqear93 I have a solution here that I just sucessfully tested today, with portus version 2.4.3
, and here you go :
# The name of the portus container, but you could also use 'docker-compose exec'
export PORTUS_CONTAINER_NAME=${PORTUS_CONTAINER_NAME:-'portuscontainer'}
export FIRST_SUPER_ADMIN_USERNAME=superjbl
export FIRST_SUPER_ADMIN_PASSWORD=pokusportus
export FIRST_SUPER_ADMIN_EMAIL=jbl@pegasusio.io
export FIRST_SUPER_ADMIN_ROLE=admin
echo "Current working directory is [$(pwd)]. Creating Portus' first super admin [$FIRST_SUPER_ADMIN_USERNAME]... "
# docker-compose config && docker-compose exec portus bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME $FIRST_SUPER_ADMIN_EMAIL $FIRST_SUPER_ADMIN_PASSWORD $FIRST_SUPER_ADMIN_ROLE]
# docker-compose config && docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME $FIRST_SUPER_ADMIN_EMAIL $FIRST_SUPER_ADMIN_PASSWORD $FIRST_SUPER_ADMIN_ROLE]"
docker-compose config || exit 1
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i bundler -v 1.17.3"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && ./bin/bundle install"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && ./bin/bundle update --bundler"
# installation de rake
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i annotate"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i rake -v 12.3.2"
# Et creation du FIRST SUPER USER
# Now creating first super admin user, like we would create any other user, only
# we do want 'admin' role for this particular user.
#
# Extremely important down there :
# NO SPACES BETWEEN RAKE ARGS, AND COMMA SEPARATED ARGS
#
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && export RAILS_ENV=production && ./bin/bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME,$FIRST_SUPER_ADMIN_EMAIL,$FIRST_SUPER_ADMIN_PASSWORD,$FIRST_SUPER_ADMIN_ROLE]"
# Finally, note that the portus role for the newly created user, above
# named 'FIRST_SUPER_ADMIN_ROLE' ,can have either of the following values :
#
# - "admin" (that's the value used above)
# - "owner"
# - "contributor"
# - "viewer"
#
# An example of how to create a regular user with lowest permissions (viewer role) :
# username is "omersimpson", "omer@pegasusio.io" his email address, and "viewer"is its portus role.
# docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && export RAILS_ENV=production && ./bin/bundle exec rake portus:create_user[omersimpson,omer@pegasusio.io,$FIRST_SUPER_ADMIN_PASSWORD,viewer]"
jbl@poste-devops-typique:/tmp/portus.autopilot.provision.HhOb2D/portus/official/compose$ docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && export RAILS_ENV=production && ./bin/bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME,$FIRST_SUPER_ADMIN_EMAIL,$FIRST_SUPER_ADMIN_PASSWORD,FIRST_SUPER_ADMIN_ROLE]"
[Mailer config] Host: portus.test.lan
[Mailer config] Protocol: https://
User Exists (0.2ms) SELECT 1 AS one FROM `users` WHERE `users`.`username` = 'portus' LIMIT 1
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`username` = 'portus' LIMIT 1
(0.3ms) BEGIN
SQL (0.4ms) UPDATE `users` SET `encrypted_password` = '$2a$10$HROpzRDH.ujgCVNRC2.4J.oN1TAjlHFURF.tbxwWhJ1ahWpYp0K0y', `updated_at` = '2020-02-12 01:24:34' WHERE `users`.`id` = 1
(0.4ms) COMMIT
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`username` = 'portus' LIMIT 1
(0.2ms) SELECT COUNT(*) FROM `registries`
(0.3ms) SELECT COUNT(*) FROM `registries`
(0.3ms) BEGIN
User Exists (25.5ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'jbl@pegasusio.io' LIMIT 1
User Exists (0.5ms) SELECT 1 AS one FROM `users` WHERE `users`.`username` = BINARY 'superjbl' LIMIT 1
Namespace Exists (0.4ms) SELECT 1 AS one FROM `namespaces` WHERE `namespaces`.`name` = 'superjbl' LIMIT 1
SQL (30.0ms) INSERT INTO `users` (`username`, `encrypted_password`, `email`, `created_at`, `updated_at`) VALUES ('superjbl', '$2a$10$jxHUDJv2t2N5zyMzue2GzeitACxOm/1mpNEr/wbRCk2NfXKsXgJ3C', 'jbl@pegasusio.io', '2020-02-12 01:24:34', '2020-02-12 01:24:34')
(0.4ms) SELECT COUNT(*) FROM `registries`
(0.2ms) SELECT COUNT(*) FROM `registries`
Namespace Exists (0.2ms) SELECT 1 AS one FROM `namespaces` WHERE `namespaces`.`name` = 'superjbl' LIMIT 1
Team Exists (0.6ms) SELECT 1 AS one FROM `teams` WHERE `teams`.`name` = 'superjbl' LIMIT 1
Team Exists (0.5ms) SELECT 1 AS one FROM `teams` WHERE `teams`.`name` = BINARY 'superjbl' LIMIT 1
TeamUser Exists (0.5ms) SELECT 1 AS one FROM `team_users` WHERE (`team_users`.`user_id` = BINARY 3 AND `team_users`.`team_id` IS NULL) LIMIT 1
User Exists (0.5ms) SELECT 1 AS one FROM `users` WHERE (`users`.`email` = BINARY 'jbl@pegasusio.io' AND `users`.`id` != 3) LIMIT 1
User Exists (0.5ms) SELECT 1 AS one FROM `users` WHERE (`users`.`username` = BINARY 'superjbl' AND `users`.`id` != 3) LIMIT 1
SQL (0.3ms) INSERT INTO `teams` (`name`, `hidden`, `created_at`, `updated_at`) VALUES ('superjbl', 1, '2020-02-12 01:24:34', '2020-02-12 01:24:34')
TeamUser Exists (0.4ms) SELECT 1 AS one FROM `team_users` WHERE (`team_users`.`user_id` = BINARY 3 AND `team_users`.`team_id` = 4) LIMIT 1
SQL (0.3ms) INSERT INTO `team_users` (`role`, `user_id`, `team_id`, `created_at`, `updated_at`) VALUES (2, 3, 4, '2020-02-12 01:24:34', '2020-02-12 01:24:34')
TeamUser Exists (0.4ms) SELECT 1 AS one FROM `team_users` WHERE (`team_users`.`user_id` = BINARY 3 AND `team_users`.`id` != 5 AND `team_users`.`team_id` = 4) LIMIT 1
Registry Load (0.3ms) SELECT `registries`.* FROM `registries` ORDER BY `registries`.`id` ASC LIMIT 1
Namespace Load (0.4ms) SELECT `namespaces`.* FROM `namespaces` WHERE `namespaces`.`name` = 'superjbl' AND `namespaces`.`visibility` = 0 AND `namespaces`.`description` = 'This personal namespace belongs to superjbl.' AND `namespaces`.`team_id` = 4 AND `namespaces`.`registry_id` = 1 LIMIT 1
Namespace Exists (0.5ms) SELECT 1 AS one FROM `namespaces` WHERE (`namespaces`.`name` = BINARY 'superjbl' AND `namespaces`.`registry_id` = 1) LIMIT 1
SQL (0.3ms) INSERT INTO `namespaces` (`team_id`, `name`, `visibility`, `description`, `registry_id`, `created_at`, `updated_at`) VALUES (4, 'superjbl', 0, 'This personal namespace belongs to superjbl.', 1, '2020-02-12 01:24:34', '2020-02-12 01:24:34')
SQL (0.4ms) UPDATE `users` SET `username` = 'superjbl', `encrypted_password` = '$2a$10$jxHUDJv2t2N5zyMzue2GzeitACxOm/1mpNEr/wbRCk2NfXKsXgJ3C', `email` = 'jbl@pegasusio.io', `created_at` = '2020-02-12 01:24:34', `updated_at` = '2020-02-12 01:24:34', `id` = 3, `namespace_id` = 4 WHERE `users`.`id` = 3
(0.3ms) COMMIT
jbl@poste-devops-typique:/tmp/portus.autopilot.provision.HhOb2D/portus/official/compose$
docker login
using superjbl
as username,and pokusportus
, as password.2.5
soon, if u have results before me on 2.5
, and share, i'll read them with interest.Honestly, I think distributed containers are either a little bit trashy, or they are automated flows used by the project team, not documented for the public audience yet. Update: It actually is totally normal that rake and bundle are not distributed with app in container, and we shouldnot use rake or any "inside container" operation, to silently create first admin user, see my final note
Examining the commands I above execute in the docker container, you might askyouself a few questions. Here are a few answers.
RAILS_ENV=production
variable ..?
AnswerTo investigate "what's wrong with portus", I very early found that you can set portus log level using one environment variable for the portus run, PORTUS_LOG_LEVEL=debug
.
So I set that env., and what did i find in the portus container logs ? see for yourself :
jbl@poste-devops-typique:/tmp/portus.autopilot.provision.S7Ngyh/portus/official/compose$ docker-compose logs -f |more
Attaching to compose_registry_1, compose_background_1, portuscontainer, compose_
db_1
registry_1 | + cp /secrets/portus.crt /usr/local/share/ca-certificates
registry_1 | + update-ca-certificates
registry_1 | WARNING: ca-certificates.crt does not contain exactly one
certificate or CRL: skipping
registry_1 | + registry serve /etc/docker/registry/config.yml
registry_1 | time="2020-02-12T22:04:55Z" level=warning msg="No HTTP se
cret provided - generated random secret. This may cause problems with uploads if
multiple registries are behind a load-balancer. To provide a shared secret, fil
l in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET envir
onment variable." go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b919
8e223 version=v2.6.2-14-ga66a4c3
registry_1 | time="2020-02-12T22:04:55Z" level=info msg="configuring e
ndpoint portus (https://portus.pegasusio.io:3000/v2/webhooks/events), timeout=2s
, headers=map[]" go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b9198
e223 version=v2.6.2-14-ga66a4c3
registry_1 | time="2020-02-12T22:04:55Z" level=info msg="redis not con
figured" go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b9198e223 ver
sion=v2.6.2-14-ga66a4c3
registry_1 | time="2020-02-12T22:04:55Z" level=info msg="debug server
listening 0.0.0.0:5001"
registry_1 | time="2020-02-12T22:04:55Z" level=info msg="Starting uplo
ad purge in 27m0s" go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b91
98e223 version=v2.6.2-14-ga66a4c3
registry_1 | time="2020-02-12T22:04:55Z" level=info msg="listening on
[::]:5000, tls" go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b9198e
223 version=v2.6.2-14-ga66a4c3
registry_1 | time="2020-02-13T16:17:37Z" level=info msg="PurgeUploads
starting: olderThan=2020-02-06 16:17:37.814679695 +0000 UTC, actuallyDelete=true
"
registry_1 | time="2020-02-13T16:17:37Z" level=info msg="Purge uploads
finished. Num deleted=0, num errors=1"
registry_1 | time="2020-02-13T16:17:37Z" level=info msg="Starting uplo
ad purge in 24h0m0s" go.version=go1.7.6 instance.id=25680c74-8fa8-45a3-b049-1b8b
9198e223 version=v2.6.2-14-ga66a4c3
portuscontainer | PORTUS_DB_PASSWORD=portus
portuscontainer | PORTUS_DB_HOST=db
portuscontainer | HOSTNAME=077b7544ea42
portuscontainer | RAILS_SERVE_STATIC_ASSETS='true'
portuscontainer | PORTUS_DB_POOL=5
portuscontainer | CCONFIG_PREFIX=PORTUS
portuscontainer | PORTUS_KEY_PATH=/certificates/portus.key
portuscontainer | PORTUS_LDAP_AUTHENTICATION_PASSWORD=
portuscontainer | PWD=/
portuscontainer | PORTUS_PUMA_HOST=0.0.0.0:3000
portuscontainer | HOME=/root
portuscontainer | PORTUS_MACHINE_FQDN_VALUE=portus.pegasusio.io
portuscontainer | RAILS_SERVE_STATIC_FILES='true'
portuscontainer | PORTUS_EMAIL_SMTP_PASSWORD=
portuscontainer | GEM_PATH=/srv/Portus/vendor/bundle/ruby/2.5.0
portuscontainer | RAILS_ENV=production
portuscontainer | PORTUS_PASSWORD=12341234
portuscontainer | PORTUS_SECRET_KEY_BASE=b494a25faa8d22e430e843e220e424e1
0ac84d2ce0e64231f5b636d21251eb6d267adb042ad5884cbff0f3891bcf911bdf8abb3ce719849c
cda9a4889249e5c2
portuscontainer | RACK_ENV=production
portuscontainer | PORTUS_SERVICE_FQDN_VALUE=portus.pegasusio.io
portuscontainer | PORTUS_LOG_LEVEL=debug
portuscontainer | PORTUS_PUMA_TLS_CERT=/certificates/portus.crt
portuscontainer | SHLVL=2
portuscontainer | PORTUS_PUMA_TLS_KEY=/certificates/portus.key
portuscontainer | PORTUS_DB_DATABASE=portus_production
portuscontainer | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:
/sbin:/bin
portuscontainer | _=/usr/bin/printenv
portuscontainer | Waiting for mariadb to be ready in 5 seconds
portuscontainer | [Mailer config] Host: portus.pegasusio.io
portuscontainer | [Mailer config] Protocol: https://
portuscontainer | Configuring database...
portuscontainer | -- create_table("activities", {:force=>:cascade})
portuscontainer | (76.5ms) CREATE TABLE `activities` (`i
--More--
See the portuscontainer | RAILS_ENV=production
?
@shqear93 Waiting for your feedback to close the issue with @mssola validation I think
Update
So with the commands I gave, the output shows that I actually did not create a new user, there's an error about the use of the arguments.
We're not on a solution yet, but we're getting very close. I bring any news here as soon as I get something new.
RE-Update
Ok found the issue, see comma separated args (and no spaces) in the update code snippet above
(yeahhhh it works)
and you don't even have to restart portus!!
I above explained how to silently (non-interactively) create users with admin role in portus. Never the less, what @shqear93 wasasking for,is how to create the first super admin user, non interactively.
Two important things :
registry
in portus
, and that can be done using this :
export PORTUS_CONTAINER_NAME=${PORTUS_CONTAINER_NAME:-'portuscontainer'}
export REGISTRY_PORTUS_NAME=gracefulregistry
export REGISTRY_PORTUS_HOST=oci-registry.pegasusio.io:5000
export REGISTRY_PORTUS_USE_SSL=true
export REGISTRY_PORTUS_EXTERNAL_NAME=oci-registry.pegasusio.io
echo "Current working directory is [$(pwd)]. Configuring Portus' OCI image registry [$REGISTRY_PORTUS_HOST]... "
# docker-compose config && docker-compose exec portus bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME $FIRST_SUPER_ADMIN_EMAIL $FIRST_SUPER_ADMIN_PASSWORD $FIRST_SUPER_ADMIN_ROLE]
# docker-compose config && docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && bundle exec rake portus:create_user[$FIRST_SUPER_ADMIN_USERNAME $FIRST_SUPER_ADMIN_EMAIL $FIRST_SUPER_ADMIN_PASSWORD $FIRST_SUPER_ADMIN_ROLE]"
docker-compose config || exit 1
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i bundler -v 1.17.3"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && ./bin/bundle install"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && ./bin/bundle update --bundler"
# installation de rake
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i annotate"
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && gem i rake -v 12.3.2"
# Et configuration du registry docker dans portus
#
# Extremely important down there :
# NO SPACES BETWEEN RAKE ARGS, AND COMMA SEPARATED ARGS
#
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && export RAILS_ENV=production && ./bin/bundle exec rake portus:create_registry['$REGISTRY_PORTUS_NAME','$REGISTRY_PORTUS_HOST','$REGISTRY_PORTUS_USE_SSL','$REGISTRY_PORTUS_EXTERNAL_NAME']"
admin
role, the portus
user still isn't a super-admin : it doesn't have permissions to manage users and users' permissions. To do that, you have to execute the following, additionnaly to the above given script for creating a user : # Enfin, on définit le nouveau user, comme super-admin.
#
# http://port.us.org/docs/Configuring-Portus.html#creating-the-first-admin-user
#
docker exec $PORTUS_CONTAINER_NAME bash -c "cd /srv/Portus && export RAILS_ENV=production && ./bin/bundle exec rake portus:make_admin[$FIRST_SUPER_ADMIN_USERNAME]"
@shqear93 Now I think we can close this issue, can't we?
@mssola I'll read very carefully any remarks from you, do you think there are other aspects I missed here ?
@Jean-Baptiste-Lasselle Sorry for late, thank you very much for your help, I'll close the issue.
@shqear93 Hi again, I think we are going to keep this issue closed, but I have something that slowly builded up my mind, and I have to share with you, as it has great importance about production management :
portus
container, in order to be able to perform live ops.Ok, so my recommandation, is to NOT use the rake-based solution, but instead use the Portus API, with the following flow :
jq --version || sudo apt-get install -y jq || sudo yum install -y jq || sudo zypper install -y jq
export PORTUS_HOST=portus.pegasusio.io
# -- bootstrap (no one has opened the web ui and auto-registered as first super admin)
# first, we need the secret (the token) to authenticate to Portus API
# - The [/bootstrap] Endpoints, POST, to crate users, and PUT to modify permissions
# http://port.us.org/docs/API.html#spec-method-post-api-v1-users-bootstrap
# => With this first Portus API call, you retrieve in the response the token you are going to use to
# authenticate to the Portus REST API in all the next Portus API calls below
export FIRST_SUPER_ADMIN_USERNAME=superjbl
export FIRST_SUPER_ADMIN_PASSWORD=pokusportus
export FIRST_SUPER_ADMIN_EMAIL=jbl@pegasusio.io
# We don't need the role, cause bootstraping implicitly means
# giving admin role to bootstraped first user.
# export FIRST_SUPER_ADMIN_ROLE=admin
export PAYLOAD="{\"user\": {\"username\": \"$FIRST_SUPER_ADMIN_USERNAME\", \"email\": \"$FIRST_SUPER_ADMIN_EMAIL\", \"password\": \"$FIRST_SUPER_ADMIN_PASSWORD\", \"display_name\": \"$FIRST_SUPER_ADMIN_EMAIL\"}}"
curl --insecure -H 'Content-type: application/json' -H 'Accept: application/json' -X POST --data "$PAYLOAD" https://$PORTUS_HOST/api/v1/users/bootstrap > ./portus.bootstrap.json
export PORTUS_API_BOOT_TOKEN=(cat ./portus.bootstrap.json|jq '.plain_token'|awk -F '"' '{print $2}')
# And this one guy , $PORTUS_API_BOOT_TOKEN , it's your most critical portus secret, so you immediately secrue it into a secret manager like ansible secret manager, kubernetes / openshift secret manager, personally I prefer hashicorp vault.
# Then you'll use a credential helper, configured with your secret manager, to resolve your Portus API auth secret, for all subsequent Portus API calls.
# Or best: you revoke it once bootstrap process completed
#
# Now we can authenticate to portus api using the token :
# --- #
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/_ping | jq '.'
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/health | jq '.'
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/users | jq '.[]'
# --->> REGISTRY CONFIG
# ok, so now let's configure the OCI image regsitry in portus :
#
# 1./ Configuring the registry, so portus knows how to reach it, onthe network.
# [POST /api/v1/registries]
export PORTUS_REGISTRY_NAME=companyregistry
export PORTUS_REGISTRY_HOSTNAME=oci-registry.pegasusio.io:5000
export PORTUS_REGISTRY_USE_SSL=true
export PORTUS_REGISTRY_EXTERNAL_HOSTNAME=oci-registry.pegasusio.io
export PAYLOAD="{\"registry\": {\"name\": \"$PORTUS_REGISTRY_NAME\", \"hostname\": \"$PORTUS_REGISTRY_HOSTNAME\", \"use_ssl\": \"$PORTUS_REGISTRY_USE_SSL\", \"external_hostname\": \"$PORTUS_REGISTRY_EXTERNAL_HOSTNAME\"}}"
curl --insecure --header 'Content-type: application/json' --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" -X POST --data "$PAYLOAD" https://${PORTUS_HOST}/api/v1/registries | jq '.'
# 2./ After configuring the registry, we test itis reachable as is.
# [GET /api/v1/registries/validate]
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/registries/validate | jq '.'
# --- #
#
# Using the just created Bootstraped user, we could also now :
#
# => [docker login $OCI_REGISTRY_SERVICE_FQDN], using
# => but even after creating the registry, we could, but won't use the [PORTUS_API_BOOT_TOKEN] to [docker login $OCI_REGISTRY_SERVICE_FQDN] : it is just meant to bootstrap, and :
# => We use the token to create other users, with less privilege than the first super admin user : for example a Portus User with 'Contributor' Role,and probably set it as a ROBOT user.
# => We will then create token for that robot user, and docker login using that new token;
# => We should then even revoke/delete it.
# Here below I demonstrate how to create that robot user
export TEAM_BOT_USER_USERNAME=bumblebee
export TEAM_BOT_USER_EMAIL=bumblebee@pegasusio.io
export TEAM_BOT_USER_PASSWORD=beebeeio
export TEAM_BOT_USER_IS_BOT=true
export PAYLOAD="{\"user\": {\"username\": \"$TEAM_BOT_USER_USERNAME\", \"email\": \"$TEAM_BOT_USER_EMAIL\", \"password\": \"$TEAM_BOT_USER_PASSWORD\", \"display_name\": \"$TEAM_BOT_USER_USERNAME\", \"bot\": \"$TEAM_BOT_USER_IS_BOT\"}}"
curl --insecure -H 'Content-type: application/json' -H 'Accept: application/json' -H "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" -d "$PAYLOAD" -X POST https://${PORTUS_HOST}/api/v1/users > ./team.bot.user.portus.json
cat ./team.bot.user.portus.json | jq '.[]'
export TEAM_BOT_USER_ID=$(cat ./team.bot.user.portus.json | jq .id)
# So for silently (non-interactively) [docker login $OCI_REGISTRY_SERVICE_FQDN], After creating registry, we
# need to create an app token for the [$TEAM_BOT_USER_USERNAME] portus user.
# We'll do that using http://port.us.org/docs/API.html#spec-method-post-api-v1-users-{id}-application_tokens
# [POST /api/v1/users/{id}/application_tokens]
# As it is a bootstraped user, you may expect PORTUS_FIRST_SUPER_ADMIN_USER_ID=1
export PORTUS_USER_ID=$TEAM_BOT_USER_ID
export export PORTUS_APP_TOKEN_NAME=pokusbee
export PAYLOAD="{\"application\": \"$PORTUS_APP_TOKEN_NAME\", \"id\": \"$PORTUS_USER_ID\"}"
curl --insecure -H 'Content-type: application/json' -H 'Accept: application/json' -H "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" -X POST --data "$PAYLOAD" https://$PORTUS_HOST/api/v1/users/${PORTUS_USER_ID}/application_tokens > ./bee.oci.registry.auth.json
export BOT_OCI_REGISTRY_AUTH_TOKEN=$(cat bee.oci.registry.auth.json | jq '.plain_token' | awk -F '"' '{print $2}')
# And this one guy , $BOT_OCI_REGISTRY_AUTH_TOKEN , it's your most critical protus secret, so you immediately secrue it into a secret manager like ansible secret manager, kubernetes / openshift secret manager, personally I prefer hashicorp vault.
# Then you'll use a credential helper, configured with your secret manager, to resolve your Portus API auth secret, for all subsequent Portus API calls.
#
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ export PAYLOAD="{\"user\": {\"username\": \"obelix\", \"email\" : \"obelix@armorique.io\", \"password\" : \"idefixidefix\", \"display_name\" : \"obelixlegros\"}}"
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ echo "$PAYLOAD"
{"user": {"username": "obelix", "email" : "obelix@armorique.io", "password" : "idefixidefix", "display_name" : "obelixlegros"}}
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ curl --insecure -H 'Content-type: application/json' -H 'Accept: application/json' -X POST --data "$PAYLOAD" https://$PORTUS_HOST/api/v1/users/bootstrap
{"id":1,"application":"bootstrap","plain_token":"Lxy_z9MT8d1uBES3uwXK"}jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ export PORTUS_API_BOOT_TOKEN=(cat ./portus.bootstrap.json|jq '.plain_token'|awk -F '"' '{print $2}')
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ export FIRST_SUPER_ADMIN_USERNAME=obelix
jbl@poste-devops-jbl-16gbram:~/portus.autopilot.dev$ curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/users | jq '.[]'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 579 100 579 0 0 4438 0 --:--:-- --:--:-- --:--:-- 4453
{
"id": 1,
"username": "portus",
"email": "portus@portus.com",
"current_sign_in_at": null,
"last_sign_in_at": null,
"created_at": "2020-02-12T22:05:12.000Z",
"updated_at": "2020-02-12T22:05:21.000Z",
"admin": true,
"enabled": true,
"locked_at": null,
"namespace_id": null,
"display_name": null,
"bot": false
}
{
"id": 2,
"username": "obelix",
"email": "obelix@armorique.io",
"current_sign_in_at": null,
"last_sign_in_at": null,
"created_at": "2020-02-13T20:04:54.000Z",
"updated_at": "2020-02-13T20:04:54.000Z",
"admin": true,
"enabled": true,
"locked_at": null,
"namespace_id": null,
"display_name": "obelixlegros",
"bot": false
}
Portus API v1
, using the following syntax:
export PORTUS_HOST=portus.pegasusio.io
# -- bootstrap (no one has opened the web ui and auto-registered as first super admin)
# - The [/bootstrap] Endpoints, POST, to crate users, and PUT to modify permissions
# http://port.us.org/docs/API.html#spec-method-post-api-v1-users-bootstrap
# => With this one,you retrieve in the response the token you are going to use to
# authenticate to the Portus REST API in all the next Portus API calls below
export FIRST_SUPER_ADMIN_USERNAME=superjbl
export FIRST_SUPER_ADMIN_PASSWORD=pokusportus
export FIRST_SUPER_ADMIN_EMAIL=jbl@pegasusio.io
# We don't need the role, cause bootstraping implicitly means
# giving admin role to bootstraped first user.
# export FIRST_SUPER_ADMIN_ROLE=admin
export PAYLOAD="{\"user\": {\"username\": \"$FIRST_SUPER_ADMIN_USERNAME\", \"email\": \"$FIRST_SUPER_ADMIN_EMAIL\", \"password\": \"$FIRST_SUPER_ADMIN_PASSWORD\", \"display_name\": \"$FIRST_SUPER_ADMIN_EMAIL\"}}"
curl --insecure -H 'Content-type: application/json' -H 'Accept: application/json' -X POST --data $PAYLOAD https://$PORTUS_HOST/api/v1/users/bootstrap > ./portus.bootstrap.json
export PORTUS_API_BOOT_TOKEN=(cat ./portus.bootstrap.json|jq '.plain_token'|awk -F '"' '{print $2}')
# --- #
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/_ping | jq '.'
curl --insecure -X GET --header 'Accept: application/json' --header "Portus-Auth: $FIRST_SUPER_ADMIN_USERNAME:$PORTUS_API_BOOT_TOKEN" https://${PORTUS_HOST}/api/v1/users | jq '.[]'
#nobgifatdaemon
) for portus,# -- Registry configuration in the portus instance
# - The [/users] Endpoints, POST, to crate users, and PUT to modify permissions
# http://port.us.org/docs/API.html#spec-method-post-api-v1-registries
# -- And even the teams, namespaces, repositories, tags,everything
# Teams : http://port.us.org/docs/API.html#spec-teams
# - The [/users] Endpoints, POST, to crate users, and PUT to modify permissions
# http://port.us.org/docs/API.html#spec-method-put-api-v1-registries-{id}
@Jean-Baptiste-Lasselle
Thank you for you support, it was really helpful.
about your last updates, I suggest to make it a part of the entrypoint!
example: provide options like USER_CREATE
as environment variable to create a list of users with their passwords simply by passing this option to the docker container, inspired by DroneCI option DRONE_USER_CREATE
:
https://docs.drone.io/server/reference/drone-user-create/
what do you think?
@Jean-Baptiste-Lasselle Thank you for you support, it was really helpful. about your last updates, I suggest to make it a part of the entrypoint! example: provide options like
USER_CREATE
as environment variable to create a list of users with their passwords simply by passing this option to the docker container, inspired by DroneCI optionDRONE_USER_CREATE
: https://docs.drone.io/server/reference/drone-user-create/what do you think?
I updated several times yesterday, and now "it's stable" : at the time I write this sentence, I have tested everything, and the whole Portus REST API-based automation works with portus 2.4.3
(latest stable release of portus
).
I understand, with the drone.io documentation line you quote, that you state :
What if protus was working like drone.io ? (bootstrap first user using environment variables)
So, to answer your question, I today recommend a fully-Portus REST API-based automation for portus provisioning. But to give you an example relevant to your eyes, if i had to use drone.io for example, in building a CI/CD factory, my approach would be the following :
Ctrl + F
) the string And this one guy , $PORTUS_API_BOOT_TOKEN , it's your most critical portus secret
And this one guy , $PORTUS_API_BOOT_TOKEN , it's your most critical portus secret
comment, I explain that immediately after you get that token, you should secure it in a Secret manager,like HashiCorp Vaultor ansible secret manager@shqear93
drone.io and secret managers :
https://docs.drone.io/secret/external/vault/ : i'm almost sure this one talks about hashicorp vault, as an external service, that can be integrated with drone
https://docs.drone.io/runner/extensions/vault/ : I did not quite understand this one yet, I also found https://github.com/drone/drone-vault
I just implemented my private registry in my automation server stack, I'm trying to create first user automatically without using UI because I'm already building CI/CD system and it doesn't make sense to set it using UI ! Is there any way to create first user and first registry within the initialisation using docker-compose file?
I'm using the latest portus version 2.4.3