Skip to content

Commit

Permalink
impr: preflight checks for HA configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
pandatix committed Jan 25, 2025
1 parent 7ebaac4 commit caa41c8
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
2 changes: 1 addition & 1 deletion deploy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/pulumi/pulumi/pkg/v3 v3.145.0
github.com/pulumi/pulumi/sdk/v3 v3.145.0
github.com/stretchr/testify v1.10.0
go.uber.org/multierr v1.11.0
google.golang.org/grpc v1.69.4
google.golang.org/protobuf v1.36.2
)
Expand Down Expand Up @@ -187,7 +188,6 @@ require (
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
gocloud.dev v0.37.0 // indirect
gocloud.dev/secrets/hashivault v0.37.0 // indirect
Expand Down
43 changes: 38 additions & 5 deletions deploy/services/chall-manager.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package services

import (
"errors"
"strings"
"sync"

netwv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/networking/v1"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"go.uber.org/multierr"

"github.com/ctfer-io/chall-manager/deploy/common"
"github.com/ctfer-io/chall-manager/deploy/services/parts"
Expand Down Expand Up @@ -68,7 +71,12 @@ const (
// It is not made to be exposed to outer world (outside of the cluster).
func NewChallManager(ctx *pulumi.Context, name string, args *ChallManagerArgs, opts ...pulumi.ResourceOption) (*ChallManager, error) {
cm := &ChallManager{}
args = cm.defaults(ctx, args)

args = cm.defaults(args)
if err := cm.check(args); err != nil {
return nil, err
}

if err := ctx.RegisterComponentResource("ctfer-io:chall-manager", name, cm, opts...); err != nil {
return nil, err
}
Expand All @@ -81,7 +89,7 @@ func NewChallManager(ctx *pulumi.Context, name string, args *ChallManagerArgs, o
return cm, nil
}

func (cm *ChallManager) defaults(ctx *pulumi.Context, args *ChallManagerArgs) *ChallManagerArgs {
func (cm *ChallManager) defaults(args *ChallManagerArgs) *ChallManagerArgs {
if args == nil {
args = &ChallManagerArgs{}
}
Expand Down Expand Up @@ -110,26 +118,47 @@ func (cm *ChallManager) defaults(ctx *pulumi.Context, args *ChallManagerArgs) *C
}).(pulumi.StringOutput)
}

if args.Replicas == nil || args.PrivateRegistry.ToStringPtrOutput().OutputState == nil {
if args.Replicas == nil || args.Replicas.ToIntPtrOutput().OutputState == nil {
args.replicas = pulumi.Int(1).ToIntOutput()
} else {
args.replicas = args.Replicas.ToIntPtrOutput().Elem()
}

return args
}

func (cm *ChallManager) check(args *ChallManagerArgs) error {
wg := &sync.WaitGroup{}
checks := 1 // number of checks to perform
wg.Add(checks)
cerr := make(chan error, checks)

pulumi.All(args.replicas, args.EtcdReplicas).ApplyT(func(all []any) error {
defer wg.Done()

replicas := all[0].(int)
var etcdReplicas *int
if r, ok := all[1].(*int); ok {
etcdReplicas = r
}
if r, ok := all[1].(int); ok {
etcdReplicas = ptr(r)
}

if replicas > 1 && (etcdReplicas == nil || *etcdReplicas < 1) {
ctx.Log.Error("cannot deploy chall-manager replicas (High-Availability) without a distributed lock system (etcd)", &pulumi.LogArgs{})
cerr <- errors.New("cannot deploy chall-manager replicas (High-Availability) without a distributed lock system (etcd)")
}
return nil
})

return args
wg.Wait()
close(cerr)

var merr error
for err := range cerr {
merr = multierr.Append(merr, err)
}
return merr
}

func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, opts ...pulumi.ResourceOption) (err error) {
Expand Down Expand Up @@ -320,3 +349,7 @@ func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, o
func (cm *ChallManager) outputs() {
cm.Endpoint = cm.cm.Endpoint
}

func ptr[T any](t T) *T {
return &t
}
26 changes: 20 additions & 6 deletions deploy/services/chall-manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ctfer-io/chall-manager/deploy/common"
"github.com/ctfer-io/chall-manager/deploy/services"
Expand All @@ -26,7 +27,8 @@ func Test_U_ChallManager(t *testing.T) {
t.Parallel()

var tests = map[string]struct {
Args *services.ChallManagerArgs
Args *services.ChallManagerArgs
ExpectErr bool
}{
"nil-args": {
Args: nil,
Expand Down Expand Up @@ -79,6 +81,13 @@ func Test_U_ChallManager(t *testing.T) {
},
},
},
"replicas-no-etcd": {
Args: &services.ChallManagerArgs{
Replicas: pulumi.IntPtr(2),
EtcdReplicas: nil,
},
ExpectErr: true,
},
"public-dev": {
Args: &services.ChallManagerArgs{
Swagger: true,
Expand All @@ -96,15 +105,20 @@ func Test_U_ChallManager(t *testing.T) {
for testname, tt := range tests {
t.Run(testname, func(t *testing.T) {
assert := assert.New(t)
require := require.New(t)

err := pulumi.RunErr(func(ctx *pulumi.Context) error {
cm, err := services.NewChallManager(ctx, "cm-test", tt.Args)
assert.NoError(err)
if tt.ExpectErr {
require.Error(err)
} else {
require.NoError(err)

cm.Endpoint.ApplyT(func(edp string) error {
assert.NotEmpty(edp)
return nil
})
cm.Endpoint.ApplyT(func(edp string) error {
assert.NotEmpty(edp)
return nil
})
}

return nil
}, pulumi.WithMocks("project", "stack", mocks{}))
Expand Down

0 comments on commit caa41c8

Please sign in to comment.