Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
iamnoah committed Apr 14, 2021
2 parents 37c8fef + 93d76f9 commit 4983e5c
Show file tree
Hide file tree
Showing 12 changed files with 430 additions and 157 deletions.
90 changes: 90 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@ package main

import (
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"text/template"
"time"

"github.com/argoproj-labs/argocd-image-updater/pkg/argocd"
"github.com/argoproj-labs/argocd-image-updater/pkg/common"
"github.com/argoproj-labs/argocd-image-updater/pkg/env"
"github.com/argoproj-labs/argocd-image-updater/pkg/health"
"github.com/argoproj-labs/argocd-image-updater/pkg/image"
"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
"github.com/argoproj-labs/argocd-image-updater/pkg/log"
"github.com/argoproj-labs/argocd-image-updater/pkg/metrics"
"github.com/argoproj-labs/argocd-image-updater/pkg/registry"
"github.com/argoproj-labs/argocd-image-updater/pkg/tag"
"github.com/argoproj-labs/argocd-image-updater/pkg/version"

"github.com/spf13/cobra"
Expand All @@ -31,6 +36,9 @@ const defaultArgoCDServerAddr = "argocd-server.argocd"
// Default path to registry configuration
const defaultRegistriesConfPath = "/app/config/registries.conf"

// Default path to Git commit message template
const defaultCommitTemplatePath = "/app/config/commit.template"

const applicationsAPIKindK8S = "kubernetes"
const applicationsAPIKindArgoCD = "argocd"

Expand All @@ -51,6 +59,7 @@ type ImageUpdaterConfig struct {
AppNamePatterns []string
GitCommitUser string
GitCommitMail string
GitCommitMessage *template.Template
DisableKubeEvents bool
}

Expand Down Expand Up @@ -155,6 +164,7 @@ func runImageUpdater(cfg *ImageUpdaterConfig, warmUp bool) (argocd.ImageUpdaterR
DryRun: dryRun,
GitCommitUser: cfg.GitCommitUser,
GitCommitEmail: cfg.GitCommitMail,
GitCommitMessage: cfg.GitCommitMessage,
DisableKubeEvents: cfg.DisableKubeEvents,
}
res := argocd.UpdateApplication(upconf, syncState)
Expand Down Expand Up @@ -203,6 +213,7 @@ func newRootCommand() error {
rootCmd.AddCommand(newRunCommand())
rootCmd.AddCommand(newVersionCommand())
rootCmd.AddCommand(newTestCommand())
rootCmd.AddCommand(newTemplateCommand())
err := rootCmd.Execute()
return err
}
Expand Down Expand Up @@ -231,6 +242,55 @@ func newVersionCommand() *cobra.Command {
return versionCmd
}

func newTemplateCommand() *cobra.Command {
var (
commitMessageTemplatePath string
tplStr string
)
var runCmd = &cobra.Command{
Use: "template [<PATH>]",
Short: "Test & render a commit message template",
Long: `
The template command lets you validate your commit message template. It will
parse the template at given PATH and execute it with a defined set of changes
so that you can see how it looks like when being templated by Image Updater.
If PATH is not given, will show you the default message that is used.
`,
Run: func(cmd *cobra.Command, args []string) {
var tpl *template.Template
var err error
if len(args) != 1 {
tplStr = common.DefaultGitCommitMessage
} else {
commitMessageTemplatePath = args[0]
tplData, err := ioutil.ReadFile(commitMessageTemplatePath)
if err != nil {
log.Fatalf("%v", err)
}
tplStr = string(tplData)
}
if tpl, err = template.New("commitMessage").Parse(tplStr); err != nil {
log.Fatalf("could not parse commit message template: %v", err)
}
chL := []argocd.ChangeEntry{
{
Image: image.NewFromIdentifier("gcr.io/example/example:1.0.0"),
OldTag: tag.NewImageTag("1.0.0", time.Now(), ""),
NewTag: tag.NewImageTag("1.0.1", time.Now(), ""),
},
{
Image: image.NewFromIdentifier("gcr.io/example/updater@sha256:f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2"),
OldTag: tag.NewImageTag("", time.Now(), "sha256:01d09d19c2139a46aebfb577780d123d7396e97201bc7ead210a2ebff8239dee"),
NewTag: tag.NewImageTag("", time.Now(), "sha256:7aa7a5359173d05b63cfd682e3c38487f3cb4f7f1d60659fe59fab1505977d4c"),
},
}
fmt.Printf("%s\n", argocd.TemplateCommitMessage(tpl, "example-app", chL))
},
}
return runCmd
}

func newTestCommand() *cobra.Command {
var (
semverConstraint string
Expand Down Expand Up @@ -388,6 +448,8 @@ func newRunCommand() *cobra.Command {
var kubeConfig string
var disableKubernetes bool
var warmUpCache bool = true
var commitMessagePath string
var commitMessageTpl string
var runCmd = &cobra.Command{
Use: "run",
Short: "Runs the argocd-image-updater with a set of options",
Expand All @@ -414,6 +476,33 @@ func newRunCommand() *cobra.Command {
getPrintableHealthPort(cfg.HealthPort),
)

// User can specify a path to a template used for Git commit messages
if commitMessagePath != "" {
tpl, err := ioutil.ReadFile(commitMessagePath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
log.Warnf("commit message template at %s does not exist, using default", commitMessagePath)
commitMessageTpl = common.DefaultGitCommitMessage
} else {
log.Fatalf("could not read commit message template: %v", err)
}
} else {
commitMessageTpl = string(tpl)
}
}

if commitMessageTpl == "" {
log.Infof("Using default Git commit messages")
commitMessageTpl = common.DefaultGitCommitMessage
}

if tpl, err := template.New("commitMessage").Parse(commitMessageTpl); err != nil {
log.Fatalf("could not parse commit message template: %v", err)
} else {
log.Debugf("Successfully parsed commit message template")
cfg.GitCommitMessage = tpl
}

// Load registries configuration early on. We do not consider it a fatal
// error when the file does not exist, but we emit a warning.
if cfg.RegistriesConf != "" {
Expand Down Expand Up @@ -548,6 +637,7 @@ func newRunCommand() *cobra.Command {
runCmd.Flags().BoolVar(&warmUpCache, "warmup-cache", true, "whether to perform a cache warm-up on startup")
runCmd.Flags().StringVar(&cfg.GitCommitUser, "git-commit-user", env.GetStringVal("GIT_COMMIT_USER", "argocd-image-updater"), "Username to use for Git commits")
runCmd.Flags().StringVar(&cfg.GitCommitMail, "git-commit-email", env.GetStringVal("GIT_COMMIT_EMAIL", "noreply@argoproj.io"), "E-Mail address to use for Git commits")
runCmd.Flags().StringVar(&commitMessagePath, "git-commit-message-path", defaultCommitTemplatePath, "Path to a template to use for Git commit messages")
runCmd.Flags().BoolVar(&cfg.DisableKubeEvents, "disable-kube-events", env.GetBoolVal("IMAGE_UPDATER_KUBE_EVENTS", false), "Disable kubernetes events")

return runCmd
Expand Down
33 changes: 33 additions & 0 deletions docs/configuration/applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,36 @@ as the author. You can override the author using the
`--git-commit-user` and `--git-commit-email` command line switches or set
`git.user` and `git.email`
in the `argocd-image-updater-config` ConfigMap.

#### Changing the Git commit message

You can change the default commit message used by Argo CD Image Updater to some
message that best suites your processes and regulations. For this, a simple
template can be created (evaluating using the `text/template` Golang package)
and made available through setting the key `git.commit-message-template` in the
`argocd-image-updater-config` ConfigMap to the template's contents, e.g.

```yaml
data:
git.commit-message-template: |
build: automatic update of {{ .AppName }}
{{ range .AppChanges -}}
updates image {{ .Image }} tag '{{ .OldTag }}' to '{{ .NewTag }}'
{{ end -}}
```

Two top-level variables are provided to the template:

* `.AppName` is the name of the application that is being updated
* `.AppChanges` is a list of changes that were performed by the update. Each
entry in this list is a struct providing the following information for
each change:
* `.Image` holds the full name of the image that was updated
* `.OldTag` holds the tag name or SHA digest previous to the update
* `.NewTag` holds the tag name or SHA digest that was updated to

In order to test a template before configuring it for use in Image Updater,
you can store the template you want to use in a temporary file, and then use
the `argocd-image-updater template /path/to/file` command to render the
template using pre-defined data and see its outcome on the terminal.
29 changes: 23 additions & 6 deletions ext/git/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ type Refs struct {
// heads and remotes are also refs, but are not needed at this time.
}

// CommitOptions holds options for a git commit operation
type CommitOptions struct {
// CommitMessageText holds a short commit message (-m option)
CommitMessageText string
// CommitMessagePath holds the path to a file to be used for the commit message (-F option)
CommitMessagePath string
// SigningKey holds a GnuPG key ID used to sign the commit with (-S option)
SigningKey string
// SignOff specifies whether to sign-off a commit (-s option)
SignOff bool
}

// Client is a generic git client interface
type Client interface {
Root() string
Expand All @@ -60,7 +72,7 @@ type Client interface {
RevisionMetadata(revision string) (*RevisionMetadata, error)
VerifyCommitSignature(string) (string, error)
Branch(sourceBranch, targetBranch string) error
Commit(pathSpec string, message string, signingKey string) error
Commit(pathSpec string, opts *CommitOptions) error
Push(remote string, branch string, force bool) error
Add(path string) error
SymRefToBranch(symRef string) (string, error)
Expand Down Expand Up @@ -522,17 +534,22 @@ func (m *nativeGitClient) VerifyCommitSignature(revision string) (string, error)
// used as the commit message, otherwise a default commit message will be used.
// If signingKey is not the empty string, commit will be signed with the given
// GPG key.
func (m *nativeGitClient) Commit(pathSpec string, message string, signingKey string) error {
func (m *nativeGitClient) Commit(pathSpec string, opts *CommitOptions) error {
defaultCommitMsg := "Update parameters"
args := []string{"commit"}
if pathSpec == "" || pathSpec == "*" {
args = append(args, "-a")
}
if signingKey != "" {
args = append(args, "-S", signingKey)
if opts.SigningKey != "" {
args = append(args, "-S", opts.SigningKey)
}
if opts.SignOff {
args = append(args, "-s")
}
if message != "" {
args = append(args, "-m", message)
if opts.CommitMessageText != "" {
args = append(args, "-m", opts.CommitMessageText)
} else if opts.CommitMessagePath != "" {
args = append(args, "-F", opts.CommitMessagePath)
} else {
args = append(args, "-m", defaultCommitMsg)
}
Expand Down
12 changes: 6 additions & 6 deletions ext/git/mocks/Client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ext/git/mocks/Creds.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,16 @@ spec:
initialDelaySeconds: 3
periodSeconds: 30
volumeMounts:
- name: registries-conf
- name: image-updater-conf
mountPath: /app/config
serviceAccountName: argocd-image-updater
volumes:
- name: registries-conf
- name: image-updater-conf
configMap:
name: argocd-image-updater-config
optional: true
items:
- key: registries.conf
path: registries.conf
- key: git.commit-message-template
path: commit.template
6 changes: 4 additions & 2 deletions manifests/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,15 @@ spec:
periodSeconds: 30
volumeMounts:
- mountPath: /app/config
name: registries-conf
name: image-updater-conf
serviceAccountName: argocd-image-updater
volumes:
- configMap:
items:
- key: registries.conf
path: registries.conf
- key: git.commit-message-template
path: commit.template
name: argocd-image-updater-config
optional: true
name: registries-conf
name: image-updater-conf

0 comments on commit 4983e5c

Please sign in to comment.