Skip to content

Commit 7c45a44

Browse files
committed
WIP: allow users to select machine hub mode
Signed-off-by: Ashley Davis <[email protected]>
1 parent 731d789 commit 7c45a44

File tree

2 files changed

+96
-19
lines changed

2 files changed

+96
-19
lines changed

pkg/agent/config.go

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type Config struct {
3939
// https://preflight.jetstack.io in Jetstack Secure OAuth and Jetstack
4040
// Secure API Token modes, and https://api.venafi.cloud in Venafi Cloud Key
4141
// Pair Service Account mode. It is ignored in Venafi Cloud VenafiConnection
42-
// mode.
42+
// mode and in MachineHub mode.
4343
Server string `yaml:"server"`
4444

4545
// OrganizationID is only used in Jetstack Secure OAuth and Jetstack Secure
@@ -62,6 +62,9 @@ type Config struct {
6262
ExcludeAnnotationKeysRegex []string `yaml:"exclude-annotation-keys-regex"`
6363
// Skips label keys that match the given set of regular expressions.
6464
ExcludeLabelKeysRegex []string `yaml:"exclude-label-keys-regex"`
65+
66+
// MachineHub holds config specific to MachineHub mode
67+
MachineHub MachineHubConfig `yaml:"machineHub"`
6568
}
6669

6770
type Endpoint struct {
@@ -89,6 +92,32 @@ type VenafiCloudConfig struct {
8992
UploadPath string `yaml:"upload_path,omitempty"`
9093
}
9194

95+
// MachineHubConfig holds configuration values specific to the CyberArk Machine Hub integration
96+
type MachineHubConfig struct {
97+
// Subdomain is the subdomain indicating where data should be pushed. Used for
98+
// querying the Service Discovery Service to discover the Identity API URL
99+
Subdomain string `yaml:"subdomain"`
100+
101+
// CredentialsSecretName is the name of a Kubernetes Secret in the same namespace as
102+
// the agent, which will be watched for a username and password to send to CyberArk
103+
// Identity for authentication.
104+
CredentialsSecretName string `yaml:"credentialsSecretName"`
105+
}
106+
107+
func (mhc MachineHubConfig) Validate() error {
108+
var errs []error
109+
110+
if mhc.Subdomain == "" {
111+
errs = append(errs, fmt.Errorf("subdomain must not be empty in MachineHub mode"))
112+
}
113+
114+
if mhc.CredentialsSecretName == "" {
115+
errs = append(errs, fmt.Errorf("credentialsSecretName must not be empty in MachineHub mode"))
116+
}
117+
118+
return errors.Join(errs...)
119+
}
120+
92121
type AgentCmdFlags struct {
93122
// ConfigFilePath (--config-file, -c) is the path to the agent configuration
94123
// YAML file.
@@ -103,6 +132,9 @@ type AgentCmdFlags struct {
103132
// --credentials-file.
104133
VenafiCloudMode bool
105134

135+
// MachineHubMode configures the agent to send data to CyberArk Machine Hub
136+
MachineHubMode bool
137+
106138
// ClientID (--client-id) is the clientID in case of Venafi Cloud Key Pair
107139
// Service Account mode.
108140
ClientID string
@@ -305,13 +337,17 @@ func InitAgentCmdFlags(c *cobra.Command, cfg *AgentCmdFlags) {
305337

306338
}
307339

340+
// AuthMode controls how to authenticate to TLSPK / Jetstack Secure. Only one AuthMode
341+
// may be provided if using using those backends.
308342
type AuthMode string
309343

310344
const (
311345
JetstackSecureOAuth AuthMode = "Jetstack Secure OAuth"
312346
JetstackSecureAPIToken AuthMode = "Jetstack Secure API Token"
313347
VenafiCloudKeypair AuthMode = "Venafi Cloud Key Pair Service Account"
314348
VenafiCloudVenafiConnection AuthMode = "Venafi Cloud VenafiConnection"
349+
350+
NoTLSPK AuthMode = "MachineHub only"
315351
)
316352

317353
// The command-line flags and the config file are combined into this struct by
@@ -351,6 +387,11 @@ type CombinedConfig struct {
351387
// Only used for testing purposes.
352388
OutputPath string
353389
InputPath string
390+
391+
// MachineHub-related settings
392+
MachineHubMode bool
393+
394+
MachineHub MachineHubConfig
354395
}
355396

356397
// ValidateAndCombineConfig combines and validates the input configuration with
@@ -366,6 +407,16 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags)
366407
res := CombinedConfig{}
367408
var errs error
368409

410+
if flags.MachineHubMode {
411+
err := cfg.MachineHub.Validate()
412+
if err != nil {
413+
return CombinedConfig{}, nil, fmt.Errorf("invalid MachineHub config provided: %w", err)
414+
}
415+
416+
res.MachineHubMode = true
417+
res.MachineHubConfig = cfg.MachineHubConfig
418+
}
419+
369420
{
370421
var (
371422
mode AuthMode
@@ -396,19 +447,26 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags)
396447
mode = JetstackSecureOAuth
397448
reason = "--credentials-file was specified without --venafi-cloud"
398449
default:
399-
return CombinedConfig{}, nil, fmt.Errorf("no auth mode specified. You can use one of four auth modes:\n" +
400-
" - Use (--venafi-cloud with --credentials-file) or (--client-id with --private-key-path) to use the " + string(VenafiCloudKeypair) + " mode.\n" +
401-
" - Use --venafi-connection for the " + string(VenafiCloudVenafiConnection) + " mode.\n" +
402-
" - Use --credentials-file alone if you want to use the " + string(JetstackSecureOAuth) + " mode.\n" +
403-
" - Use --api-token if you want to use the " + string(JetstackSecureAPIToken) + " mode.\n")
450+
if !flags.MachineHubMode {
451+
return CombinedConfig{}, nil, fmt.Errorf("no auth mode specified and MachineHub mode is disabled. You can use one of four auth modes:\n" +
452+
" - Use (--venafi-cloud with --credentials-file) or (--client-id with --private-key-path) to use the " + string(VenafiCloudKeypair) + " mode.\n" +
453+
" - Use --venafi-connection for the " + string(VenafiCloudVenafiConnection) + " mode.\n" +
454+
" - Use --credentials-file alone if you want to use the " + string(JetstackSecureOAuth) + " mode.\n" +
455+
" - Use --api-token if you want to use the " + string(JetstackSecureAPIToken) + " mode.\n")
456+
}
457+
458+
mode = NoTLSPK
459+
reason = "only MachineHub has been configured as a backend"
404460
}
461+
405462
res.AuthMode = mode
406463
keysAndValues = append(keysAndValues, "mode", mode, "reason", reason)
407464
log.V(logs.Debug).Info("Authentication mode", keysAndValues...)
408465
}
409466

410467
// Validation and defaulting of `server` and the deprecated `endpoint.path`.
411-
{
468+
if res.AuthMode != NoTLSPK {
469+
// Only relevant if using TLSPK backends
412470
hasEndpointField := cfg.Endpoint.Host != "" && cfg.Endpoint.Path != ""
413471
hasServerField := cfg.Server != ""
414472
var server string
@@ -493,7 +551,7 @@ func ValidateAndCombineConfig(log logr.Logger, cfg Config, flags AgentCmdFlags)
493551
}
494552

495553
// Validation of `cluster_id` and `organization_id`.
496-
{
554+
if res.AuthMode != NoTLSPK {
497555
var clusterID string
498556
var organizationID string // Only used by the old jetstack-secure mode.
499557
switch {

pkg/agent/run.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -327,19 +327,38 @@ func gatherAndOutputData(ctx context.Context, eventf Eventf, config CombinedConf
327327
}
328328
log.Info("Data saved to local file", "outputPath", config.OutputPath)
329329
} else {
330-
backOff := backoff.NewExponentialBackOff()
331-
backOff.InitialInterval = 30 * time.Second
332-
backOff.MaxInterval = 3 * time.Minute
333-
backOff.MaxElapsedTime = config.BackoffMaxTime
334-
post := func() error {
335-
return postData(klog.NewContext(ctx, log), config, preflightClient, readings)
336-
}
337-
err := backoff.RetryNotify(post, backOff, func(err error, t time.Duration) {
330+
group, gctx := errgroup.WithContext(ctx)
331+
332+
backOffCfg := backoff.NewExponentialBackOff()
333+
backOffCfg.InitialInterval = 30 * time.Second
334+
backOffCfg.MaxInterval = 3 * time.Minute
335+
backOffCfg.MaxElapsedTime = config.BackoffMaxTime
336+
337+
notifyFn := func(err error, t time.Duration) {
338338
eventf("Warning", "PushingErr", "retrying in %v after error: %s", t, err)
339339
log.Info("Warning: PushingErr: retrying", "in", t, "reason", err)
340-
})
341-
if err != nil {
342-
return fmt.Errorf("Exiting due to fatal error uploading: %v", err)
340+
}
341+
342+
if cfg.MachineHubMode {
343+
post := func() error {
344+
log.Info("machine hub mode not yet implemented")
345+
return nil
346+
}
347+
348+
group.Go(backoff.RetryNotify(post, backOffCfg, notifyFn))
349+
}
350+
351+
if cfg.AuthMode != NoTLSPK {
352+
post := func() error {
353+
return postData(klog.NewContext(ctx, log), config, preflightClient, readings)
354+
}
355+
356+
group.Go(backoff.RetryNotify(post, backOffCfg, notifyFn))
357+
}
358+
359+
groupErr := group.Wait()
360+
if groupErr != nil {
361+
return fmt.Errorf("got a fatal error from one or more upload actions: %s", groupErr)
343362
}
344363
}
345364
return nil

0 commit comments

Comments
 (0)