Skip to content

Commit e7bec88

Browse files
authored
refactor: reorganize into modules and rework server config path (#43)
1 parent 4bf1089 commit e7bec88

16 files changed

+213
-185
lines changed

cmd/access-controller/main.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"os/signal"
1212
"runtime"
13+
"strings"
1314
"syscall"
1415
"time"
1516

@@ -25,6 +26,7 @@ import (
2526
aclpb "github.com/authorizer-tech/access-controller/genprotos/authorizer/accesscontroller/v1alpha1"
2627
ac "github.com/authorizer-tech/access-controller/internal"
2728
"github.com/authorizer-tech/access-controller/internal/datastores"
29+
"github.com/authorizer-tech/access-controller/internal/healthchecker"
2830
"github.com/authorizer-tech/access-controller/internal/namespace-manager/postgres"
2931
log "github.com/sirupsen/logrus"
3032
"google.golang.org/grpc"
@@ -44,7 +46,6 @@ var advertise = flag.String("advertise", "", "The address that this node adverti
4446
var grpcPort = flag.Int("grpc-port", 50052, "The bind port for the grpc server")
4547
var httpPort = flag.Int("http-port", 8082, "The bind port for the grpc-gateway http server")
4648
var join = flag.String("join", "", "A comma-separated list of 'host:port' addresses for nodes in the cluster to join to")
47-
var configPath = flag.String("config", "./localconfig/config.yaml", "The path to the server config")
4849
var migrations = flag.String("migrations", "./db/migrations", "The absolute path to the database migrations directory")
4950

5051
type config struct {
@@ -63,10 +64,17 @@ func main() {
6364

6465
flag.Parse()
6566

66-
viper.SetConfigFile(*configPath)
67+
configPaths := []string{"/etc/authorizer/access-controller", "$HOME/.authorizer/access-controller", "."}
68+
for _, path := range configPaths {
69+
viper.AddConfigPath(path)
70+
}
6771
viper.AutomaticEnv()
6872

6973
if err := viper.ReadInConfig(); err != nil {
74+
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
75+
log.Fatalf("server config not found in paths [%s]", strings.Join(configPaths, ","))
76+
}
77+
7078
log.Fatalf("Failed to load server config file: %v", err)
7179
}
7280

@@ -173,7 +181,7 @@ func main() {
173181
log.Fatalf("Failed to initialize the access-controller: %v", err)
174182
}
175183

176-
healthChecker := ac.NewHealthChecker(controller.HealthCheck)
184+
healthChecker := healthchecker.NewHealthChecker(controller.HealthCheck)
177185

178186
addr := fmt.Sprintf(":%d", *grpcPort)
179187
listener, err := net.Listen("tcp", addr)

docker/docker-compose.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ services:
55
ports:
66
- "50052:50052"
77
- "8082:8082"
8-
command: access-controller -config /etc/config/config.yaml
8+
command: access-controller
99
volumes:
10-
- "${PWD}/docker:/etc/config"
10+
- "${PWD}/docker:/etc/authorizer/access-controller"
1111
depends_on:
1212
- cockroachdb
1313

@@ -16,9 +16,9 @@ services:
1616
ports:
1717
- "50053:50053"
1818
- "8083:8083"
19-
command: access-controller -config /etc/config/config.yaml -grpc-port 50053 -http-port 8083 -node-port 7947 -join access-controller0:7946
19+
command: access-controller -grpc-port 50053 -http-port 8083 -node-port 7947 -join access-controller0:7946
2020
volumes:
21-
- "${PWD}/docker:/etc/config"
21+
- "${PWD}/docker:/etc/authorizer/access-controller"
2222
depends_on:
2323
- access-controller0
2424

@@ -27,9 +27,9 @@ services:
2727
ports:
2828
- "50054:50054"
2929
- "8084:8084"
30-
command: access-controller -config /etc/config/config.yaml -grpc-port 50054 -http-port 8084 -node-port 7948 -join access-controller0:7946,access-controller1:7947
30+
command: access-controller -grpc-port 50054 -http-port 8084 -node-port 7948 -join access-controller0:7946,access-controller1:7947
3131
volumes:
32-
- "${PWD}/docker:/etc/config"
32+
- "${PWD}/docker:/etc/authorizer/access-controller"
3333
depends_on:
3434
- access-controller1
3535

internal/access-controller.go

+45-47
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"github.com/pkg/errors"
1515

1616
aclpb "github.com/authorizer-tech/access-controller/genprotos/authorizer/accesscontroller/v1alpha1"
17+
"github.com/authorizer-tech/access-controller/internal/hashring"
18+
namespacemgr "github.com/authorizer-tech/access-controller/internal/namespace-manager"
1719
log "github.com/sirupsen/logrus"
1820
"google.golang.org/grpc"
1921
"google.golang.org/grpc/codes"
@@ -36,11 +38,11 @@ type AccessController struct {
3638

3739
Memberlist *memberlist.Memberlist
3840
RPCRouter ClientRouter
39-
Hashring Hashring
41+
Hashring hashring.Hashring
4042

4143
RelationTupleStore
42-
PeerNamespaceConfigStore
43-
NamespaceManager
44+
namespacemgr.PeerNamespaceConfigStore
45+
namespacemgr.NamespaceManager
4446
NodeConfigs
4547

4648
shutdown chan struct{}
@@ -56,7 +58,7 @@ func WithStore(store RelationTupleStore) AccessControllerOption {
5658
}
5759

5860
// WithNamespaceManager sets the AccessController's NamespaceManager.
59-
func WithNamespaceManager(m NamespaceManager) AccessControllerOption {
61+
func WithNamespaceManager(m namespacemgr.NamespaceManager) AccessControllerOption {
6062
return func(ac *AccessController) {
6163
ac.NamespaceManager = m
6264
}
@@ -80,7 +82,7 @@ func (a *AccessController) watchNamespaceConfigs(ctx context.Context) {
8082
go func() {
8183
for {
8284

83-
var iter ChangelogIterator
85+
var iter namespacemgr.ChangelogIterator
8486
var err error
8587

8688
err = backoff.Retry(func() error {
@@ -115,7 +117,7 @@ func (a *AccessController) watchNamespaceConfigs(ctx context.Context) {
115117
timestamp := change.Timestamp
116118

117119
switch change.Operation {
118-
case AddNamespace, UpdateNamespace:
120+
case namespacemgr.AddNamespace, namespacemgr.UpdateNamespace:
119121
err := a.PeerNamespaceConfigStore.SetNamespaceConfigSnapshot(a.ServerID, namespace, config, timestamp)
120122
if err != nil {
121123
log.Errorf("Failed to set the namespace config snapshot for this node: %v", err)
@@ -137,7 +139,7 @@ func (a *AccessController) watchNamespaceConfigs(ctx context.Context) {
137139

138140
// chooseNamespaceConfigSnapshot selects the most recent namespace config snapshot that is
139141
// common to all peers/nodes within the cluster that this node is a part of.
140-
func (a *AccessController) chooseNamespaceConfigSnapshot(namespace string) (*NamespaceConfigSnapshot, error) {
142+
func (a *AccessController) chooseNamespaceConfigSnapshot(namespace string) (*namespacemgr.NamespaceConfigSnapshot, error) {
141143

142144
peerSnapshots, err := a.PeerNamespaceConfigStore.ListNamespaceConfigSnapshots(namespace)
143145
if err != nil {
@@ -180,10 +182,10 @@ func (a *AccessController) chooseNamespaceConfigSnapshot(namespace string) (*Nam
180182
}
181183

182184
if len(commonTimestamps) < 1 {
183-
return nil, ErrNoLocalNamespacesDefined
185+
return nil, namespacemgr.ErrNoLocalNamespacesDefined
184186
}
185187
} else {
186-
return nil, ErrNoLocalNamespacesDefined
188+
return nil, namespacemgr.ErrNoLocalNamespacesDefined
187189
}
188190

189191
var selectedTS time.Time
@@ -195,7 +197,7 @@ func (a *AccessController) chooseNamespaceConfigSnapshot(namespace string) (*Nam
195197

196198
config := peerSnapshots[peerWithMin][selectedTS]
197199

198-
snapshot := &NamespaceConfigSnapshot{
200+
snapshot := &namespacemgr.NamespaceConfigSnapshot{
199201
Config: config,
200202
Timestamp: selectedTS,
201203
}
@@ -206,14 +208,10 @@ func (a *AccessController) chooseNamespaceConfigSnapshot(namespace string) (*Nam
206208
// NewAccessController constructs a new AccessController with the options provided.
207209
func NewAccessController(opts ...AccessControllerOption) (*AccessController, error) {
208210

209-
peerConfigs := &inmemPeerNamespaceConfigStore{
210-
configs: make(map[string]map[string]map[time.Time]*aclpb.NamespaceConfig),
211-
}
212-
213211
ac := AccessController{
214212
RPCRouter: NewMapClientRouter(),
215-
Hashring: NewConsistentHashring(nil),
216-
PeerNamespaceConfigStore: peerConfigs,
213+
Hashring: hashring.NewConsistentHashring(nil),
214+
PeerNamespaceConfigStore: namespacemgr.NewInMemoryPeerNamespaceConfigStore(),
217215
shutdown: make(chan struct{}),
218216
}
219217

@@ -234,8 +232,8 @@ func NewAccessController(opts ...AccessControllerOption) (*AccessController, err
234232
}
235233

236234
switch entry.Operation {
237-
case AddNamespace, UpdateNamespace:
238-
err = peerConfigs.SetNamespaceConfigSnapshot(ac.ServerID, entry.Namespace, entry.Config, entry.Timestamp)
235+
case namespacemgr.AddNamespace, namespacemgr.UpdateNamespace:
236+
err = ac.SetNamespaceConfigSnapshot(ac.ServerID, entry.Namespace, entry.Config, entry.Timestamp)
239237
if err != nil {
240238
return nil, err
241239
}
@@ -461,7 +459,7 @@ func (a *AccessController) checkRewrite(ctx context.Context, rule *aclpb.Rewrite
461459

462460
func (a *AccessController) check(ctx context.Context, namespace, object, relation, subject string) (bool, error) {
463461

464-
if peerChecksum, ok := ChecksumFromContext(ctx); ok {
462+
if peerChecksum, ok := hashring.ChecksumFromContext(ctx); ok {
465463
// The hash ring checksum of the peer should always be present if the
466464
// request is proxied from another access-controller. If the request
467465
// is made externally it won't be present.
@@ -476,14 +474,14 @@ func (a *AccessController) check(ctx context.Context, namespace, object, relatio
476474
// The namespace config timestamp from the peer should always be present if
477475
// the request is proxied from another access-controller. If the request is
478476
// made externally, we select a namespace config timestamp and forward it on.
479-
peerNamespaceCfgTs, ok := NamespaceConfigTimestampFromContext(ctx, namespace)
477+
peerNamespaceCfgTs, ok := namespacemgr.NamespaceConfigTimestampFromContext(ctx, namespace)
480478
if !ok {
481479
snapshot, err := a.chooseNamespaceConfigSnapshot(namespace)
482480
if err != nil {
483-
if err == ErrNoLocalNamespacesDefined {
484-
return false, NamespaceConfigError{
481+
if err == namespacemgr.ErrNoLocalNamespacesDefined {
482+
return false, namespacemgr.NamespaceConfigError{
485483
Message: fmt.Sprintf("'%s' namespace is undefined. If you recently added it, it may take a couple minutes to propagate", namespace),
486-
Type: NamespaceDoesntExist,
484+
Type: namespacemgr.NamespaceDoesntExist,
487485
}.ToStatus().Err()
488486
}
489487

@@ -492,7 +490,7 @@ func (a *AccessController) check(ctx context.Context, namespace, object, relatio
492490

493491
snapshotTimestamp = snapshot.Timestamp
494492

495-
ctx = NewContextWithNamespaceConfigTimestamp(ctx, namespace, snapshotTimestamp)
493+
ctx = namespacemgr.NewContextWithNamespaceConfigTimestamp(ctx, namespace, snapshotTimestamp)
496494
} else {
497495
snapshotTimestamp = peerNamespaceCfgTs
498496
}
@@ -503,9 +501,9 @@ func (a *AccessController) check(ctx context.Context, namespace, object, relatio
503501
}
504502

505503
if cfg == nil {
506-
return false, NamespaceConfigError{
504+
return false, namespacemgr.NamespaceConfigError{
507505
Message: fmt.Sprintf("'%s' namespace is undefined. If you recently added it, it may take a couple minutes to propagate", namespace),
508-
Type: NamespaceDoesntExist,
506+
Type: namespacemgr.NamespaceDoesntExist,
509507
}.ToStatus().Err()
510508
}
511509

@@ -531,7 +529,7 @@ func (a *AccessController) check(ctx context.Context, namespace, object, relatio
531529
panic("unexpected rpc client type encountered")
532530
}
533531

534-
ctx = NewContextWithChecksum(ctx, a.Hashring.Checksum())
532+
ctx = hashring.NewContextWithChecksum(ctx, a.Hashring.Checksum())
535533

536534
subject := SubjectID{ID: subject}
537535

@@ -709,10 +707,10 @@ func (a *AccessController) expand(ctx context.Context, namespace, object, relati
709707

710708
configSnapshot, err := a.chooseNamespaceConfigSnapshot(namespace)
711709
if err != nil {
712-
if err == ErrNoLocalNamespacesDefined {
713-
return nil, NamespaceConfigError{
710+
if err == namespacemgr.ErrNoLocalNamespacesDefined {
711+
return nil, namespacemgr.NamespaceConfigError{
714712
Message: fmt.Sprintf("'%s' namespace is undefined. If you recently added it, it may take a couple minutes to propagate", namespace),
715-
Type: NamespaceDoesntExist,
713+
Type: namespacemgr.NamespaceDoesntExist,
716714
}.ToStatus().Err()
717715
}
718716

@@ -732,7 +730,7 @@ func (a *AccessController) expand(ctx context.Context, namespace, object, relati
732730
return nil, nil
733731
}
734732

735-
ctx = NewContextWithNamespaceConfigTimestamp(ctx, namespace, configSnapshot.Timestamp)
733+
ctx = namespacemgr.NewContextWithNamespaceConfigTimestamp(ctx, namespace, configSnapshot.Timestamp)
736734

737735
return a.expandWithRewrite(ctx, rewrite, tree, namespace, object, relation, depth)
738736
}
@@ -804,9 +802,9 @@ func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclp
804802

805803
configSnapshot, err := a.chooseNamespaceConfigSnapshot(namespace)
806804
if err != nil {
807-
return nil, NamespaceConfigError{
805+
return nil, namespacemgr.NamespaceConfigError{
808806
Message: fmt.Sprintf("'%s' namespace is undefined. If you recently added it, it may take a couple minutes to propagate", namespace),
809-
Type: NamespaceDoesntExist,
807+
Type: namespacemgr.NamespaceDoesntExist,
810808
}.ToStatus().Err()
811809
}
812810

@@ -822,9 +820,9 @@ func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclp
822820

823821
rewrite := rewriteFromNamespaceConfig(relation, configSnapshot.Config)
824822
if rewrite == nil {
825-
return nil, NamespaceConfigError{
823+
return nil, namespacemgr.NamespaceConfigError{
826824
Message: fmt.Sprintf("'%s' relation is undefined in namespace '%s' at snapshot config timestamp '%s'. If this relation was recently added, please try again in a couple minutes", relation, namespace, configSnapshot.Timestamp),
827-
Type: NamespaceRelationUndefined,
825+
Type: namespacemgr.NamespaceRelationUndefined,
828826
}.ToStatus().Err()
829827
}
830828

@@ -835,10 +833,10 @@ func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclp
835833

836834
configSnapshot, err := a.chooseNamespaceConfigSnapshot(n)
837835
if err != nil {
838-
if err == ErrNoLocalNamespacesDefined {
839-
return nil, NamespaceConfigError{
836+
if err == namespacemgr.ErrNoLocalNamespacesDefined {
837+
return nil, namespacemgr.NamespaceConfigError{
840838
Message: fmt.Sprintf("SubjectSet '%s' references the '%s' namespace which is undefined. If this namespace was recently added, please try again in a couple minutes", subject.String(), n),
841-
Type: NamespaceDoesntExist,
839+
Type: namespacemgr.NamespaceDoesntExist,
842840
}.ToStatus().Err()
843841
}
844842

@@ -848,9 +846,9 @@ func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclp
848846
if r != "..." {
849847
rewrite := rewriteFromNamespaceConfig(r, configSnapshot.Config)
850848
if rewrite == nil {
851-
return nil, NamespaceConfigError{
849+
return nil, namespacemgr.NamespaceConfigError{
852850
Message: fmt.Sprintf("SubjectSet '%s' references relation '%s' which is undefined in the namespace '%s' at snapshot config timestamp '%s'. If this relation was recently added to the config, please try again in a couple minutes", subject.String(), r, n, configSnapshot.Timestamp),
853-
Type: NamespaceRelationUndefined,
851+
Type: namespacemgr.NamespaceRelationUndefined,
854852
}.ToStatus().Err()
855853
}
856854
}
@@ -892,9 +890,9 @@ func (a *AccessController) ListRelationTuples(ctx context.Context, req *aclpb.Li
892890

893891
_, err := a.chooseNamespaceConfigSnapshot(namespace)
894892
if err != nil {
895-
return nil, NamespaceConfigError{
893+
return nil, namespacemgr.NamespaceConfigError{
896894
Message: fmt.Sprintf("'%s' namespace is undefined. If you recently added it, it may take a couple minutes to propagate", namespace),
897-
Type: NamespaceDoesntExist,
895+
Type: namespacemgr.NamespaceDoesntExist,
898896
}.ToStatus().Err()
899897
}
900898

@@ -990,7 +988,7 @@ func (a *AccessController) WriteConfig(ctx context.Context, req *aclpb.WriteConf
990988
err := a.NamespaceManager.WrapTransaction(ctx, func(txnCtx context.Context) error {
991989
currentConfig, err := a.NamespaceManager.GetConfig(txnCtx, namespace)
992990
if err != nil {
993-
if err == ErrNamespaceDoesntExist {
991+
if err == namespacemgr.ErrNamespaceDoesntExist {
994992
return a.NamespaceManager.UpsertConfig(txnCtx, config)
995993
}
996994

@@ -1022,17 +1020,17 @@ func (a *AccessController) WriteConfig(ctx context.Context, req *aclpb.WriteConf
10221020
relations = append(relations, relation)
10231021
}
10241022

1025-
return NamespaceConfigError{
1023+
return namespacemgr.NamespaceConfigError{
10261024
Message: fmt.Sprintf("Relation(s) [%v] cannot be removed while one or more relation tuples reference them. Please migrate all relation tuples before removing a relation.", strings.Join(relations, ",")),
1027-
Type: NamespaceUpdateFailedPrecondition,
1025+
Type: namespacemgr.NamespaceUpdateFailedPrecondition,
10281026
}
10291027
}
10301028
}
10311029

10321030
return a.NamespaceManager.UpsertConfig(txnCtx, config)
10331031
})
10341032
if err != nil {
1035-
err, ok := err.(NamespaceConfigError)
1033+
err, ok := err.(namespacemgr.NamespaceConfigError)
10361034
if ok {
10371035
return nil, err.ToStatus().Err()
10381036
}
@@ -1054,7 +1052,7 @@ func (a *AccessController) ReadConfig(ctx context.Context, req *aclpb.ReadConfig
10541052

10551053
config, err := a.NamespaceManager.GetConfig(ctx, namespace)
10561054
if err != nil {
1057-
if errors.Is(err, ErrNamespaceDoesntExist) {
1055+
if errors.Is(err, namespacemgr.ErrNamespaceDoesntExist) {
10581056
return nil, status.Errorf(codes.NotFound, "The namespace '%s' does not exist. If it was recently added, please try again in a couple of minutes", namespace)
10591057
}
10601058
return nil, internalErrorStatus

0 commit comments

Comments
 (0)