Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove magic strings in struct tags #2787

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/pkg/cluster/injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,11 @@ func (c *Cluster) createPayloadConfigMaps(ctx context.Context, spinner *message.
return cmNames, shasum, nil
}

var zarfImageRegex = regexp.MustCompile(`(?m)^127\.0\.0\.1:`)

// getImagesAndNodesForInjection checks for images on schedulable nodes within a cluster.
func (c *Cluster) getInjectorImageAndNode(ctx context.Context, resReq corev1.ResourceRequirements) (string, string, error) {
// Regex for Zarf seed image
zarfImageRegex, err := regexp.Compile(`(?m)^127\.0\.0\.1:`)
if err != nil {
return "", "", err
}
listOpts := metav1.ListOptions{
FieldSelector: fmt.Sprintf("status.phase=%s", corev1.PodRunning),
}
Expand Down
30 changes: 22 additions & 8 deletions src/pkg/variables/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"fmt"
"regexp"

"github.com/invopop/jsonschema"
"github.com/zarf-dev/zarf/src/config/lang"
)

Expand All @@ -21,24 +22,31 @@
FileVariableType VariableType = "file"
)

var (
// IsUppercaseNumberUnderscore is a regex for uppercase, numbers and underscores.
// https://regex101.com/r/tfsEuZ/1
IsUppercaseNumberUnderscore = regexp.MustCompile(`^[A-Z0-9_]+$`).MatchString
)
// UppercaseNumberUnderscorePattern is a regex for uppercase, numbers and underscores.
// https://regex101.com/r/tfsEuZ/1
const UppercaseNumberUnderscorePattern = `^[A-Z0-9_]+$`

// Variable represents a variable that has a value set programmatically
type Variable struct {
// The name to be used for the variable
Name string `json:"name" jsonschema:"pattern=^[A-Z0-9_]+$"`
Name string `json:"name"`
// Whether to mark this variable as sensitive to not print it in the log
Sensitive bool `json:"sensitive,omitempty"`
// Whether to automatically indent the variable's value (if multiline) when templating. Based on the number of chars before the start of ###ZARF_VAR_.
AutoIndent bool `json:"autoIndent,omitempty"`
// An optional regex pattern that a variable value must match before a package deployment can continue.
Pattern string `json:"pattern,omitempty"`
// Changes the handling of a variable to load contents differently (i.e. from a file rather than as a raw variable - templated files should be kept below 1 MiB)
Type VariableType `json:"type,omitempty" jsonschema:"enum=raw,enum=file"`
Type VariableType `json:"type,omitempty"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (Variable) JSONSchemaExtend(schema *jsonschema.Schema) {
kind, _ := schema.Properties.Get("type")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ignoring an error 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ignoring the present flag but I'd rather have the code panic if it doesn't find something since this is only run on zarf internal gen-config-schema

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't change the signature to return an error, since this signature is necessary for this function to get called by the jsonschema package during schema creation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot be a production grade tool that panics.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only called during schema generation, zarf internal gen-config-schema, and this would only panic if, during development, someone changed the json tag to not equal what is in the schema.Properties.Get call.

Given that we don't have control over this function signature I think there's two options:

  1. return when the key isn't found - IMO this is worse because there won't be any signal from the CLI that something went wrong during schema generation. I'm fine with this though, it would happen rarely & it should be relatively obvious from the git diff that something went wrong.
  2. Keep panicing, maybe explicitly panic with a clear error message.

kind.Enum = []any{RawVariableType, FileVariableType}

Check warning on line 46 in src/pkg/variables/types.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/variables/types.go#L44-L46

Added lines #L44 - L46 were not covered by tests

name, _ := schema.Properties.Get("name")
name.Pattern = UppercaseNumberUnderscorePattern

Check warning on line 49 in src/pkg/variables/types.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/variables/types.go#L48-L49

Added lines #L48 - L49 were not covered by tests
}

// InteractiveVariable is a variable that can be used to prompt a user for more information
Expand All @@ -55,7 +63,7 @@
// Constant are constants that can be used to dynamically template K8s resources or run in actions.
type Constant struct {
// The name to be used for the constant
Name string `json:"name" jsonschema:"pattern=^[A-Z0-9_]+$"`
Name string `json:"name"`
// The value to set for the constant during deploy
Value string `json:"value"`
// A description of the constant to explain its purpose on package create or deploy confirmation prompts
Expand All @@ -66,6 +74,12 @@
Pattern string `json:"pattern,omitempty"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (Constant) JSONSchemaExtend(schema *jsonschema.Schema) {
name, _ := schema.Properties.Get("name")
name.Pattern = UppercaseNumberUnderscorePattern

Check warning on line 80 in src/pkg/variables/types.go

View check run for this annotation

Codecov / codecov/patch

src/pkg/variables/types.go#L78-L80

Added lines #L78 - L80 were not covered by tests
}

// SetVariable tracks internal variables that have been set during this run of Zarf
type SetVariable struct {
Variable `json:",inline"`
Expand Down
28 changes: 25 additions & 3 deletions src/types/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,23 @@
// ZarfComponentOnlyTarget filters a component to only show it for a given local OS and cluster.
type ZarfComponentOnlyTarget struct {
// Only deploy component to specified OS.
LocalOS string `json:"localOS,omitempty" jsonschema:"enum=linux,enum=darwin,enum=windows"`
LocalOS string `json:"localOS,omitempty"`
// Only deploy component to specified clusters.
Cluster ZarfComponentOnlyCluster `json:"cluster,omitempty"`
// Only include this component when a matching '--flavor' is specified on 'zarf package create'.
Flavor string `json:"flavor,omitempty"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (ZarfComponentOnlyTarget) JSONSchemaExtend(schema *jsonschema.Schema) {
kind, _ := schema.Properties.Get("localOS")
supportOSEnum := []any{}
for _, os := range supportedOS {
supportOSEnum = append(supportOSEnum, os)

Check warning on line 107 in src/types/component.go

View check run for this annotation

Codecov / codecov/patch

src/types/component.go#L103-L107

Added lines #L103 - L107 were not covered by tests
}
kind.Enum = supportOSEnum

Check warning on line 109 in src/types/component.go

View check run for this annotation

Codecov / codecov/patch

src/types/component.go#L109

Added line #L109 was not covered by tests
}

// ZarfComponentOnlyCluster represents the architecture and K8s cluster distribution to filter on.
type ZarfComponentOnlyCluster struct {
// Only create and deploy to clusters of the given architecture.
Expand Down Expand Up @@ -152,13 +162,19 @@
// ZarfChartVariable represents a variable that can be set for a Helm chart overrides.
type ZarfChartVariable struct {
// The name of the variable.
Name string `json:"name" jsonschema:"pattern=^[A-Z0-9_]+$"`
Name string `json:"name"`
// A brief description of what the variable controls.
Description string `json:"description"`
// The path within the Helm chart values where this variable applies.
Path string `json:"path"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (ZarfChartVariable) JSONSchemaExtend(schema *jsonschema.Schema) {
name, _ := schema.Properties.Get("name")
name.Pattern = variables.UppercaseNumberUnderscorePattern

Check warning on line 175 in src/types/component.go

View check run for this annotation

Codecov / codecov/patch

src/types/component.go#L173-L175

Added lines #L173 - L175 were not covered by tests
}

// ZarfManifest defines raw manifests Zarf will deploy as a helm chart.
type ZarfManifest struct {
// A name to give this collection of manifests; this will become the name of the dynamically-created helm chart.
Expand Down Expand Up @@ -248,7 +264,7 @@
// (cmd only) Indicates a preference for a shell for the provided cmd to be executed in on supported operating systems.
Shell *exec.Shell `json:"shell,omitempty"`
// [Deprecated] (replaced by setVariables) (onDeploy/cmd only) The name of a variable to update with the output of the command. This variable will be available to all remaining actions and components in the package. This will be removed in Zarf v1.0.0.
DeprecatedSetVariable string `json:"setVariable,omitempty" jsonschema:"pattern=^[A-Z0-9_]+$"`
DeprecatedSetVariable string `json:"setVariable,omitempty"`
// (onDeploy/cmd only) An array of variables to update with the output of the command. These variables will be available to all remaining actions and components in the package.
SetVariables []variables.Variable `json:"setVariables,omitempty"`
// Description of the action to be displayed during package execution instead of the command.
Expand All @@ -257,6 +273,12 @@
Wait *ZarfComponentActionWait `json:"wait,omitempty"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (ZarfComponentAction) JSONSchemaExtend(schema *jsonschema.Schema) {
name, _ := schema.Properties.Get("setVariable")
name.Pattern = variables.UppercaseNumberUnderscorePattern

Check warning on line 279 in src/types/component.go

View check run for this annotation

Codecov / codecov/patch

src/types/component.go#L277-L279

Added lines #L277 - L279 were not covered by tests
}

// ZarfComponentActionWait specifies a condition to wait for before continuing
type ZarfComponentActionWait struct {
// Wait for a condition to be met in the cluster before continuing. Only one of cluster or network can be specified.
Expand Down
14 changes: 12 additions & 2 deletions src/types/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
// Package types contains all the types used by Zarf.
package types

import "github.com/zarf-dev/zarf/src/pkg/variables"
import (
"github.com/invopop/jsonschema"
"github.com/zarf-dev/zarf/src/pkg/variables"
)

// ZarfPackageKind is an enum of the different kinds of Zarf packages.
type ZarfPackageKind string
Expand All @@ -19,7 +22,7 @@
// ZarfPackage the top-level structure of a Zarf config file.
type ZarfPackage struct {
// The kind of Zarf package.
Kind ZarfPackageKind `json:"kind" jsonschema:"enum=ZarfInitConfig,enum=ZarfPackageConfig,default=ZarfPackageConfig"`
Kind ZarfPackageKind `json:"kind"`
// Package metadata.
Metadata ZarfMetadata `json:"metadata,omitempty"`
// Zarf-generated package build data.
Expand All @@ -32,6 +35,13 @@
Variables []variables.InteractiveVariable `json:"variables,omitempty"`
}

// JSONSchemaExtend extends the generated json schema during `zarf internal gen-config-schema`
func (ZarfPackage) JSONSchemaExtend(schema *jsonschema.Schema) {
kind, _ := schema.Properties.Get("kind")
kind.Enum = []interface{}{ZarfInitConfig, ZarfPackageConfig}
kind.Default = ZarfPackageConfig

Check warning on line 42 in src/types/package.go

View check run for this annotation

Codecov / codecov/patch

src/types/package.go#L39-L42

Added lines #L39 - L42 were not covered by tests
}

// IsInitConfig returns whether a Zarf package is an init config.
func (pkg ZarfPackage) IsInitConfig() bool {
return pkg.Kind == ZarfInitConfig
Expand Down
10 changes: 2 additions & 8 deletions src/types/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,10 @@ var (
// IsLowercaseNumberHyphenNoStartHyphen is a regex for lowercase, numbers and hyphens that cannot start with a hyphen.
// https://regex101.com/r/FLdG9G/2
IsLowercaseNumberHyphenNoStartHyphen = regexp.MustCompile(`^[a-z0-9][a-z0-9\-]*$`).MatchString
// Define allowed OS, an empty string means it is allowed on all operating systems
// same as enums on ZarfComponentOnlyTarget
supportedOS = []string{"linux", "darwin", "windows", ""}
supportedOS = []string{"linux", "darwin", "windows"}
)

// SupportedOS returns the supported operating systems.
//
// The supported operating systems are: linux, darwin, windows.
//
// An empty string signifies no OS restrictions.
// SupportedOS returns the Zarf supported operating systems.
func SupportedOS() []string {
return supportedOS
}
Expand Down