diff --git a/src/pkg/cluster/injector.go b/src/pkg/cluster/injector.go index 48552ac5e1..1ee24c2150 100644 --- a/src/pkg/cluster/injector.go +++ b/src/pkg/cluster/injector.go @@ -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), } diff --git a/src/pkg/variables/types.go b/src/pkg/variables/types.go index 6b3be2863b..442d35bbb2 100644 --- a/src/pkg/variables/types.go +++ b/src/pkg/variables/types.go @@ -8,6 +8,7 @@ import ( "fmt" "regexp" + "github.com/invopop/jsonschema" "github.com/zarf-dev/zarf/src/config/lang" ) @@ -21,16 +22,14 @@ const ( 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_. @@ -38,7 +37,16 @@ type Variable struct { // 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") + kind.Enum = []any{RawVariableType, FileVariableType} + + name, _ := schema.Properties.Get("name") + name.Pattern = UppercaseNumberUnderscorePattern } // InteractiveVariable is a variable that can be used to prompt a user for more information @@ -55,7 +63,7 @@ type InteractiveVariable struct { // 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 @@ -66,6 +74,12 @@ type Constant struct { 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 +} + // SetVariable tracks internal variables that have been set during this run of Zarf type SetVariable struct { Variable `json:",inline"` diff --git a/src/types/component.go b/src/types/component.go index b43493ad0a..32193cfc29 100644 --- a/src/types/component.go +++ b/src/types/component.go @@ -92,13 +92,23 @@ func (c ZarfComponent) IsRequired() bool { // 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) + } + kind.Enum = supportOSEnum +} + // ZarfComponentOnlyCluster represents the architecture and K8s cluster distribution to filter on. type ZarfComponentOnlyCluster struct { // Only create and deploy to clusters of the given architecture. @@ -152,13 +162,19 @@ type ZarfChart struct { // 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 +} + // 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. @@ -248,7 +264,7 @@ type ZarfComponentAction struct { // (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. @@ -257,6 +273,12 @@ type ZarfComponentAction struct { 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 +} + // 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. diff --git a/src/types/package.go b/src/types/package.go index bb4b0edc0a..f2d3394e8f 100644 --- a/src/types/package.go +++ b/src/types/package.go @@ -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 @@ -19,7 +22,7 @@ const ( // 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. @@ -32,6 +35,13 @@ type ZarfPackage struct { 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 +} + // IsInitConfig returns whether a Zarf package is an init config. func (pkg ZarfPackage) IsInitConfig() bool { return pkg.Kind == ZarfInitConfig diff --git a/src/types/validate.go b/src/types/validate.go index 05289a1781..3d9c8cf2e4 100644 --- a/src/types/validate.go +++ b/src/types/validate.go @@ -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 }