Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

### Classes

#### Public Classes

* [`gitlab`](#gitlab): This module installs and configures Gitlab with the Omnibus package.
* [`gitlab::backup`](#gitlab--backup): This class is called from gitlab for backup config.
* [`gitlab::host_config`](#gitlab--host_config): This class is for setting host configurations required for gitlab installation.
Expand All @@ -14,6 +16,10 @@
* [`gitlab::omnibus_package_repository`](#gitlab--omnibus_package_repository): This class is used to configure gitlab repositories
* [`gitlab::service`](#gitlab--service): This class is meant to be called from gitlab. It ensure the service is running.

#### Private Classes

* `gitlab::initial_root_token`: Manages initial root token

### Defined types

* [`gitlab::custom_hook`](#gitlab--custom_hook): Manage custom hook files within a GitLab project.
Expand Down Expand Up @@ -129,6 +135,9 @@ The following parameters are available in the `gitlab` class:
* [`pgpass_file_location`](#-gitlab--pgpass_file_location)
* [`pgpass_file_ensure`](#-gitlab--pgpass_file_ensure)
* [`pgbouncer_password`](#-gitlab--pgbouncer_password)
* [`create_initial_root_token`](#-gitlab--create_initial_root_token)
* [`initial_root_token`](#-gitlab--initial_root_token)
* [`initial_root_token_ttl_minutes`](#-gitlab--initial_root_token_ttl_minutes)
* [`consul`](#-gitlab--consul)
* [`custom_hooks_dir`](#-gitlab--custom_hooks_dir)
* [`system_hooks_dir`](#-gitlab--system_hooks_dir)
Expand Down Expand Up @@ -919,6 +928,30 @@ Password for the gitlab-consul database user in the pgbouncer database

Default value: `undef`

##### <a name="-gitlab--create_initial_root_token"></a>`create_initial_root_token`

Data type: `Boolean`

Whether to create an initial root token. If set to true and initial_root_token is undef, a random token string will be generated.

Default value: `false`

##### <a name="-gitlab--initial_root_token"></a>`initial_root_token`

Data type: `Optional[Sensitive[String[1]]]`

Preset a root token to allow API usage immediately.

Default value: `undef`

##### <a name="-gitlab--initial_root_token_ttl_minutes"></a>`initial_root_token_ttl_minutes`

Data type: `Integer[0]`

Initial root token time to live (in minutes).

Default value: `60`

##### <a name="-gitlab--consul"></a>`consul`

Data type: `Optional[Hash]`
Expand Down
10 changes: 9 additions & 1 deletion manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,17 @@
# @param backup_cron_minute The minute when to run the daily backup cron job
# @param backup_cron_hour The hour when to run the daily backup cron job
# @param backup_cron_skips Array of items to skip valid values: db, uploads, repositories, builds, artifacts, lfs, registry, pages
# @param package_hold Wether to hold the specified package version. Available options are 'hold' or 'none'. Defaults to 'none'. Available only for Debian/Solaris package managers.
# @param package_hold Wether to hold the specified package version. Available options are 'hold' or 'none'. Defaults to 'none'. Available only for Debian/Solaris package managers.
# @param package_name The internal packaging system's name for the package. This name will automatically be changed by the gitlab::edition parameter. Can be overridden for the purposes of installing custom compiled version of gitlab-omnibus.
# @param manage_package Should the GitLab package be managed?
# @param repository_configuration A hash of repository types and attributes for configuraiton the gitlab package repositories. See docs in README.md
# @param manage_omnibus_repository Set to false if you wish to manage gitlab without configuring the package repository
# @param pgpass_file_location Path to location of .pgpass file used by consul to authenticate with pgbouncer database
# @param pgpass_file_ensure Create .pgpass file for pgbouncer authentication. When set to present requires valid value for pgbouncer_password.
# @param pgbouncer_password Password for the gitlab-consul database user in the pgbouncer database
# @param create_initial_root_token Whether to create an initial root token. If set to true and initial_root_token is undef, a random token string will be generated.
# @param initial_root_token Preset a root token to allow API usage immediately.
# @param initial_root_token_ttl_minutes Initial root token time to live (in minutes).
class gitlab (
Hash $repository_configuration,
# package configuration
Expand Down Expand Up @@ -224,6 +227,9 @@
Optional[Hash] $gitlab_workhorse = undef,
Optional[Hash] $user = undef,
Optional[Hash] $web_server = undef,
Boolean $create_initial_root_token = false,
Optional[Sensitive[String[1]]] $initial_root_token = undef,
Integer[0] $initial_root_token_ttl_minutes = 60,
Boolean $backup_cron_enable = false,
Integer[0,59] $backup_cron_minute = 0,
Integer[0,23] $backup_cron_hour = 2,
Expand All @@ -238,11 +244,13 @@
contain gitlab::omnibus_config
contain gitlab::install
contain gitlab::service
contain gitlab::initial_root_token

Class['gitlab::host_config']
-> Class['gitlab::omnibus_config']
-> Class['gitlab::install']
-> Class['gitlab::service']
-> Class['gitlab::initial_root_token']

$custom_hooks.each |$name, $options| {
gitlab::custom_hook { $name:
Expand Down
44 changes: 44 additions & 0 deletions manifests/initial_root_token.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# @summary Manages initial root token
#
# **NOTE** This hack allows to use the gitlab instance via API immediately.
# While this way is quite convenient, it cannot be called a good one..
# Use it at your own risk!
#
# Remove the /etc/gitlab/initial_root_token file to regenerate the token in a
# next Puppet run.
#
# @see https://docs.gitlab.com/administration/operations/rails_console/#using-the-rails-runner
# @see https://docs.gitlab.com/user/profile/personal_access_tokens/#create-a-personal-access-token-programmatically
#
# @api private
class gitlab::initial_root_token {
$token_file_path = '/etc/gitlab/initial_root_token'
$script_path = '/etc/gitlab/create_initial_root_token.rb'

if $gitlab::create_initial_root_token {
$script_ensure = 'file'
$script_content = epp('gitlab/create_initial_root_token.rb.epp',
token => $gitlab::initial_root_token,
token_ttl_minutes => $gitlab::initial_root_token_ttl_minutes,
token_file_path => $token_file_path,
)

# Execute after the script is created, but only if token is managed
exec { 'create_initial_root_token':
command => "/usr/bin/gitlab-rails runner '${script_path}'",
creates => $token_file_path,
require => File[$script_path],
}
} else {
$script_ensure = 'absent'
$script_content = undef
}

file { $script_path:
ensure => $script_ensure,
owner => 'root',
group => 'git', # gitlab-rails runner executes this script as 'git' user
mode => '0640',
content => $script_content,
}
}
28 changes: 27 additions & 1 deletion spec/classes/init_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
it { is_expected.to contain_class('gitlab::host_config').that_comes_before('Class[gitlab::install]') }
it { is_expected.to contain_class('gitlab::omnibus_config').that_comes_before('Class[gitlab::install]') }
it { is_expected.to contain_class('gitlab::install').that_comes_before('Class[gitlab::service]') }
it { is_expected.to contain_class('gitlab::service') }
it { is_expected.to contain_class('gitlab::service').that_comes_before('Class[gitlab::initial_root_token]') }
it { is_expected.to contain_class('gitlab::initial_root_token') }
it { is_expected.to contain_file('/etc/gitlab/create_initial_root_token.rb').with_ensure('absent') }
it { is_expected.not_to contain_exec('create_initial_root_token') }
it { is_expected.to contain_exec('gitlab_reconfigure').that_subscribes_to('Class[gitlab::omnibus_config]') }
it { is_expected.to contain_file('/etc/gitlab/gitlab.rb') }
it { is_expected.to contain_package('gitlab-omnibus').with_ensure('installed').with_name('gitlab-ce') }
Expand Down Expand Up @@ -511,6 +514,29 @@
is_expected.to contain_package('gitlab-omnibus').with('ensure' => '16.10.3-ce.0', 'name' => 'gitlab-ce', 'mark' => 'hold')
}
end
describe 'create_intial_root_token' do
let(:params) { { create_initial_root_token: true } }

it do
is_expected.to contain_file('/etc/gitlab/create_initial_root_token.rb').
with_content(%r{^token_value = 'glpat-' \+ SecureRandom.alphanumeric\(20\)$}).
with_content(%r{^token_ttl_minutes = 60$}).
with_content(%r{^token_file_path = '/etc/gitlab/initial_root_token'$})
end
it { is_expected.to contain_exec('create_initial_root_token').with_creates('/etc/gitlab/initial_root_token') }

describe 'initial_root_token' do
let(:params) { super().merge(initial_root_token: sensitive('foobarbaz')) }

it { is_expected.to contain_file('/etc/gitlab/create_initial_root_token.rb').with_content(%r{^token_value = 'foobarbaz'$}) }
end

describe 'initial_root_token_ttl_minutes' do
let(:params) { super().merge(initial_root_token_ttl_minutes: 123) }

it { is_expected.to contain_file('/etc/gitlab/create_initial_root_token.rb').with_content(%r{^token_ttl_minutes = 123$}) }
end
end
end
end
end
Expand Down
21 changes: 21 additions & 0 deletions templates/create_initial_root_token.rb.epp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%-|
Optional[Sensitive[String[1]]] $token,
Integer[0] $token_ttl_minutes,
Stdlib::AbsolutePath $token_file_path,
|-%>
# This scripts creates an initial root token and stores it to the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about a shebang line?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's executed through the Gitlab Rails Runner, so it shouldn't need one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add comment there to reduce confusion :)

# $token_file_path file.
require 'securerandom'

token_value = <%= $token.then |$x| { "'${$x.unwrap}'" }.lest || { "'glpat-' + SecureRandom.alphanumeric(20)" } %>
token_ttl_minutes = <%= $token_ttl_minutes %>
token_file_path = '<%= $token_file_path %>'

t = User.find(1).personal_access_tokens.create(
scopes: [:api],
name: 'Gitlab Puppet module initial root token',
expires_at: token_ttl_minutes.minutes.from_now,
)
t.set_token(token_value)
t.save!
File.write(token_file_path, token_value)
Loading