Over three years ago we introduced git and systemd custom propmise types.
While these are quite functional I recently needed to manage a git repository that was private and so needed a way to authenticate to a git server, in this case gitlab.
Gitlab has project access tokens but we didn’t directly support any sort of authentication attributes on the promise type.
I ran across git credential as a way to provide authentication and thought it was a good fit.
I developed some policy which kept the token secure via cf-secret and setup the needed dot files in /root
to setup git credentials.
bundle agent manage_private_repo
{
vars:
"source_directory" string => "/var/cfengine/masterfiles/files/buildhost";
"keys" slist => { "username", "password" };
"secret_path[${keys}]" string => "${sys.statedir}/private-repo-deploy-token-${keys}";
"credentials_final" string => "/root/.git-credentials";
"credentials_staged" string => "${credentials_final}.staged";
packages:
linux::
"git";
git:
credentials_ok::
"private-repo"
repository => "https://gitlab.com/organization/private-repo.git",
version => "master",
destination => "/home/user/private-repo";
classes:
"git_credentials_exists" expression => fileexists("${credentials_final}");
"username_newer_than_credentials" expression => isnewerthan("${secret_path[username]}", "${credentials_final}");
"password_newer_than_credentials" expression => isnewerthan("${secret_path[password]}", "${credentials_final}");
"update_git_stuff" expression => or(not(git_credentials_exists), username_newer_than_credentials, password_newer_than_credentials);
commands:
"{ echo -n 'https://'; cf-secret decrypt ${secret_path[username]} -o - | tr -d '\n' | sed 's/+/%2b/'; echo -n ':'; cf-secret decrypt ${secret_path[password]} -o - | tr -d '\n'; echo '@gitlab.com'; } > ${credentials_staged}"
contain => in_shell,
handle => "staged_credentials_rendered";
files:
"${credentials_final}"
copy_from => local_dcp("${credentials_staged}"),
depends_on => { "staged_credentials_rendered" },
classes => scoped_classes_generic("bundle", "credentials");
"${sys.statedir}/private-repo-deploy-token-${keys}" copy_from => remote_dcp("${source_directory}/user-vms-deploy-token-${keys}", "${sys.policy_hub}");
"/root/.gitconfig" content => "
[credential]
helper = store
[safe]
directory = /home/user/private-repo
";
"/home/user/private-repo/."
depth_search => recurse_with_base(inf),
perms => owner("user");
reports:
DEBUG::
"secret_paths are ${secret_path[username]} and ${secret_path[password]}";
DEBUG.git_credentials_exists::
"git_credentials_exists is defined";
DEBUG.username_newer_than_credentials::
"username_newer_than_credentials";
DEBUG.password_newer_than_credentials::
"password_newer_than_credentials";
}
I can encrypt to one or more hosts with the cf-secret
command and save the encrypted files in my policy set.
Check out more in this series of monthly module blogs and consider what you might contribute!
Questions?
If you have questions or need help, reach out on the mailing list or GitHub discussions. If you have a support contract, feel free to open a ticket in our support system.