Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow another process (eg Vault Agent) #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ If your configuration is right and Vault is running on the same host as the agen

`approle` Specifies the approle name used to login. Defaults to "approle".

`token_path` Specifies the path to a file containing a Vault token, if one exists (e.g. a Vault Agent might already be running along the Vault Server, and it writes a token to the Sink file path). If this is specified, approle authentication is skipped. This token must have a policy with at least the permissions described in the authentication section.

### Storage options

Note that if you specify more than one storage option, *all* options will be written to. For example, specifying `local_storage` and `aws_storage` will write to both locations.
Expand Down Expand Up @@ -118,7 +120,7 @@ Note that if you specify more than one storage option, *all* options will be wri

## Authentication

You must do some quick initial setup prior to being able to use the Snapshot Agent. This involves the following:
Unless another process like a Vault Agent is providing the Snapshot Agent with a token (specified via the `token_path` configuration), you must do some quick initial setup prior to being able to use the Snapshot Agent. This involves the following:

`vault login` with an admin user.
Create the following policy `vault policy write snapshot ./my_policies/snapshot_policy.hcl`
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Configuration struct {
RoleID string `json:"role_id"`
SecretID string `json:"secret_id"`
Approle string `json:"approle"`
TokenPath string `json:"token_path"`
}

// AzureConfig is the configuration for Azure blob snapshots
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ func main() {

for {
if snapshotter.TokenExpiration.Before(time.Now()) {
snapshotter.SetClientTokenFromAppRole(c)
snapshotter.SetClientToken(c)
}
leader, err := snapshotter.API.Sys().Leader()
if err != nil {
log.Println(err.Error())
log.Fatalln("Unable to determine leader instance. The snapshot agent will only run on the leader node. Are you running this daemon on a Vault instance?")
}
leaderIsSelf := leader.IsSelf
if ! leaderIsSelf {
if !leaderIsSelf {
log.Println("Not running on leader node, skipping.")
} else {
var snapshot bytes.Buffer
Expand Down
30 changes: 27 additions & 3 deletions snapshot_agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package snapshot_agent

import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
Expand Down Expand Up @@ -70,14 +72,36 @@ func (s *Snapshotter) ConfigureVaultClient(config *config.Configuration) error {
return err
}
s.API = api
err = s.SetClientTokenFromAppRole(config)
err = s.SetClientToken(config)
if err != nil {
return err
}
return nil
}

func (s *Snapshotter) SetClientTokenFromAppRole(config *config.Configuration) error {
func (s *Snapshotter) SetClientToken(config *config.Configuration) error {
if config.TokenPath != "" {
// The process generating this token file (e.g. a Vault Agent) should be
// renewing or replacing the underlying token appropriately.
cBytes, err := ioutil.ReadFile(config.TokenPath)
if err != nil {
return fmt.Errorf("error reading the given TokenPath: %s", err)
}
token := string(cBytes)
s.API.SetToken(token)
childInfo, err := s.API.Auth().Token().LookupSelf()
if err != nil {
s.API.ClearToken()
return fmt.Errorf("error looking up provided token: %s", err)
}
ttl, err := childInfo.Data["ttl"].(json.Number).Int64()
if err != nil {
s.API.ClearToken()
return fmt.Errorf("error converting ttl to int: %s", err)
}
s.TokenExpiration = time.Now().Add(time.Duration((time.Second * time.Duration(ttl)) / 2))
return nil
}
data := map[string]interface{}{
"role_id": config.RoleID,
"secret_id": config.SecretID,
Expand All @@ -86,7 +110,7 @@ func (s *Snapshotter) SetClientTokenFromAppRole(config *config.Configuration) er
if config.Approle != "" {
approle = config.Approle
}
resp, err := s.API.Logical().Write("auth/" + approle + "/login", data)
resp, err := s.API.Logical().Write("auth/"+approle+"/login", data)
if err != nil {
return fmt.Errorf("error logging into AppRole auth backend: %s", err)
}
Expand Down