Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Add git-crypt support #3239

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion chart/flux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ The following tables lists the configurable parameters of the Flux chart and the
| `git.pollInterval` | `5m` | Period at which to poll git repo for new commits
| `git.timeout` | `20s` | Duration after which git operations time out
| `git.secretName` | `None` | Kubernetes secret with the SSH private key. Superseded by `helmOperator.git.secretName` if set.
| `git.secret.enabled` | `false` | If set and a `.gitsecret` directory exist in the root of the git repository, Flux will execute a `git secret reveal -f` in the working clone before performing any operations
| `git.secret.enabled` | `false` | If set and a `.gitsecret` directory exist in the root of the git repository, Flux will execute a `git secret reveal -f` in the working clone before performing any operations; mutually exclusive with `git.crypt.enabled`
| `git.crypt.enabled` | `false` | If set and a `.git-crypt` directory exist in the root of the git repository, Flux will execute a `git crypt unlock` in the working clone before performing any operations; mutually exclusive with `git.secret.enabled`
| `git.config.enabled` | `false` | Mount `$HOME/.gitconfig` via Secret into the Flux and HelmOperator Pods, allowing for custom global Git configuration
| `git.config.secretName` | `Computed` | Kubernetes secret with the global Git configuration
| `git.config.data` | `None` | Global Git configuration per [git-config](https://git-scm.com/docs/git-config)
Expand Down
3 changes: 3 additions & 0 deletions chart/flux/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ spec:
- --git-verify-signatures={{ .Values.git.verifySignatures }}
- --git-set-author={{ .Values.git.setAuthor }}
{{- if .Values.git.secret.enabled }}
Copy link

Choose a reason for hiding this comment

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

this line should be deleted, as it causes a syntax error:
two opening if's but only one end.
This line is made obsolete by the next line :)

{{- if and .Values.git.secret.enabled (not .Values.git.crypt.enabled) }}
- --git-secret
{{- else if and .Values.git.crypt.enabled (not .Values.git.secret.enabled) }}
- --git-crypt
{{- end }}
- --git-poll-interval={{ .Values.git.pollInterval }}
- --git-timeout={{ .Values.git.timeout }}
Expand Down
11 changes: 11 additions & 0 deletions cmd/fluxd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func main() {
gitSetAuthor = fs.Bool("git-set-author", false, "if set, the author of git commits will reflect the user who initiated the commit and will differ from the git committer.")
gitLabel = fs.String("git-label", "", "label to keep track of sync progress; overrides both --git-sync-tag and --git-notes-ref")
gitSecret = fs.Bool("git-secret", false, `if set, git-secret will be run on every git checkout. A gpg key must be imported using --git-gpg-key-import or by mounting a keyring containing it directly`)
gitCrypt = fs.Bool("git-crypt", false, `if set, git-crypt will be run on every git checkout. A gpg key must be imported using --git-gpg-key-import or by mounting a keyring containing it directly`)
sopsEnabled = fs.Bool("sops", false, `if set, decrypt SOPS-encrypted manifest files with before syncing them. Provide decryption keys in the same way you would provide them for the sops binary. Be aware that manifests generated with .flux.yaml are not automatically decrypted`)
// Old git config; still used if --git-label is not supplied, but --git-label is preferred.
gitSyncTag = fs.String("git-sync-tag", defaultGitSyncTag, fmt.Sprintf("tag to use to mark sync progress for this cluster (only relevant when --sync-state=%s)", fluxsync.GitTagStateMode))
Expand Down Expand Up @@ -379,10 +380,18 @@ func main() {
}
mandatoryRegistry := stringset(*registryRequire)

if *gitSecret && *gitCrypt {
logger.Log("error", fmt.Sprintf("both --git-secret and --git-crypt are enabled, but these are mutually exclusive."), "err", err.Error())
}

if *gitSecret && len(*gitImportGPG) == 0 {
logger.Log("warning", fmt.Sprintf("--git-secret is enabled but there is no GPG key(s) provided using --git-gpg-key-import, we assume you mounted the keyring directly and continue"))
}

if *gitCrypt && len(*gitImportGPG) == 0 {
logger.Log("warning", fmt.Sprintf("--git-crypt is enabled but there is no GPG key(s) provided using --git-gpg-key-import, we assume you mounted the keyring directly and continue"))
}

if *sopsEnabled && len(*gitImportGPG) == 0 {
logger.Log("warning", fmt.Sprintf("--sops is enabled but there is no GPG key(s) provided using --git-gpg-key-import, we assume that the means of decryption has been provided in another way"))
}
Expand Down Expand Up @@ -676,6 +685,7 @@ func main() {
"notes-ref", *gitNotesRef,
"set-author", *gitSetAuthor,
"git-secret", *gitSecret,
"git-crypt", *gitCrypt,
"sops", *sopsEnabled,
)

Expand Down Expand Up @@ -733,6 +743,7 @@ func main() {
Logger: log.With(logger, "component", "daemon"),
ManifestGenerationEnabled: *manifestGeneration,
GitSecretEnabled: *gitSecret,
GitCryptEnabled: *gitCrypt,
LoopVars: &daemon.LoopVars{
SyncInterval: *syncInterval,
SyncTimeout: *syncTimeout,
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.flux
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM alpine:3.12

WORKDIR /home/flux

RUN apk add --no-cache openssh-client ca-certificates tini 'git>=2.24.2' 'gnutls>=3.6.7' 'glib>=2.62.5-r0' gnupg gawk socat
RUN apk add --no-cache openssh-client ca-certificates tini 'git>=2.24.2' 'gnutls>=3.6.7' 'glib>=2.62.5-r0' gnupg gawk socat git-crypt
RUN apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing git-secret

# Add git hosts to known hosts file so we can use
Expand Down
3 changes: 2 additions & 1 deletion docs/references/daemon.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ Version controlling of cluster manifests provides reproducibility and a historic
| --git-set-author | false | if set, the author of git commits will reflect the user who initiated the commit and will differ from the git committer
| --git-gpg-key-import | | if set, fluxd will attempt to import the gpg key(s) found on the given path
| --git-signing-key | | if set, commits made by fluxd to the user git repo will be signed with the provided GPG key.
| --git-secret | | if set and a `.gitsecret` directory exist in the root of the git repository, Flux will execute a `git secret reveal -f` in the working clone before performing any operations
| --git-secret | | if set and a `.gitsecret` directory exist in the root of the git repository, Flux will execute a `git secret reveal -f` in the working clone before performing any operations. mutually exclusive with `--git-crypt`
| --git-crypt | | if set and a `.git-crypt` directory exist in the root of the git repository, Flux will execute a `git crypt unlock` in the working clone before performing any operations. mutually exclusive with `--git-secret`
| --git-label | | label to keep track of sync progress; overrides both --git-sync-tag and --git-notes-ref
| --git-sync-tag | `flux-sync` | tag to use to mark sync progress for this cluster (old config, still used if --git-label is not supplied)
| --git-notes-ref | `flux` | ref to use for keeping commit annotations in git notes
Expand Down
9 changes: 9 additions & 0 deletions pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Daemon struct {
Logger log.Logger
ManifestGenerationEnabled bool
GitSecretEnabled bool
GitCryptEnabled bool
// bookkeeping
*LoopVars
}
Expand Down Expand Up @@ -667,6 +668,10 @@ func (d *Daemon) WithWorkingClone(ctx context.Context, fn func(*git.Checkout) er
if err := co.SecretUnseal(ctx); err != nil {
return err
}
} else if d.GitCryptEnabled {
if err := co.CryptUnseal(ctx); err != nil {
return err
}
}
return fn(co)
}
Expand All @@ -692,6 +697,10 @@ func (d *Daemon) WithReadonlyClone(ctx context.Context, fn func(*git.Export) err
if err := co.SecretUnseal(ctx); err != nil {
return err
}
} else if d.GitCryptEnabled {
if err := co.CryptUnseal(ctx); err != nil {
return err
}
}
return fn(co)
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/daemon/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ func (d *Daemon) cloneRepo(ctx context.Context, revision string) (clone *git.Exp
if err := clone.SecretUnseal(ctxGitOp); err != nil {
return nil, nil, err
}
} else if d.GitCryptEnabled {
ctxGitOp, cancel := context.WithTimeout(ctx, d.GitTimeout)
defer cancel()
if err := clone.CryptUnseal(ctxGitOp); err != nil {
return nil, nil, err
}
}

cleanup = func() {
Expand Down
10 changes: 9 additions & 1 deletion pkg/git/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var allowedEnvVars = []string{
"http_proxy", "https_proxy", "no_proxy", "HTTPS_PROXY", "NO_PROXY", "GIT_PROXY_COMMAND",
// these are needed for GPG to find its files
"HOME", "GNUPGHOME",
// these for the git-secrets helper
// these for the git-secrets/git-crypt helper
"SECRETS_DIR", "SECRETS_EXTENSION",
// these are for Google Cloud SDK to find its files (which will
// have to be mounted, if running in a container)
Expand Down Expand Up @@ -141,6 +141,14 @@ func secretUnseal(ctx context.Context, workingDir string) error {
return nil
}

func cryptUnseal(ctx context.Context, workingDir string) error {
args := []string{"crypt", "unlock"}
if err := execGitCmd(ctx, args, gitCmdConfig{dir: workingDir}); err != nil {
return errors.Wrap(err, "git crypt unlock")
}
return nil
}

func commit(ctx context.Context, workingDir string, commitAction CommitAction) error {
message, err := ioutil.TempFile("", "flux-commit-*.txt")
if err != nil {
Expand Down