github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/types/component.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package types contains all the types used by Jackal.
     5  package types
     6  
     7  import (
     8  	"github.com/Racer159/jackal/src/pkg/utils/exec"
     9  	"github.com/Racer159/jackal/src/types/extensions"
    10  )
    11  
    12  // JackalComponent is the primary functional grouping of assets to deploy by Jackal.
    13  type JackalComponent struct {
    14  	// Name is the unique identifier for this component
    15  	Name string `json:"name" jsonschema:"description=The name of the component,pattern=^[a-z0-9\\-]*[a-z0-9]$"`
    16  
    17  	// Description is a message given to a user when deciding to enable this component or not
    18  	Description string `json:"description,omitempty" jsonschema:"description=Message to include during package deploy describing the purpose of this component"`
    19  
    20  	// Default changes the default option when deploying this component
    21  	Default bool `json:"default,omitempty" jsonschema:"description=Determines the default Y/N state for installing this component on package deploy"`
    22  
    23  	// Required makes this component mandatory for package deployment
    24  	Required *bool `json:"required,omitempty" jsonschema:"description=Do not prompt user to install this component, always install on package deploy."`
    25  
    26  	// Only include compatible components during package deployment
    27  	Only JackalComponentOnlyTarget `json:"only,omitempty" jsonschema:"description=Filter when this component is included in package creation or deployment"`
    28  
    29  	// DeprecatedGroup is a key to match other components to produce a user selector field, used to create a BOOLEAN XOR for a set of components
    30  	//
    31  	// Note: ignores default and required flags
    32  	DeprecatedGroup string `json:"group,omitempty" jsonschema:"description=[Deprecated] Create a user selector field based on all components in the same group. This will be removed in Jackal v1.0.0. Consider using 'only.flavor' instead.,deprecated=true"`
    33  
    34  	// DeprecatedCosignKeyPath to cosign public key for signed online resources
    35  	DeprecatedCosignKeyPath string `json:"cosignKeyPath,omitempty" jsonschema:"description=[Deprecated] Specify a path to a public key to validate signed online resources. This will be removed in Jackal v1.0.0.,deprecated=true"`
    36  
    37  	// Import refers to another jackal.yaml package component.
    38  	Import JackalComponentImport `json:"import,omitempty" jsonschema:"description=Import a component from another Jackal package"`
    39  
    40  	// Manifests are raw manifests that get converted into jackal-generated helm charts during deploy
    41  	Manifests []JackalManifest `json:"manifests,omitempty" jsonschema:"description=Kubernetes manifests to be included in a generated Helm chart on package deploy"`
    42  
    43  	// Charts are helm charts to install during package deploy
    44  	Charts []JackalChart `json:"charts,omitempty" jsonschema:"description=Helm charts to install during package deploy"`
    45  
    46  	// Data packages to push into a running cluster
    47  	DataInjections []JackalDataInjection `json:"dataInjections,omitempty" jsonschema:"description=Datasets to inject into a container in the target cluster"`
    48  
    49  	// Files are files to place on disk during deploy
    50  	Files []JackalFile `json:"files,omitempty" jsonschema:"description=Files or folders to place on disk during package deployment"`
    51  
    52  	// Images are the online images needed to be included in the jackal package
    53  	Images []string `json:"images,omitempty" jsonschema:"description=List of OCI images to include in the package"`
    54  
    55  	// Repos are any git repos that need to be pushed into the git server
    56  	Repos []string `json:"repos,omitempty" jsonschema:"description=List of git repos to include in the package"`
    57  
    58  	// Extensions provide additional functionality to a component
    59  	Extensions extensions.JackalComponentExtensions `json:"extensions,omitempty" jsonschema:"description=Extend component functionality with additional features"`
    60  
    61  	// DeprecatedScripts are custom commands that run before or after package deployment
    62  	DeprecatedScripts DeprecatedJackalComponentScripts `json:"scripts,omitempty" jsonschema:"description=[Deprecated] (replaced by actions) Custom commands to run before or after package deployment.  This will be removed in Jackal v1.0.0.,deprecated=true"`
    63  
    64  	// Replaces scripts, fine-grained control over commands to run at various stages of a package lifecycle
    65  	Actions JackalComponentActions `json:"actions,omitempty" jsonschema:"description=Custom commands to run at various stages of a package lifecycle"`
    66  }
    67  
    68  // RequiresCluster returns if the component requires a cluster connection to deploy
    69  func (c JackalComponent) RequiresCluster() bool {
    70  	hasImages := len(c.Images) > 0
    71  	hasCharts := len(c.Charts) > 0
    72  	hasManifests := len(c.Manifests) > 0
    73  	hasRepos := len(c.Repos) > 0
    74  	hasDataInjections := len(c.DataInjections) > 0
    75  
    76  	if hasImages || hasCharts || hasManifests || hasRepos || hasDataInjections {
    77  		return true
    78  	}
    79  
    80  	return false
    81  }
    82  
    83  // JackalComponentOnlyTarget filters a component to only show it for a given local OS and cluster.
    84  type JackalComponentOnlyTarget struct {
    85  	LocalOS string                     `json:"localOS,omitempty" jsonschema:"description=Only deploy component to specified OS,enum=linux,enum=darwin,enum=windows"`
    86  	Cluster JackalComponentOnlyCluster `json:"cluster,omitempty" jsonschema:"description=Only deploy component to specified clusters"`
    87  	Flavor  string                     `json:"flavor,omitempty" jsonschema:"description=Only include this component when a matching '--flavor' is specified on 'jackal package create'"`
    88  }
    89  
    90  // JackalComponentOnlyCluster represents the architecture and K8s cluster distribution to filter on.
    91  type JackalComponentOnlyCluster struct {
    92  	Architecture string   `json:"architecture,omitempty" jsonschema:"description=Only create and deploy to clusters of the given architecture,enum=amd64,enum=arm64"`
    93  	Distros      []string `json:"distros,omitempty" jsonschema:"description=A list of kubernetes distros this package works with (Reserved for future use),example=k3s,example=eks"`
    94  }
    95  
    96  // JackalFile defines a file to deploy.
    97  type JackalFile struct {
    98  	Source      string   `json:"source" jsonschema:"description=Local folder or file path or remote URL to pull into the package"`
    99  	Shasum      string   `json:"shasum,omitempty" jsonschema:"description=(files only) Optional SHA256 checksum of the file"`
   100  	Target      string   `json:"target" jsonschema:"description=The absolute or relative path where the file or folder should be copied to during package deploy"`
   101  	Executable  bool     `json:"executable,omitempty" jsonschema:"description=(files only) Determines if the file should be made executable during package deploy"`
   102  	Symlinks    []string `json:"symlinks,omitempty" jsonschema:"description=List of symlinks to create during package deploy"`
   103  	ExtractPath string   `json:"extractPath,omitempty" jsonschema:"description=Local folder or file to be extracted from a 'source' archive"`
   104  }
   105  
   106  // JackalChart defines a helm chart to be deployed.
   107  type JackalChart struct {
   108  	Name        string   `json:"name" jsonschema:"description=The name of the chart within Jackal; note that this must be unique and does not need to be the same as the name in the chart repo"`
   109  	Version     string   `json:"version,omitempty" jsonschema:"description=The version of the chart to deploy; for git-based charts this is also the tag of the git repo by default (when not using the '@' syntax for 'repos')"`
   110  	URL         string   `json:"url,omitempty" jsonschema:"example=OCI registry: oci://ghcr.io/stefanprodan/charts/podinfo,example=helm chart repo: https://stefanprodan.github.io/podinfo,example=git repo: https://github.com/stefanprodan/podinfo (note the '@' syntax for 'repos' is supported here too)" jsonschema_description:"The URL of the OCI registry, chart repository, or git repo where the helm chart is stored"`
   111  	RepoName    string   `json:"repoName,omitempty" jsonschema:"description=The name of a chart within a Helm repository (defaults to the Jackal name of the chart)"`
   112  	GitPath     string   `json:"gitPath,omitempty" jsonschema:"description=(git repo only) The sub directory to the chart within a git repo,example=charts/your-chart"`
   113  	LocalPath   string   `json:"localPath,omitempty" jsonschema:"description=The path to a local chart's folder or .tgz archive"`
   114  	Namespace   string   `json:"namespace" jsonschema:"description=The namespace to deploy the chart to"`
   115  	ReleaseName string   `json:"releaseName,omitempty" jsonschema:"description=The name of the Helm release to create (defaults to the Jackal name of the chart)"`
   116  	NoWait      bool     `json:"noWait,omitempty" jsonschema:"description=Whether to not wait for chart resources to be ready before continuing"`
   117  	ValuesFiles []string `json:"valuesFiles,omitempty" jsonschema:"description=List of local values file paths or remote URLs to include in the package; these will be merged together when deployed"`
   118  }
   119  
   120  // JackalManifest defines raw manifests Jackal will deploy as a helm chart.
   121  type JackalManifest struct {
   122  	Name                       string   `json:"name" jsonschema:"description=A name to give this collection of manifests; this will become the name of the dynamically-created helm chart"`
   123  	Namespace                  string   `json:"namespace,omitempty" jsonschema:"description=The namespace to deploy the manifests to"`
   124  	Files                      []string `json:"files,omitempty" jsonschema:"description=List of local K8s YAML files or remote URLs to deploy (in order)"`
   125  	KustomizeAllowAnyDirectory bool     `json:"kustomizeAllowAnyDirectory,omitempty" jsonschema:"description=Allow traversing directory above the current directory if needed for kustomization"`
   126  	Kustomizations             []string `json:"kustomizations,omitempty" jsonschema:"description=List of local kustomization paths or remote URLs to include in the package"`
   127  	NoWait                     bool     `json:"noWait,omitempty" jsonschema:"description=Whether to not wait for manifest resources to be ready before continuing"`
   128  }
   129  
   130  // DeprecatedJackalComponentScripts are scripts that run before or after a component is deployed
   131  type DeprecatedJackalComponentScripts struct {
   132  	ShowOutput     bool     `json:"showOutput,omitempty" jsonschema:"description=Show the output of the script during package deployment"`
   133  	TimeoutSeconds int      `json:"timeoutSeconds,omitempty" jsonschema:"description=Timeout in seconds for the script"`
   134  	Retry          bool     `json:"retry,omitempty" jsonschema:"description=Retry the script if it fails"`
   135  	Prepare        []string `json:"prepare,omitempty" jsonschema:"description=Scripts to run before the component is added during package create"`
   136  	Before         []string `json:"before,omitempty" jsonschema:"description=Scripts to run before the component is deployed"`
   137  	After          []string `json:"after,omitempty" jsonschema:"description=Scripts to run after the component successfully deploys"`
   138  }
   139  
   140  // JackalComponentActions are ActionSets that map to different jackal package operations
   141  type JackalComponentActions struct {
   142  	OnCreate JackalComponentActionSet `json:"onCreate,omitempty" jsonschema:"description=Actions to run during package creation"`
   143  	OnDeploy JackalComponentActionSet `json:"onDeploy,omitempty" jsonschema:"description=Actions to run during package deployment"`
   144  	OnRemove JackalComponentActionSet `json:"onRemove,omitempty" jsonschema:"description=Actions to run during package removal"`
   145  }
   146  
   147  // JackalComponentActionSet is a set of actions to run during a jackal package operation
   148  type JackalComponentActionSet struct {
   149  	Defaults  JackalComponentActionDefaults `json:"defaults,omitempty" jsonschema:"description=Default configuration for all actions in this set"`
   150  	Before    []JackalComponentAction       `json:"before,omitempty" jsonschema:"description=Actions to run at the start of an operation"`
   151  	After     []JackalComponentAction       `json:"after,omitempty" jsonschema:"description=Actions to run at the end of an operation"`
   152  	OnSuccess []JackalComponentAction       `json:"onSuccess,omitempty" jsonschema:"description=Actions to run if all operations succeed"`
   153  	OnFailure []JackalComponentAction       `json:"onFailure,omitempty" jsonschema:"description=Actions to run if all operations fail"`
   154  }
   155  
   156  // JackalComponentActionDefaults sets the default configs for child actions
   157  type JackalComponentActionDefaults struct {
   158  	Mute            bool       `json:"mute,omitempty" jsonschema:"description=Hide the output of commands during execution (default false)"`
   159  	MaxTotalSeconds int        `json:"maxTotalSeconds,omitempty" jsonschema:"description=Default timeout in seconds for commands (default to 0, no timeout)"`
   160  	MaxRetries      int        `json:"maxRetries,omitempty" jsonschema:"description=Retry commands given number of times if they fail (default 0)"`
   161  	Dir             string     `json:"dir,omitempty" jsonschema:"description=Working directory for commands (default CWD)"`
   162  	Env             []string   `json:"env,omitempty" jsonschema:"description=Additional environment variables for commands"`
   163  	Shell           exec.Shell `json:"shell,omitempty" jsonschema:"description=(cmd only) Indicates a preference for a shell for the provided cmd to be executed in on supported operating systems"`
   164  }
   165  
   166  // JackalComponentAction represents a single action to run during a jackal package operation
   167  type JackalComponentAction struct {
   168  	Mute                  *bool                              `json:"mute,omitempty" jsonschema:"description=Hide the output of the command during package deployment (default false)"`
   169  	MaxTotalSeconds       *int                               `json:"maxTotalSeconds,omitempty" jsonschema:"description=Timeout in seconds for the command (default to 0, no timeout for cmd actions and 300, 5 minutes for wait actions)"`
   170  	MaxRetries            *int                               `json:"maxRetries,omitempty" jsonschema:"description=Retry the command if it fails up to given number of times (default 0)"`
   171  	Dir                   *string                            `json:"dir,omitempty" jsonschema:"description=The working directory to run the command in (default is CWD)"`
   172  	Env                   []string                           `json:"env,omitempty" jsonschema:"description=Additional environment variables to set for the command"`
   173  	Cmd                   string                             `json:"cmd,omitempty" jsonschema:"description=The command to run. Must specify either cmd or wait for the action to do anything."`
   174  	Shell                 *exec.Shell                        `json:"shell,omitempty" jsonschema:"description=(cmd only) Indicates a preference for a shell for the provided cmd to be executed in on supported operating systems"`
   175  	DeprecatedSetVariable string                             `json:"setVariable,omitempty" jsonschema:"description=[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 Jackal v1.0.0,pattern=^[A-Z0-9_]+$"`
   176  	SetVariables          []JackalComponentActionSetVariable `json:"setVariables,omitempty" jsonschema:"description=(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."`
   177  	Description           string                             `json:"description,omitempty" jsonschema:"description=Description of the action to be displayed during package execution instead of the command"`
   178  	Wait                  *JackalComponentActionWait         `json:"wait,omitempty" jsonschema:"description=Wait for a condition to be met before continuing. Must specify either cmd or wait for the action. See the 'jackal tools wait-for' command for more info."`
   179  }
   180  
   181  // JackalComponentActionSetVariable represents a variable that is to be set via an action
   182  type JackalComponentActionSetVariable struct {
   183  	Name       string       `json:"name" jsonschema:"description=The name to be used for the variable,pattern=^[A-Z0-9_]+$"`
   184  	Type       VariableType `json:"type,omitempty" jsonschema:"description=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),enum=raw,enum=file"`
   185  	Pattern    string       `json:"pattern,omitempty" jsonschema:"description=An optional regex pattern that a variable value must match before a package deployment can continue."`
   186  	Sensitive  bool         `json:"sensitive,omitempty" jsonschema:"description=Whether to mark this variable as sensitive to not print it in the Jackal log"`
   187  	AutoIndent bool         `json:"autoIndent,omitempty" jsonschema:"description=Whether to automatically indent the variable's value (if multiline) when templating. Based on the number of chars before the start of ###JACKAL_VAR_."`
   188  }
   189  
   190  // JackalComponentActionWait specifies a condition to wait for before continuing
   191  type JackalComponentActionWait struct {
   192  	Cluster *JackalComponentActionWaitCluster `json:"cluster,omitempty" jsonschema:"description=Wait for a condition to be met in the cluster before continuing. Only one of cluster or network can be specified."`
   193  	Network *JackalComponentActionWaitNetwork `json:"network,omitempty" jsonschema:"description=Wait for a condition to be met on the network before continuing. Only one of cluster or network can be specified."`
   194  }
   195  
   196  // JackalComponentActionWaitCluster specifies a condition to wait for before continuing
   197  type JackalComponentActionWaitCluster struct {
   198  	Kind       string `json:"kind" jsonschema:"description=The kind of resource to wait for,example=Pod,example=Deployment)"`
   199  	Identifier string `json:"name" jsonschema:"description=The name of the resource or selector to wait for,example=podinfo,example=app=podinfo"`
   200  	Namespace  string `json:"namespace,omitempty" jsonschema:"description=The namespace of the resource to wait for"`
   201  	Condition  string `json:"condition,omitempty" jsonschema:"description=The condition or jsonpath state to wait for; defaults to exist, a special condition that will wait for the resource to exist,example=Ready,example=Available,'{.status.availableReplicas}'=23"`
   202  }
   203  
   204  // JackalComponentActionWaitNetwork specifies a condition to wait for before continuing
   205  type JackalComponentActionWaitNetwork struct {
   206  	Protocol string `json:"protocol" jsonschema:"description=The protocol to wait for,enum=tcp,enum=http,enum=https"`
   207  	Address  string `json:"address" jsonschema:"description=The address to wait for,example=localhost:8080,example=1.1.1.1"`
   208  	Code     int    `json:"code,omitempty" jsonschema:"description=The HTTP status code to wait for if using http or https,example=200,example=404"`
   209  }
   210  
   211  // JackalContainerTarget defines the destination info for a JackalData target
   212  type JackalContainerTarget struct {
   213  	Namespace string `json:"namespace" jsonschema:"description=The namespace to target for data injection"`
   214  	Selector  string `json:"selector" jsonschema:"description=The K8s selector to target for data injection,example=app=data-injection"`
   215  	Container string `json:"container" jsonschema:"description=The container name to target for data injection"`
   216  	Path      string `json:"path" jsonschema:"description=The path within the container to copy the data into"`
   217  }
   218  
   219  // JackalDataInjection is a data-injection definition.
   220  type JackalDataInjection struct {
   221  	Source   string                `json:"source" jsonschema:"description=Either a path to a local folder/file or a remote URL of a file to inject into the given target pod + container"`
   222  	Target   JackalContainerTarget `json:"target" jsonschema:"description=The target pod + container to inject the data into"`
   223  	Compress bool                  `json:"compress,omitempty" jsonschema:"description=Compress the data before transmitting using gzip.  Note: this requires support for tar/gzip locally and in the target image."`
   224  }
   225  
   226  // JackalComponentImport structure for including imported Jackal components.
   227  type JackalComponentImport struct {
   228  	ComponentName string `json:"name,omitempty" jsonschema:"description=The name of the component to import from the referenced jackal.yaml"`
   229  	// For further explanation see https://regex101.com/r/nxX8vx/1
   230  	Path string `json:"path,omitempty" jsonschema:"description=The relative path to a directory containing a jackal.yaml to import from"`
   231  	// For further explanation see https://regex101.com/r/nxX8vx/1
   232  	URL string `json:"url,omitempty" jsonschema:"description=[beta] The URL to a Jackal package to import via OCI,pattern=^oci://.*$"`
   233  }