Skip to content

Commit

Permalink
#1: Implements sync policies logic from config
Browse files Browse the repository at this point in the history
  • Loading branch information
erikreinert committed Mar 22, 2020
1 parent 84dc046 commit 1437664
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### vaultsync ###
policies/
config.json

# Created by https://www.gitignore.io/api/go,osx,vim,windows
Expand Down
23 changes: 23 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
services:
source:
cap_add:
- IPC_LOCK
environment:
VAULT_DEV_ROOT_TOKEN_ID: d23c2d2a-a6a8-4742-9b61-c8c9a5f1031b
image: vault:1.3.4
ports:
- "127.0.0.1:8300:8200"
volumes:
- source:/vault/file
target:
environment:
VAULT_DEV_ROOT_TOKEN_ID: 709e007e-a35c-4b3d-8c86-e393fb851ace
image: vault:1.3.4
ports:
- "127.0.0.1:8200:8200"
volumes:
- target:/vault/file
version: "3.7"
volumes:
source:
target:
48 changes: 41 additions & 7 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
)

// ConfigAuth : auth configuration
type ConfigAuth struct {
Address string `json:"address"`
Credentials map[string]string `json:"credentials"`
Method string `json:"method"`
}
Expand All @@ -22,15 +28,18 @@ type ConfigSecret struct {

// Config : configuration for vaultsync
type Config struct {
SourceAddr string `json:"vault_source_addr"`
SourceAuth ConfigAuth `json:"vault_source_auth"`
SourceSecrets []ConfigSecret `json:"vault_source_secrets"`
SourceToken string `json:"vault_source_token"`
TargetAddr string `json:"vault_target_addr"`
TargetToken string `json:"vault_target_token"`
SourceAuth ConfigAuth `json:"source_auth"`
SourceSecrets []ConfigSecret `json:"source_secrets"`
SourcePoliciesPath string `json:"source_policies_path"`
TargetAuth ConfigAuth `json:"target_auth"`
}

// GetConfig : gets configuration
// FilenameWithoutExt : removes extension from filename
func FilenameWithoutExt(name string) string {
return strings.TrimSuffix(name, path.Ext(name))
}

// GetConfig : gets configuration from path
func GetConfig(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)

Expand All @@ -50,3 +59,28 @@ func GetConfig(path string) (*Config, error) {

return &config, nil
}

// GetPolicies : gets all policies from path
func GetPolicies(path string) ([]os.FileInfo, error) {
policies := make([]os.FileInfo, 0)

dir, err := ioutil.ReadDir(path)

if err != nil {
return nil, err
}

for _, f := range dir {
name := f.Name()

file := fmt.Sprintf("%s/%s", path, name)

extension := filepath.Ext(file)

if extension == ".hcl" {
policies = append(policies, f)
}
}

return policies, nil
}
18 changes: 15 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,33 @@ func main() {
logrus.Fatal("invalid_config")
}

client, err := NewClient(config.TargetAddr, config.TargetToken)
targetToken, err := Login(config.TargetAuth)

if err != nil {
logrus.Fatal(err)
}

syncEnginesErr := SyncEngines(client, config)
targetClient, err := NewClient(config.TargetAuth.Address, *targetToken)

if err != nil {
logrus.Fatal(err)
}

syncEnginesErr := SyncEngines(targetClient, config)

if syncEnginesErr != nil {
logrus.Fatal(syncEnginesErr)
}

syncSecretsErr := SyncSecrets(client, config)
syncSecretsErr := SyncSecrets(targetClient, config)

if syncSecretsErr != nil {
logrus.Fatal(syncSecretsErr)
}

syncPoliciesErr := SyncPolicies(targetClient, config)

if syncEnginesErr != nil {
logrus.Fatal(syncPoliciesErr)
}
}
84 changes: 64 additions & 20 deletions vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"github.com/hashicorp/vault/api"
"github.com/sirupsen/logrus"
)

// AppRole : defines app role for authentication
type AppRole struct {
RoleID string `json:"role_id"`
SecretID string `json:"secret_id"`
}

// LoginAuthResult : defines vault successful login
type LoginAuthResult struct {
Accessor string `json:"accessor"`
ClientToken string `json:"client_token"`
Expand All @@ -29,31 +32,39 @@ type LoginResult struct {
}

// Login : login to Vault
func Login(config *Config) (*string, error) {
auth := AppRole{
RoleID: config.SourceAuth.Credentials["role_id"],
SecretID: config.SourceAuth.Credentials["secret_id"],
}
func Login(auth ConfigAuth) (*string, error) {
var token string

data, err := json.Marshal(auth)
if auth.Method == "approle" {
approle := AppRole{
RoleID: auth.Credentials["role_id"],
SecretID: auth.Credentials["secret_id"],
}

if err != nil {
return nil, err
}
data, err := json.Marshal(approle)

url := fmt.Sprintf("%s/v1/auth/approle/login", config.SourceAddr)
if err != nil {
return nil, err
}

resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
url := fmt.Sprintf("%s/v1/auth/approle/login", auth.Address)

if err != nil {
return nil, err
}
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))

var result LoginResult
if err != nil {
return nil, err
}

var result LoginResult

json.NewDecoder(resp.Body).Decode(&result)
json.NewDecoder(resp.Body).Decode(&result)

token = result.Auth.ClientToken
}

token := result.Auth.ClientToken
if auth.Method == "token" {
token = auth.Credentials["token"]
}

return &token, nil
}
Expand Down Expand Up @@ -131,21 +142,54 @@ func SyncEngines(client *api.Client, config *Config) error {
return nil
}

// SyncPolicies : syncs policies to client Vault service
func SyncPolicies(client *api.Client, config *Config) error {
policies, err := GetPolicies(config.SourcePoliciesPath)

if err != nil {
return err
}

sys := client.Sys()

for _, p := range policies {
filename := p.Name()

path := fmt.Sprintf("%s/%s", config.SourcePoliciesPath, filename)

policy, err := ioutil.ReadFile(path)

if err != nil {
return err
}

name := FilenameWithoutExt(filename)

putErr := sys.PutPolicy(name, string(policy))

if putErr != nil {
return err
}
}

return nil
}

// SyncSecrets : sync secrets from source to target
func SyncSecrets(client *api.Client, config *Config) error {
token, err := Login(config)
sourceToken, err := Login(config.SourceAuth)

if err != nil {
return err
}

sourceClient, err := NewClient(config.SourceAddr, config.SourceToken)
sourceClient, err := NewClient(config.SourceAuth.Address, *sourceToken)

if err != nil {
return err
}

sourceClient.SetToken(*token)
sourceClient.SetToken(*sourceToken)

source := sourceClient.Logical()

Expand Down

0 comments on commit 1437664

Please sign in to comment.