Skip to content

Commit

Permalink
Enable the ability to run just once (#83)
Browse files Browse the repository at this point in the history
* Enable the ability to run just once

* Fix issues when enableMetrics is false. Fix some error handling
  • Loading branch information
sudermanjr authored Mar 6, 2023
1 parent 74c33ea commit f887eed
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
8 changes: 7 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -34,6 +34,7 @@ var (
tfCloudToken string
vaultTokenFile string
enableMetrics bool
runOnce bool
)

var rootCmd = &cobra.Command{
Expand All @@ -52,6 +53,10 @@ func run(cmd *cobra.Command, args []string) error {
}
app := app.NewApp(circleToken, vaultTokenFile, tfCloudToken, config, enableMetrics)

if runOnce {
app.EnableMetrics = false
return app.RunOnce()
}
return app.Run()
}

Expand All @@ -71,6 +76,7 @@ func init() {
rootCmd.Flags().StringVar(&tfCloudToken, "tfcloud-token", "", "A token for TFCloud access.")
rootCmd.Flags().StringVar(&vaultTokenFile, "vault-token-file", "", "A file that contains a vault token. Optional - can set VAULT_TOKEN directly if preferred.")
rootCmd.Flags().BoolVar(&enableMetrics, "enable-metrics", true, "Enable a prometheus endpoint on port 4329.")
rootCmd.Flags().BoolVar(&runOnce, "run-once", false, "If true, will run the token injection one time. Does not enable health endpoint or metrics.")

envMap := map[string]string{
"CIRCLE_CI_TOKEN": "circle-token",
Expand Down
41 changes: 33 additions & 8 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,29 +149,52 @@ func (a *App) Run() error {
}
}

// RunOnce just does a single run for use with a Kubernetes cronjob
func (a *App) RunOnce() error {

klog.Info("running the token injection once")

if err := a.refreshVaultToken(); err != nil {
return err
}
var wg sync.WaitGroup
for _, workspace := range a.Config.TFCloud {
wg.Add(1)
go a.updateTFCloudInstance(workspace, &wg)
}
for _, project := range a.Config.CircleCI {
wg.Add(1)
go a.updateCircleCIInstance(project, &wg)
}
wg.Wait()
return nil
}

func (a *App) updateCircleCIInstance(project CircleCIConfig, wg *sync.WaitGroup) {
defer wg.Done()
projName := project.Name
projVariableName := a.Config.TokenVariable
token, err := a.VaultClient.CreateToken(project.VaultRole, project.VaultPolicies, a.Config.TokenTTL, a.Config.OrphanTokens)
if err != nil {
a.incrementVaultError()
klog.Errorf("error making token for CircleCI project %s: %w", projName, err)
klog.Errorf("error making token for CircleCI project %s: %s", projName, err.Error())
return
}
klog.V(10).Infof("got token %s for CircleCI project %s", token.Auth.ClientToken, projName)
klog.Infof("setting env var %s to vault token value in CircleCI project %s", projVariableName, projName)
if err := circleci.UpdateEnvVar(projName, projVariableName, token.Auth.ClientToken, a.CircleToken); err != nil {
a.incrementCircleCIError()
klog.Errorf("error updating CircleCI project %s with token value: %w", projName, err)
klog.Errorf("error updating CircleCI project %s with token value: %s", projName, err.Error())
return
}
if err := circleci.UpdateEnvVar(projName, "VAULT_ADDR", a.Config.VaultAddress, a.CircleToken); err != nil {
a.incrementCircleCIError()
klog.Errorf("error updating VAULT_ADDR in CircleCI project %s: %w", projName, err)
klog.Errorf("error updating VAULT_ADDR in CircleCI project %s: %s", projName, err.Error())
return
}
a.Metrics.circleTokensUpdated.Inc()
if a.EnableMetrics {
a.Metrics.circleTokensUpdated.Inc()
}
}

func (a *App) updateTFCloudInstance(instance TFCloudConfig, wg *sync.WaitGroup) {
Expand All @@ -185,7 +208,7 @@ func (a *App) updateTFCloudInstance(instance TFCloudConfig, wg *sync.WaitGroup)
token, err := a.VaultClient.CreateToken(instance.VaultRole, instance.VaultPolicies, a.Config.TokenTTL, a.Config.OrphanTokens)
if err != nil {
a.incrementVaultError()
klog.Errorf("error getting vault token for TFCloud workspace %s: %w", workspaceLogIdentifier, err)
klog.Errorf("error getting vault token for TFCloud workspace %s: %s", workspaceLogIdentifier, err.Error())
return
}
klog.V(10).Infof("got token %v for tfcloud workspace %s", token.Auth.ClientToken, workspaceLogIdentifier)
Expand All @@ -199,7 +222,7 @@ func (a *App) updateTFCloudInstance(instance TFCloudConfig, wg *sync.WaitGroup)
}
if err := tokenVar.Update(); err != nil {
a.incrementTfCloudError()
klog.Errorf("error updating token for TFCloud workspace %s: %w", workspaceLogIdentifier, err)
klog.Errorf("error updating token for TFCloud workspace %s: %s", workspaceLogIdentifier, err.Error())
return
}
addressVar := tfcloud.Variable{
Expand All @@ -212,10 +235,12 @@ func (a *App) updateTFCloudInstance(instance TFCloudConfig, wg *sync.WaitGroup)
}
if err := addressVar.Update(); err != nil {
a.incrementTfCloudError()
klog.Errorf("error updating VAULT_ADDR for ws %s: %w", workspaceLogIdentifier, err)
klog.Errorf("error updating VAULT_ADDR for ws %s: %s", workspaceLogIdentifier, err.Error())
return
}
a.Metrics.tfcloudTokensUpdated.Inc()
if a.EnableMetrics {
a.Metrics.tfcloudTokensUpdated.Inc()
}
}

func (a *App) refreshVaultToken() error {
Expand Down
18 changes: 12 additions & 6 deletions pkg/app/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,22 @@ func (a *App) registerMetrics() {
}

func (a App) incrementVaultError() {
a.Metrics.vaultErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
if a.EnableMetrics {
a.Metrics.vaultErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
}
}

func (a App) incrementTfCloudError() {
a.Metrics.tfCloudErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
if a.EnableMetrics {
a.Metrics.tfCloudErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
}
}

func (a App) incrementCircleCIError() {
a.Metrics.circleCIErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
if a.EnableMetrics {
a.Metrics.circleCIErrorCount.Inc()
a.Metrics.totalErrorCount.Inc()
}
}

0 comments on commit f887eed

Please sign in to comment.