Skip to content

Commit

Permalink
Work on reload support and config dir files
Browse files Browse the repository at this point in the history
  • Loading branch information
tlm committed Oct 12, 2018
1 parent 79b2c18 commit 7132d9a
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 93 deletions.
50 changes: 50 additions & 0 deletions cmd/config/anchor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package config

import (
"encoding/json"
"fmt"

"github.com/pkg/errors"

"github.com/tlmiller/disttrust/conductor"
"github.com/tlmiller/disttrust/provider"
)

type Anchor struct {
Action Action `json:"action"`
AltNames []string `json:"altNames"`
CommonName string `json:"cn"`
Dest string `json:"dest"`
DestOptions json.RawMessage `json:"destOpts"`
Name string `json:"name"`
Provider string `json:"provider"`
}

type ProviderFixer func(string) (provider.Provider, bool)

func AnchorsToMembers(anchors []Anchor, fixer ProviderFixer) ([]conductor.Member, error) {
members := []conductor.Member{}
for _, anchor := range anchors {
aprovider, exists := fixer(anchor.Provider)
if !exists {
return nil, fmt.Errorf("no provider found for %s", anchor.Provider)
}

req := provider.Request{}
req.CommonName = anchor.CommonName
req.AltNames = anchor.AltNames

dest, err := ToDest(anchor.Dest, anchor.DestOptions)
if err != nil {
return nil, errors.Wrap(err, "making dest for anchor")
}
action, err := ToAction(anchor.Action)
if err != nil {
return nil, errors.Wrap(err, "making action for anchor")
}

members = append(members, conductor.NewMember(anchor.Name, aprovider,
req, conductor.DefaultLeaseHandle(dest, action)))
}
return members, nil
}
10 changes: 0 additions & 10 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@ import (
"github.com/pkg/errors"
)

type Anchor struct {
Action Action `json:"action"`
AltNames []string `json:"altNames"`
CommonName string `json:"cn"`
Dest string `json:"dest"`
DestOptions json.RawMessage `json:"destOpts"`
Name string `json:"name"`
Provider string `json:"provider"`
}

type Config struct {
Api Api `json:"api"`
Providers []Provider `json:"providers"`
Expand Down
40 changes: 40 additions & 0 deletions cmd/config/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@ package config

import (
"io/ioutil"
"os"
"path/filepath"

"github.com/pkg/errors"
)

func FromFiles(files ...string) (*Config, error) {
conf := DefaultConfig()
for _, file := range files {
finfo, err := os.Stat(file)
if err != nil {
return nil, errors.Wrap(err, "geting config file info")
}

if finfo.Mode().IsDir() {
conf, err = FromDirectory(conf, file)
if err != nil {
return nil, err
}
continue
}

raw, err := ioutil.ReadFile(file)
if err != nil {
return nil, errors.Wrap(err, "reading config file")
Expand All @@ -22,3 +37,28 @@ func FromFiles(files ...string) (*Config, error) {
}
return conf, nil
}

func FromDirectory(conf *Config, dir string) (*Config, error) {
files, err := ioutil.ReadDir(dir)
if err != nil {
return conf, errors.Wrap(err, "reading config files from dir")
}

for _, f := range files {
if f.IsDir() || filepath.Ext(f.Name()) != ".json" {
continue
}

raw, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
if err != nil {
return conf, errors.Wrap(err, "reading config file")
}
c, err := New(raw)
if err != nil {
return conf, errors.Wrap(err, "parsing config file")
}
conf = mergeConfigs(conf, c)
}

return conf, nil
}
20 changes: 20 additions & 0 deletions cmd/config/provider_config_wrap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package config

import (
"encoding/json"

"github.com/tlmiller/disttrust/provider"
)

type ProviderConfigWrap struct {
config json.RawMessage
p provider.Provider
}

func (p *ProviderConfigWrap) Issue(r *provider.Request) (provider.Lease, error) {
return p.p.Issue(r)
}

func (p *ProviderConfigWrap) Renew(l provider.Lease) (provider.Lease, error) {
return p.p.Renew(l)
}
64 changes: 63 additions & 1 deletion cmd/config/provider_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package config
import (
"encoding/json"
"fmt"
"reflect"

"github.com/pkg/errors"

"github.com/tlmiller/disttrust/provider"
)
Expand All @@ -27,5 +30,64 @@ func ToProvider(id string, opts json.RawMessage) (provider.Provider, error) {
return nil, fmt.Errorf("provider mapper does not exists for id '%s'", id)
}

return mapper(opts)
p, err := mapper(opts)
return &ProviderConfigWrap{
config: opts,
p: p,
}, err
}

func ToProviderOnUpdate(id string, opts json.RawMessage, ex provider.Provider) (provider.Provider, error) {
if cpwrap, ok := ex.(*ProviderConfigWrap); ok {
var j1, j2 interface{}
if err := json.Unmarshal(opts, &j1); err != nil {
return nil, err
}
if err := json.Unmarshal(cpwrap.config, &j2); err != nil {
return nil, err
}
if reflect.DeepEqual(j1, j2) {
return ex, nil
}
}

mapper, exists := providerMappings[provider.Id(id)]
if exists == false {
return nil, fmt.Errorf("provider mapper does not exists for id '%s'", id)
}

p, err := mapper(opts)
return &ProviderConfigWrap{
config: opts,
p: p,
}, err
}

func ToProviderStore(cnfProviders []Provider, store *provider.Store) (*provider.Store, error) {
nstore := provider.NewStore()
for _, cnfProvider := range cnfProviders {
if len(cnfProvider.Name) == 0 {
return nstore, errors.New("undefined provider name")
}

var err error
var genProvider provider.Provider
if p, exists := store.Fetch(cnfProvider.Name); exists {
genProvider, err = ToProviderOnUpdate(cnfProvider.Name,
cnfProvider.Options, p)
} else {
genProvider, err = ToProvider(cnfProvider.Id, cnfProvider.Options)
}

if err != nil {
return nstore, errors.Wrapf(err, "config to provider %s", cnfProvider.Name)
}

err = nstore.Store(cnfProvider.Name, genProvider)
if err != nil {
return nstore, errors.Wrap(err, "registering provider")
}
}
return nstore, nil

}
109 changes: 39 additions & 70 deletions cmd/disttrust.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package cmd
import (
"fmt"
"os"

"github.com/pkg/errors"
"os/signal"
"syscall"

log "github.com/sirupsen/logrus"

Expand All @@ -13,12 +13,11 @@ import (
"github.com/tlmiller/disttrust/cmd/config"
"github.com/tlmiller/disttrust/conductor"
"github.com/tlmiller/disttrust/provider"
"github.com/tlmiller/disttrust/server"
_ "github.com/tlmiller/disttrust/server"
)

var (
configFiles []string
manager *conductor.Conductor
)

var disttrustCmd = &cobra.Command{
Expand All @@ -29,25 +28,6 @@ var disttrustCmd = &cobra.Command{
Run: Run,
}

func applyProviders(cnfProviders []config.Provider, store *provider.Store) error {
for _, cnfProvider := range cnfProviders {
if len(cnfProvider.Name) == 0 {
return errors.New("undefined provider name")
}

p, err := config.ToProvider(cnfProvider.Id, cnfProvider.Options)
if err != nil {
return errors.Wrapf(err, "config to provider%s", cnfProvider.Name)
}

err = store.Store(cnfProvider.Name, p)
if err != nil {
return errors.Wrap(err, "registering provider")
}
}
return nil
}

func Execute() {
if err := disttrustCmd.Execute(); err != nil {
fmt.Println(err)
Expand All @@ -56,7 +36,6 @@ func Execute() {
}

func init() {
manager = conductor.NewConductor()
disttrustCmd.Flags().StringSliceVarP(&configFiles, "config", "c",
[]string{}, "Config file(s)")
disttrustCmd.MarkFlagRequired("config")
Expand All @@ -67,61 +46,51 @@ func preRun(cmd *cobra.Command, args []string) {
}

func Run(cmd *cobra.Command, args []string) {
config, err := config.FromFiles(configFiles...)
if err != nil {
log.Fatalf("making config: %v", err)
}

log.Debug("applying providers from config")
err = applyProviders(config.Providers, provider.DefaultStore())
if err != nil {
log.Fatalf("applying providers: %v", err)
}
providers := provider.DefaultStore()

log.Debug("applying anchors from config")
status, err := applyAnchors(config.Anchors, manager, provider.DefaultStore())
if err != nil {
log.Fatalf("applying anchors: %v", err)
}

var apiServ *server.ApiServer
if config.Api.Address != "" {
apiServ = server.NewApiServer(config.Api.Address)
for _, s := range status {
apiServ.AddHealthzChecks(s)
}
go apiServ.Serve()
}

manager.Play().Watch()
}

func applyAnchors(anchors []config.Anchor, con *conductor.Conductor,
store *provider.Store) ([]*conductor.MemberStatus, error) {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGHUP)

status := []*conductor.MemberStatus{}
for _, cnfAnchor := range anchors {
prv, err := store.Fetch(cnfAnchor.Provider)
for {
userConfig, err := config.FromFiles(configFiles...)
if err != nil {
return nil, errors.Wrap(err, "getting anchor provider")
log.Fatalf("making config: %v", err)
}

req := provider.Request{}
req.CommonName = cnfAnchor.CommonName
req.AltNames = cnfAnchor.AltNames

dest, err := config.ToDest(cnfAnchor.Dest, cnfAnchor.DestOptions)
log.Debug("building provider store from config")
providers, err = config.ToProviderStore(userConfig.Providers, providers)
if err != nil {
return nil, errors.Wrap(err, "make dest for anchor")
log.Fatalf("building providers: %v", err)
}
action, err := config.ToAction(cnfAnchor.Action)

log.Debug("building anchors from config")
members, err := config.AnchorsToMembers(userConfig.Anchors, providers.Fetch)
if err != nil {
return nil, errors.Wrap(err, "make action for anchor")
log.Fatalf("building providers: %v", err)
}

memHandle := conductor.DefaultLeaseHandle(dest, action)
member := conductor.NewMember(cnfAnchor.Name, prv, req, memHandle)
status = append(status, con.AddMember(member))
manager := conductor.NewConductor()
_ = manager.AddMembers(members...)

//var apiServ *server.ApiServer
//if userConfig.Api.Address != "" {
// apiServ = server.NewApiServer(userConfig.Api.Address)
// for _, s := range mstatuses {
// apiServ.AddHealthzChecks(s)
// }
// go apiServ.Serve()
//}

manager.Play()

sig := <-sigCh
log.Infof("recieved signal %s", sig)

if sysSig, ok := sig.(syscall.Signal); ok && sysSig == syscall.SIGHUP {
manager.Stop()
log.Info("reloading config")
} else {
break
}
}
return status, nil
}
Loading

0 comments on commit 7132d9a

Please sign in to comment.