Skip to content

Commit

Permalink
Plumb bmc options through from cli to provider:
Browse files Browse the repository at this point in the history
Adds cli flags for all bmc options. The flags are
hidden by default but the cli mechanism we use
also makes them available as env vars.

The dependencies factory is updated with a new func
parameter for provider options that will allow future
modifications without breaking the fn signature.

the cmd/eksctl-anywhere/cmd/flags pkg was renamed to
be singular. It was named similar to the pflags library
but with "a" for anywhere.

The csv reader was modified to take in bmc options so
that the options can be added during a Read.

Signed-off-by: Jacob Weinstock <[email protected]>
  • Loading branch information
jacobweinstock committed Sep 29, 2023
1 parent 02d6225 commit 1a49735
Show file tree
Hide file tree
Showing 29 changed files with 364 additions and 182 deletions.
44 changes: 44 additions & 0 deletions cmd/eksctl-anywhere/cmd/aflag/aflag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Package aflag is the eks anywhere flag handling package.
package aflag

import "github.com/spf13/pflag"

// Flag defines a CLI flag.
type Flag[T any] struct {
Name string
Short string
Usage string
Default T
}

// String applies f to fs and writes the value to dst.
func String(f Flag[string], dst *string, fs *pflag.FlagSet) {
switch {

Check warning on line 16 in cmd/eksctl-anywhere/cmd/aflag/aflag.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/aflag.go#L15-L16

Added lines #L15 - L16 were not covered by tests
// With short form
case f.Short != "":
fs.StringVarP(dst, f.Name, f.Short, f.Default, f.Usage)

Check warning on line 19 in cmd/eksctl-anywhere/cmd/aflag/aflag.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/aflag.go#L18-L19

Added lines #L18 - L19 were not covered by tests
// Without short form
default:
fs.StringVar(dst, f.Name, f.Default, f.Usage)

Check warning on line 22 in cmd/eksctl-anywhere/cmd/aflag/aflag.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/aflag.go#L21-L22

Added lines #L21 - L22 were not covered by tests
}
}

// Bool applies f to fs and writes the value to dst.
func Bool(f Flag[bool], dst *bool, fs *pflag.FlagSet) {
switch {
case f.Short != "":
fs.BoolVarP(dst, f.Name, f.Short, f.Default, f.Usage)
default:
fs.BoolVar(dst, f.Name, f.Default, f.Usage)

Check warning on line 32 in cmd/eksctl-anywhere/cmd/aflag/aflag.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/aflag.go#L27-L32

Added lines #L27 - L32 were not covered by tests
}
}

// StringSlice applies f to fs and writes the value to dst.
func StringSlice(f Flag[[]string], dst *[]string, fs *pflag.FlagSet) {
switch {
case f.Short != "":
fs.StringSliceVarP(dst, f.Name, f.Short, f.Default, f.Usage)
default:
fs.StringSliceVar(dst, f.Name, f.Default, f.Usage)

Check warning on line 42 in cmd/eksctl-anywhere/cmd/aflag/aflag.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/aflag.go#L37-L42

Added lines #L37 - L42 were not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package flags
package aflag

// ClusterConfig is the path to a cluster specification YAML.
var ClusterConfig = Flag[string]{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package flags
package aflag

import (
"github.com/spf13/cobra"
Expand All @@ -13,3 +13,12 @@ func MarkRequired(set *pflag.FlagSet, flags ...string) {
}
}
}

// MarkHidden is a helper to mark flags hidden on cmd. If a flag does not exist, it panics.
func MarkHidden(set *pflag.FlagSet, flags ...string) {
for _, flag := range flags {
if err := set.MarkHidden(flag); err != nil {
panic(err)

Check warning on line 21 in cmd/eksctl-anywhere/cmd/aflag/marker.go

View check run for this annotation

Codecov / codecov/patch

cmd/eksctl-anywhere/cmd/aflag/marker.go#L18-L21

Added lines #L18 - L21 were not covered by tests
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package flags_test
package aflag_test

import (
"testing"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/flags"
"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/aflag"
)

func TestMarkRequired(t *testing.T) {
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestMarkRequired(t *testing.T) {
// so we need to parse the args using the flag set before calling it.
_ = cmd.Flags().Parse(tc.Args)

flags.MarkRequired(cmd.Flags(), required...)
aflag.MarkRequired(cmd.Flags(), required...)

err := cmd.ValidateRequiredFlags()

Expand Down Expand Up @@ -109,7 +109,7 @@ func TestMarkRequired_FlagDoesNotExist(t *testing.T) {
}()

flgs := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.MarkRequired(flgs, "does-not-exist")
aflag.MarkRequired(flgs, "does-not-exist")
}

func nopPflag(name string) pflag.Flag {
Expand Down
68 changes: 68 additions & 0 deletions cmd/eksctl-anywhere/cmd/aflag/tinkerbell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package aflag

// TinkerbellBootstrapIP is used to override the Tinkerbell IP for serving a Tinkerbell stack
// from an admin machine.
var TinkerbellBootstrapIP = Flag[string]{
Name: "tinkerbell-bootstrap-ip",
Usage: "The IP used to expose the Tinkerbell stack from the bootstrap cluster",
}

// TinkerbellBMCConsumerURL is a Rufio RPC provider option.
var TinkerbellBMCConsumerURL = Flag[string]{
Name: "tinkerbell-bmc-consumer-url",
Usage: "The URL used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCHTTPContentType is a Rufio RPC provider option.
var TinkerbellBMCHTTPContentType = Flag[string]{
Name: "tinkerbell-bmc-http-content-type",
Usage: "The HTTP content type used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCHTTPMethod is a Rufio RPC provider option.
var TinkerbellBMCHTTPMethod = Flag[string]{
Name: "tinkerbell-bmc-http-method",
Usage: "The HTTP method used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCTimestampHeader is a Rufio RPC provider option.
var TinkerbellBMCTimestampHeader = Flag[string]{
Name: "tinkerbell-bmc-timestamp-header",
Usage: "The HTTP timestamp header used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCStaticHeaders is a Rufio RPC provider option.
var TinkerbellBMCStaticHeaders = Flag[string]{
Name: "tinkerbell-bmc-static-headers",
Usage: "The HTTP static headers used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCHeaderName is a Rufio RPC provider option.
var TinkerbellBMCHeaderName = Flag[string]{
Name: "tinkerbell-bmc-header-name",
Usage: "The HTTP header name used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCAppendAlgoToHeaderDisabled is a Rufio RPC provider option.
var TinkerbellBMCAppendAlgoToHeaderDisabled = Flag[bool]{
Name: "tinkerbell-bmc-append-algo-to-header-disabled",
Usage: "The HTTP append algo to header disabled used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCIncludedPayloadHeaders is a Rufio RPC provider option.
var TinkerbellBMCIncludedPayloadHeaders = Flag[[]string]{
Name: "tinkerbell-bmc-included-payload-headers",
Usage: "The HTTP included payload headers used to expose the Tinkerbell BMC consumer from the bootstrap cluster. If you specify a Timestamp header, it must be included here.",
}

// TinkerbellBMCPrefixSigDisabled is a Rufio RPC provider option.
var TinkerbellBMCPrefixSigDisabled = Flag[bool]{
Name: "tinkerbell-bmc-prefix-sig-disabled",
Usage: "The HTTP prefix sig disabled used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}

// TinkerbellBMCWebhookSecrets is a Rufio RPC provider option.
var TinkerbellBMCWebhookSecrets = Flag[[]string]{
Name: "tinkerbell-bmc-webhook-secrets",
Usage: "The webhook secrets used to expose the Tinkerbell BMC consumer from the bootstrap cluster",
}
44 changes: 39 additions & 5 deletions cmd/eksctl-anywhere/cmd/createcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import (
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"

"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/flags"
"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/aflag"
"github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/awsiamauth"
"github.com/aws/eks-anywhere/pkg/clustermanager"
Expand All @@ -16,6 +17,7 @@ import (
"github.com/aws/eks-anywhere/pkg/features"
"github.com/aws/eks-anywhere/pkg/kubeconfig"
"github.com/aws/eks-anywhere/pkg/logger"
"github.com/aws/eks-anywhere/pkg/providers/tinkerbell/hardware"
"github.com/aws/eks-anywhere/pkg/types"
"github.com/aws/eks-anywhere/pkg/validations"
"github.com/aws/eks-anywhere/pkg/validations/createvalidations"
Expand All @@ -32,9 +34,18 @@ type createClusterOptions struct {
tinkerbellBootstrapIP string
installPackages string
skipValidations []string
providerOptions *dependencies.ProviderOptions
}

var cc = &createClusterOptions{}
var cc = &createClusterOptions{
providerOptions: &dependencies.ProviderOptions{
Tinkerbell: &dependencies.TinkerbellOptions{
BMCOptions: &hardware.BMCOptions{
RPC: &hardware.RPCOpts{},
},
},
},
}

var createClusterCmd = &cobra.Command{
Use: "cluster -f <cluster-config-file> [flags]",
Expand All @@ -50,14 +61,37 @@ func init() {
applyClusterOptionFlags(createClusterCmd.Flags(), &cc.clusterOptions)
applyTimeoutFlags(createClusterCmd.Flags(), &cc.timeoutOptions)
applyTinkerbellHardwareFlag(createClusterCmd.Flags(), &cc.hardwareCSVPath)
flags.String(flags.TinkerbellBootstrapIP, &cc.tinkerbellBootstrapIP, createClusterCmd.Flags())
aflag.String(aflag.TinkerbellBootstrapIP, &cc.tinkerbellBootstrapIP, createClusterCmd.Flags())
createClusterCmd.Flags().BoolVar(&cc.forceClean, "force-cleanup", false, "Force deletion of previously created bootstrap cluster")
hideForceCleanup(createClusterCmd.Flags())
createClusterCmd.Flags().BoolVar(&cc.skipIpCheck, "skip-ip-check", false, "Skip check for whether cluster control plane ip is in use")
createClusterCmd.Flags().StringVar(&cc.installPackages, "install-packages", "", "Location of curated packages configuration files to install to the cluster")
createClusterCmd.Flags().StringArrayVar(&cc.skipValidations, "skip-validations", []string{}, fmt.Sprintf("Bypass create validations by name. Valid arguments you can pass are --skip-validations=%s", strings.Join(createvalidations.SkippableValidations[:], ",")))
tinkerbellFlags(createClusterCmd.Flags(), cc.providerOptions.Tinkerbell.BMCOptions.RPC)

aflag.MarkRequired(createClusterCmd.Flags(), aflag.ClusterConfig.Name)
}

flags.MarkRequired(createClusterCmd.Flags(), flags.ClusterConfig.Name)
func tinkerbellFlags(fs *pflag.FlagSet, r *hardware.RPCOpts) {
aflag.String(aflag.TinkerbellBMCConsumerURL, &r.ConsumerURL, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCConsumerURL.Name)
aflag.String(aflag.TinkerbellBMCHTTPContentType, &r.Request.HTTPContentType, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCHTTPContentType.Name)
aflag.String(aflag.TinkerbellBMCHTTPMethod, &r.Request.HTTPMethod, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCHTTPMethod.Name)
aflag.String(aflag.TinkerbellBMCTimestampHeader, &r.Request.TimestampHeader, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCTimestampHeader.Name)
// add static headers here
aflag.String(aflag.TinkerbellBMCHeaderName, &r.Signature.HeaderName, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCHeaderName.Name)
aflag.Bool(aflag.TinkerbellBMCAppendAlgoToHeaderDisabled, &r.Signature.AppendAlgoToHeaderDisabled, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCAppendAlgoToHeaderDisabled.Name)
aflag.StringSlice(aflag.TinkerbellBMCIncludedPayloadHeaders, &r.Signature.IncludedPayloadHeaders, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCIncludedPayloadHeaders.Name)
aflag.Bool(aflag.TinkerbellBMCPrefixSigDisabled, &r.HMAC.PrefixSigDisabled, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCPrefixSigDisabled.Name)
aflag.StringSlice(aflag.TinkerbellBMCWebhookSecrets, &r.HMAC.Secrets, fs)
aflag.MarkHidden(fs, aflag.TinkerbellBMCWebhookSecrets.Name)
}

func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) error {
Expand Down Expand Up @@ -141,7 +175,7 @@ func (cc *createClusterOptions) createCluster(cmd *cobra.Command, _ []string) er
WithBootstrapper().
WithCliConfig(cliConfig).
WithClusterManager(clusterSpec.Cluster, clusterManagerTimeoutOpts).
WithProvider(cc.fileName, clusterSpec.Cluster, cc.skipIpCheck, cc.hardwareCSVPath, cc.forceClean, cc.tinkerbellBootstrapIP, skippedValidations).
WithProvider(cc.fileName, clusterSpec.Cluster, cc.skipIpCheck, cc.hardwareCSVPath, cc.forceClean, cc.tinkerbellBootstrapIP, skippedValidations, cc.providerOptions).
WithGitOpsFlux(clusterSpec.Cluster, clusterSpec.FluxConfig, cliConfig).
WithWriter().
WithEksdInstaller().
Expand Down
15 changes: 13 additions & 2 deletions cmd/eksctl-anywhere/cmd/deletecluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws/eks-anywhere/pkg/dependencies"
"github.com/aws/eks-anywhere/pkg/kubeconfig"
"github.com/aws/eks-anywhere/pkg/logger"
"github.com/aws/eks-anywhere/pkg/providers/tinkerbell/hardware"
"github.com/aws/eks-anywhere/pkg/types"
"github.com/aws/eks-anywhere/pkg/validations"
"github.com/aws/eks-anywhere/pkg/workflows"
Expand All @@ -21,9 +22,18 @@ type deleteClusterOptions struct {
forceCleanup bool
hardwareFileName string
tinkerbellBootstrapIP string
providerOptions *dependencies.ProviderOptions
}

var dc = &deleteClusterOptions{}
var dc = &deleteClusterOptions{
providerOptions: &dependencies.ProviderOptions{
Tinkerbell: &dependencies.TinkerbellOptions{
BMCOptions: &hardware.BMCOptions{
RPC: &hardware.RPCOpts{},
},
},
},
}

var deleteClusterCmd = &cobra.Command{
Use: "cluster (<cluster-name>|-f <config-file>)",
Expand All @@ -50,6 +60,7 @@ func init() {
hideForceCleanup(deleteClusterCmd.Flags())
deleteClusterCmd.Flags().StringVar(&dc.managementKubeconfig, "kubeconfig", "", "kubeconfig file pointing to a management cluster")
deleteClusterCmd.Flags().StringVar(&dc.bundlesOverride, "bundles-override", "", "Override default Bundles manifest (not recommended)")
tinkerbellFlags(deleteClusterCmd.Flags(), dc.providerOptions.Tinkerbell.BMCOptions.RPC)
}

func (dc *deleteClusterOptions) validate(ctx context.Context, args []string) error {
Expand Down Expand Up @@ -101,7 +112,7 @@ func (dc *deleteClusterOptions) deleteCluster(ctx context.Context) error {
WithBootstrapper().
WithCliConfig(cliConfig).
WithClusterManager(clusterSpec.Cluster, nil).
WithProvider(dc.fileName, clusterSpec.Cluster, cc.skipIpCheck, dc.hardwareFileName, false, dc.tinkerbellBootstrapIP, map[string]bool{}).
WithProvider(dc.fileName, clusterSpec.Cluster, cc.skipIpCheck, dc.hardwareFileName, false, dc.tinkerbellBootstrapIP, map[string]bool{}, dc.providerOptions).
WithGitOpsFlux(clusterSpec.Cluster, clusterSpec.FluxConfig, cliConfig).
WithWriter().
Build(ctx)
Expand Down
6 changes: 3 additions & 3 deletions cmd/eksctl-anywhere/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/flags"
"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/aflag"
"github.com/aws/eks-anywhere/pkg/validations"
)

Expand Down Expand Up @@ -47,8 +47,8 @@ func bindFlagsToViper(cmd *cobra.Command, args []string) error {
}

func applyClusterOptionFlags(flagSet *pflag.FlagSet, clusterOpt *clusterOptions) {
flags.String(flags.ClusterConfig, &clusterOpt.fileName, flagSet)
flags.String(flags.BundleOverride, &clusterOpt.bundlesOverride, flagSet)
aflag.String(aflag.ClusterConfig, &clusterOpt.fileName, flagSet)
aflag.String(aflag.BundleOverride, &clusterOpt.bundlesOverride, flagSet)
flagSet.StringVar(&clusterOpt.managementKubeconfig, "kubeconfig", "", "Management cluster kubeconfig file")
}

Expand Down
23 changes: 0 additions & 23 deletions cmd/eksctl-anywhere/cmd/flags/flag.go

This file was deleted.

8 changes: 0 additions & 8 deletions cmd/eksctl-anywhere/cmd/flags/tinkerbell.go

This file was deleted.

10 changes: 5 additions & 5 deletions cmd/eksctl-anywhere/cmd/generate_tinkerbell_template_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/flags"
"github.com/aws/eks-anywhere/cmd/eksctl-anywhere/cmd/aflag"
"github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/logger"
"github.com/aws/eks-anywhere/pkg/networkutils"
Expand Down Expand Up @@ -42,9 +42,9 @@ func NewGenerateTinkerbellTemplateConfig() *cobra.Command {
// Configure the flagset. Some of these flags are duplicated from other parts of the cmd code
// for consistency but their descriptions may vary because of the commands use-case.
flgs := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.String(flags.ClusterConfig, &opts.fileName, flgs)
flags.String(flags.BundleOverride, &opts.bundlesOverride, flgs)
flags.String(flags.TinkerbellBootstrapIP, &opts.BootstrapTinkerbellIP, flgs)
aflag.String(aflag.ClusterConfig, &opts.fileName, flgs)
aflag.String(aflag.BundleOverride, &opts.bundlesOverride, flgs)
aflag.String(aflag.TinkerbellBootstrapIP, &opts.BootstrapTinkerbellIP, flgs)

cmd := &cobra.Command{
Use: "tinkerbelltemplateconfig",
Expand All @@ -54,7 +54,7 @@ func NewGenerateTinkerbellTemplateConfig() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
// When the bootstrap IP is unspecified attempt to derive it from IPs assigned to the
// primary interface.
if f := flgs.Lookup(flags.TinkerbellBootstrapIP.Name); !f.Changed {
if f := flgs.Lookup(aflag.TinkerbellBootstrapIP.Name); !f.Changed {
bootstrapIP, err := networkutils.GetLocalIP()
if err != nil {
return fmt.Errorf("tinkerbell bootstrap ip: %v", err)
Expand Down
Loading

0 comments on commit 1a49735

Please sign in to comment.