Skip to content
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
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ name: Build
jobs:
build:
env:
CONSUL_VERSION: 1.9.0
CONSUL_VERSION: 1.14.3
strategy:
matrix:
go-version: [ 1.14.x, 1.15.x ]
go-version: [ 1.18.x, 1.19.x ]
os: [ ubuntu-latest ]
runs-on: ${{matrix.os}}
steps:
- name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install Consul
run: |
mkdir -p $HOME/bin
Expand Down
3 changes: 1 addition & 2 deletions build/codeCheck.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#!/usr/bin/env bash


## ensure we have the misspell tool
## https://github.com/client9/misspell
if ! misspell=$(type -p "${GOPATH}/bin/misspell"); then
echo -n "Installing misspell ... "
go get -u github.com/client9/misspell/cmd/misspell
go install github.com/client9/misspell/cmd/misspell@latest
echo "done"
misspell=$(type -p "${GOPATH}/bin/misspell")
fi
Expand Down
65 changes: 50 additions & 15 deletions command/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,43 +54,78 @@ func (c *Command) backupKeys() (int, error) {

// backupACLs fetches acl tokens consul and writes them to a backup file
func (c *Command) backupACLs() (int, error) {
var acls []*api.ACLEntry // list of acl tokens
var opts *api.QueryOptions // client query options
var count int // token count
var data []byte // read tokens
var err error // general error holder
var aclData *common.BackupACLData // storage for acl data
var opts *api.QueryOptions // client query options
var roleCount int // role count
var policyCount int // policy count
var tokenCount int // token count
var data []byte
var err error // general error holder

// build backup acl data type
aclData = &common.BackupACLData{
Roles: make([]*api.ACLRole, 0),
Policies: make([]*api.ACLPolicy, 0),
Tokens: make([]*api.ACLToken, 0),
}

// build query options
opts = &api.QueryOptions{
AllowStale: false,
RequireConsistent: true,
}

// get all acl roles
if aclData.Roles, _, err = c.consulClient.ACL().RoleList(opts); err != nil {
return 0, err
}
// get all acl policies
if policies, _, err := c.consulClient.ACL().PolicyList(opts); err != nil {
return 0, err
} else {
for _, policy := range policies {
if aclPolicy, _, err := c.consulClient.ACL().PolicyRead(policy.ID, opts); err != nil {
return 0, err
} else {
aclData.Policies = append(aclData.Policies, aclPolicy)
}
}
}
// get all acl tokens
if acls, _, err = c.consulClient.ACL().List(opts); err != nil {
if tokens, _, err := c.consulClient.ACL().TokenList(opts); err != nil {
return 0, err
} else {
for _, token := range tokens {
if aclToken, _, err := c.consulClient.ACL().TokenRead(token.AccessorID, opts); err != nil {
return 0, err
} else {
aclData.Tokens = append(aclData.Tokens, aclToken)
}
}
}

// set count
count = len(acls)
// set counts
roleCount = len(aclData.Roles)
policyCount = len(aclData.Policies)
tokenCount = len(aclData.Tokens)

// check count
if count == 0 {
return 0, errors.New("No tokens found")
// check tokenCount
if tokenCount == 0 && roleCount == 0 && policyCount == 0 {
return 0, errors.New("no acl tokens, roles, or policies found")
}

// encode and return
if data, err = json.MarshalIndent(acls, "", " "); err != nil {
if data, err = json.MarshalIndent(aclData, "", " "); err != nil {
return 0, err
}

// write data to destination
// write acls to destination
if err = common.WriteData(c.config.aclFileName, c.config.cryptKey, data); err != nil {
return 0, err
}

// return token count - no error
return count, nil
// return token tokenCount - no error
return roleCount + policyCount + tokenCount, nil
}

// backupQueries fetches prepared query definitions from consul and writes them to a backup file
Expand Down
4 changes: 2 additions & 2 deletions command/restore/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ func (c *Command) Run(args []string) int {
// restore acls if requested
if c.config.aclFileName != "" {
if count, err = c.restoreACLs(); err != nil {
c.Log.Printf("[Error] Failed to restore ACL tokens: %s", err.Error())
c.Log.Printf("[Error] Failed to restore ACL items: %s", err.Error())
return 1
}

// show success
c.Log.Printf("[Success] Restored %d ACL tokens from %s to %s",
c.Log.Printf("[Success] Restored %d ACL roles, policies, and tokens from %s to %s",
count,
c.config.aclFileName,
c.config.consulConfig.Address)
Expand Down
51 changes: 38 additions & 13 deletions command/restore/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,60 @@ func (c *Command) restoreKeys() (int, error) {

// restoreACLs reads acl tokens from a backup file and restores them to consul
func (c *Command) restoreACLs() (int, error) {
var acls []*api.ACLEntry // acl tokens
var count int // token count
var data []byte // read json data
var err error // general error holder
var aclData common.BackupACLData // acl tokens
var roleCount int // role count
var policyCount int // policy count
var tokenCount int // token count
var data []byte // read json data
var err error // general error holder

// read json data from source
if data, err = common.ReadData(c.config.aclFileName, c.config.cryptKey); err != nil {
return 0, err
}

// decode data
if err = json.Unmarshal(data, &acls); err != nil {
if err = json.Unmarshal(data, &aclData); err != nil {
return 0, err
}

// loop through acls
for _, acl := range acls {
// loop through acl roles
for _, role := range aclData.Roles {
// write role
if _, _, err = c.consulClient.ACL().RoleCreate(role, nil); err != nil {
c.Log.Printf("[Warning] Failed to restore ACL role %s: %v",
role.Name, err)
} else {
// success - increment count
roleCount++
}
}

// loop through acl policies
for _, policy := range aclData.Policies {
if _, _, err := c.consulClient.ACL().PolicyCreate(policy, nil); err != nil {
c.Log.Printf("[Warning] Failed to restore ACL policy %s: %v",
policy.Name, err)
} else {
// success - increment count
policyCount++
}
}

// loop through acl tokens
for _, token := range aclData.Tokens {
// write token
if _, _, err = c.consulClient.ACL().Create(acl, nil); err != nil {
c.Log.Printf("[Warning] Failed to restore ACL token %s: %s",
acl.Name, err.Error())
if _, _, err = c.consulClient.ACL().TokenCreate(token, nil); err != nil {
c.Log.Printf("[Warning] Failed to restore ACL token with description %q: %v",
token.Description, err)
} else {
// success - increment count
count++
tokenCount++
}
}

// return acl count - no error
return count, nil
// return restored acl items count - no error
return roleCount + policyCount + tokenCount, nil
}

// restoreQueries reads query definitions from a backup file and restores them to consul
Expand Down
9 changes: 9 additions & 0 deletions common/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package common

import "github.com/hashicorp/consul/api"

type BackupACLData struct {
Roles []*api.ACLRole
Policies []*api.ACLPolicy
Tokens []*api.ACLToken
}
112 changes: 84 additions & 28 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,38 +1,94 @@
module github.com/myENA/consul-backinator

go 1.15
go 1.18

replace github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.7.0
require (
github.com/aws/aws-sdk-go v1.44.167
github.com/hashicorp/consul/api v1.18.0
github.com/hashicorp/consul/sdk v0.13.0
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-discover v0.0.0-20220909192527-49f60c093101
github.com/mitchellh/cli v1.1.5
github.com/stretchr/testify v1.8.1
)

require (
cloud.google.com/go v0.24.1-0.20180628163445-75763d24f380 // indirect
github.com/Azure/azure-sdk-for-go v17.4.0+incompatible // indirect
github.com/Azure/go-autorest v10.11.4+incompatible // indirect
github.com/Sirupsen/logrus v0.0.0-00010101000000-000000000000 // indirect
github.com/aws/aws-sdk-go v1.14.14
cloud.google.com/go v0.38.0 // indirect
github.com/Azure/azure-sdk-for-go v44.0.0+incompatible // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.5.0 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.1 // indirect
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/denverdino/aliyungo v0.0.0-20180626151132-3f1df87ed446 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/digitalocean/godo v1.3.1-0.20180606193730-a3505618b6f4 // indirect
github.com/go-ini/ini v1.37.1-0.20180615003539-cec2bdc49009 // indirect
github.com/golang/protobuf v0.0.0-20160829194233-1f49d83d9aa0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 // indirect
github.com/digitalocean/godo v1.7.5 // indirect
github.com/dimchansky/utfbom v1.1.0 // indirect
github.com/fatih/color v1.9.0 // indirect
github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 // indirect
github.com/gophercloud/gophercloud v0.0.0-20180626021939-19abc56a8cd8 // indirect
github.com/hashicorp/consul/api v1.8.0
github.com/hashicorp/consul/sdk v0.7.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-discover v0.0.0-20180607142956-283c00e7695d
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/gophercloud/gophercloud v0.1.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-hclog v0.12.0 // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/mdns v1.0.4 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62 // indirect
github.com/mitchellh/cli v1.1.0
github.com/nicolai86/scaleway-sdk v1.10.2-0.20170917185750-33df10cad9ff // indirect
github.com/linode/linodego v0.7.1 // indirect
github.com/mattn/go-colorable v0.1.6 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/miekg/dns v1.1.41 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect
github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
github.com/softlayer/softlayer-go v0.0.0-20180627132442-3aaf70665e74 // indirect
github.com/stretchr/testify v1.6.1
github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9 // indirect
github.com/vmware/govmomi v0.17.1 // indirect
github.com/vmware/vic v1.5.0-dev.0.20180628012636-fddf519e4fb8 // indirect
golang.org/x/oauth2 v0.0.0-20170313201147-1611bb46e67a // indirect
google.golang.org/api v0.0.0-20170125213714-dfa61ae24628 // indirect
google.golang.org/appengine v1.0.1-0.20161115221414-ca59ef35f409 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.0.6 // indirect
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.480 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.480 // indirect
github.com/vmware/govmomi v0.18.0 // indirect
go.opencensus.io v0.21.0 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/net v0.1.0 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/term v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
google.golang.org/api v0.4.0 // indirect
google.golang.org/appengine v1.5.0 // indirect
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 // indirect
google.golang.org/grpc v1.19.0 // indirect
gopkg.in/resty.v1 v1.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading