github.com/GoogleContainerTools/kpt@v1.0.0-beta.50.0.20240520170205-c25345ffcbee/pkg/api/kptfile/v1/types.go (about)

     1  // Copyright 2021 The kpt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package defines Kptfile schema.
    16  // Version: v1
    17  // swagger:meta
    18  package v1
    19  
    20  import (
    21  	"fmt"
    22  
    23  	"k8s.io/apimachinery/pkg/runtime/schema"
    24  	"sigs.k8s.io/kustomize/kyaml/yaml"
    25  )
    26  
    27  const (
    28  	KptFileName = "Kptfile"
    29  
    30  	RevisionMetaDataFileName = ".KptRevisionMetadata"
    31  
    32  	RevisionMetaDataKind = "KptRevisionMetadata"
    33  
    34  	// Deprecated: prefer KptFileGVK
    35  	KptFileKind = "Kptfile"
    36  
    37  	// Deprecated: prefer KptFileGVK
    38  	KptFileGroup = "kpt.dev"
    39  
    40  	// Deprecated: prefer KptFileGVK
    41  	KptFileVersion = "v1"
    42  
    43  	// Deprecated: prefer KptFileGVK
    44  	KptFileAPIVersion = KptFileGroup + "/" + KptFileVersion
    45  )
    46  
    47  // KptFileGVK is the GroupVersionKind of Kptfile objects
    48  func KptFileGVK() schema.GroupVersionKind {
    49  	return schema.GroupVersionKind{
    50  		Group:   "kpt.dev",
    51  		Version: "v1",
    52  		Kind:    "Kptfile",
    53  	}
    54  }
    55  
    56  // TypeMeta is the TypeMeta for KptFile instances.
    57  var TypeMeta = yaml.ResourceMeta{
    58  	TypeMeta: yaml.TypeMeta{
    59  		APIVersion: KptFileAPIVersion,
    60  		Kind:       KptFileKind,
    61  	},
    62  }
    63  
    64  // KptFile contains information about a package managed with kpt.
    65  // swagger:model kptfile
    66  type KptFile struct {
    67  	yaml.ResourceMeta `yaml:",inline" json:",inline"`
    68  
    69  	Upstream *Upstream `yaml:"upstream,omitempty" json:"upstream,omitempty"`
    70  
    71  	// UpstreamLock is a resolved locator for the last fetch of the package.
    72  	UpstreamLock *UpstreamLock `yaml:"upstreamLock,omitempty" json:"upstreamLock,omitempty"`
    73  
    74  	// Info contains metadata such as license, documentation, etc.
    75  	Info *PackageInfo `yaml:"info,omitempty" json:"info,omitempty"`
    76  
    77  	// Pipeline declares the pipeline of functions.
    78  	Pipeline *Pipeline `yaml:"pipeline,omitempty" json:"pipeline,omitempty"`
    79  
    80  	// Inventory contains parameters for the inventory object used in apply.
    81  	Inventory *Inventory `yaml:"inventory,omitempty" json:"inventory,omitempty"`
    82  
    83  	Status *Status `yaml:"status,omitempty" json:"status,omitempty"`
    84  }
    85  
    86  // OriginType defines the type of origin for a package.
    87  type OriginType string
    88  
    89  const (
    90  	// GitOrigin specifies a package as having been cloned from a git repository.
    91  	GitOrigin OriginType = "git"
    92  )
    93  
    94  // UpdateStrategyType defines the strategy for updating a package from upstream.
    95  type UpdateStrategyType string
    96  
    97  // ToUpdateStrategy takes a string representing an update strategy and will
    98  // return the strategy as an UpdateStrategyType. If the provided string does
    99  // not match any known update strategies, an error will be returned.
   100  func ToUpdateStrategy(strategy string) (UpdateStrategyType, error) {
   101  	switch strategy {
   102  	case string(ResourceMerge):
   103  		return ResourceMerge, nil
   104  	case string(FastForward):
   105  		return FastForward, nil
   106  	case string(ForceDeleteReplace):
   107  		return ForceDeleteReplace, nil
   108  	default:
   109  		return "", fmt.Errorf("unknown update strategy %q", strategy)
   110  	}
   111  }
   112  
   113  const (
   114  	// ResourceMerge performs a structural schema-aware comparison and
   115  	// merges the changes into the local package.
   116  	ResourceMerge UpdateStrategyType = "resource-merge"
   117  	// FastForward fails without updating if the local package was modified
   118  	// since it was fetched.
   119  	FastForward UpdateStrategyType = "fast-forward"
   120  	// ForceDeleteReplace wipes all local changes to the package.
   121  	ForceDeleteReplace UpdateStrategyType = "force-delete-replace"
   122  )
   123  
   124  // UpdateStrategies is a slice with all the supported update strategies.
   125  var UpdateStrategies = []UpdateStrategyType{
   126  	ResourceMerge,
   127  	FastForward,
   128  	ForceDeleteReplace,
   129  }
   130  
   131  // UpdateStrategiesAsStrings returns a list of update strategies as strings.
   132  func UpdateStrategiesAsStrings() []string {
   133  	var strs []string
   134  	for _, s := range UpdateStrategies {
   135  		strs = append(strs, string(s))
   136  	}
   137  	return strs
   138  }
   139  
   140  // Upstream is a user-specified upstream locator for a package.
   141  type Upstream struct {
   142  	// Type is the type of origin.
   143  	Type OriginType `yaml:"type,omitempty" json:"type,omitempty"`
   144  
   145  	// Git is the locator for a package stored on Git.
   146  	Git *Git `yaml:"git,omitempty" json:"git,omitempty"`
   147  
   148  	// UpdateStrategy declares how a package will be updated from upstream.
   149  	UpdateStrategy UpdateStrategyType `yaml:"updateStrategy,omitempty" json:"updateStrategy,omitempty"`
   150  }
   151  
   152  // Git is the user-specified locator for a package on Git.
   153  type Git struct {
   154  	// Repo is the git repository the package.
   155  	// e.g. 'https://github.com/kubernetes/examples.git'
   156  	Repo string `yaml:"repo,omitempty" json:"repo,omitempty"`
   157  
   158  	// Directory is the sub directory of the git repository.
   159  	// e.g. 'staging/cockroachdb'
   160  	Directory string `yaml:"directory,omitempty" json:"directory,omitempty"`
   161  
   162  	// Ref can be a Git branch, tag, or a commit SHA-1.
   163  	Ref string `yaml:"ref,omitempty" json:"ref,omitempty"`
   164  }
   165  
   166  // UpstreamLock is a resolved locator for the last fetch of the package.
   167  type UpstreamLock struct {
   168  	// Type is the type of origin.
   169  	Type OriginType `yaml:"type,omitempty" json:"type,omitempty"`
   170  
   171  	// Git is the resolved locator for a package on Git.
   172  	Git *GitLock `yaml:"git,omitempty" json:"git,omitempty"`
   173  }
   174  
   175  // GitLock is the resolved locator for a package on Git.
   176  type GitLock struct {
   177  	// Repo is the git repository that was fetched.
   178  	// e.g. 'https://github.com/kubernetes/examples.git'
   179  	Repo string `yaml:"repo,omitempty" json:"repo,omitempty"`
   180  
   181  	// Directory is the sub directory of the git repository that was fetched.
   182  	// e.g. 'staging/cockroachdb'
   183  	Directory string `yaml:"directory,omitempty" json:"directory,omitempty"`
   184  
   185  	// Ref can be a Git branch, tag, or a commit SHA-1 that was fetched.
   186  	// e.g. 'master'
   187  	Ref string `yaml:"ref,omitempty" json:"ref,omitempty"`
   188  
   189  	// Commit is the SHA-1 for the last fetch of the package.
   190  	// This is set by kpt for bookkeeping purposes.
   191  	Commit string `yaml:"commit,omitempty" json:"commit,omitempty"`
   192  }
   193  
   194  // PackageInfo contains optional information about the package such as license, documentation, etc.
   195  // These fields are not consumed by any functionality in kpt and are simply passed through.
   196  // Note that like any other KRM resource, humans and automation can also use `metadata.labels` and
   197  // `metadata.annotations` as the extension mechanism.
   198  type PackageInfo struct {
   199  	// Site is the URL for package web page.
   200  	Site string `yaml:"site,omitempty" json:"site,omitempty"`
   201  
   202  	// Email is the list of emails for the package authors.
   203  	Emails []string `yaml:"emails,omitempty" json:"emails,omitempty"`
   204  
   205  	// SPDX license identifier (e.g. "Apache-2.0"). See: https://spdx.org/licenses/
   206  	License string `yaml:"license,omitempty" json:"license,omitempty"`
   207  
   208  	// Relative slash-delimited path to the license file (e.g. LICENSE.txt)
   209  	LicenseFile string `yaml:"licenseFile,omitempty" json:"licenseFile,omitempty"`
   210  
   211  	// Description contains a short description of the package.
   212  	Description string `yaml:"description,omitempty" json:"description,omitempty"`
   213  
   214  	// Keywords is a list of keywords for this package.
   215  	Keywords []string `yaml:"keywords,omitempty" json:"keywords,omitempty"`
   216  
   217  	// Man is the path to documentation about the package
   218  	Man string `yaml:"man,omitempty" json:"man,omitempty"`
   219  
   220  	ReadinessGates []ReadinessGate `yaml:"readinessGates,omitempty" json:"readinessGates,omitempty"`
   221  }
   222  
   223  type ReadinessGate struct {
   224  	ConditionType string `yaml:"conditionType" json:"conditionType"`
   225  }
   226  
   227  // Subpackages declares a local or remote subpackage.
   228  type Subpackage struct {
   229  	// Name of the immediate subdirectory relative to this Kptfile where the suppackage
   230  	// either exists (local subpackages) or will be fetched to (remote subpckages).
   231  	// This must be unique across all subpckages of a package.
   232  	LocalDir string `yaml:"localDir,omitempty" json:"localDir,omitempty"`
   233  
   234  	// Upstream is a reference to where the subpackage should be fetched from.
   235  	// Whether a subpackage is local or remote is determined by whether Upstream is specified.
   236  	Upstream *Upstream `yaml:"upstream,omitempty" json:"upstream,omitempty"`
   237  }
   238  
   239  // Pipeline declares a pipeline of functions used to mutate or validate resources.
   240  // +kubebuilder:object:generate=true
   241  type Pipeline struct {
   242  	//  Sources defines the source packages to resolve as input to the pipeline. Possible values:
   243  	//  a) A slash-separated, OS-agnostic relative package path which may include '.' and '..' e.g. './base', '../foo'
   244  	//     The source package is resolved recursively.
   245  	//  b) Resources in this package using '.'. Meta resources such as the Kptfile, Pipeline, and function configs
   246  	//     are excluded.
   247  	//  c) Resources in this package AND all resolved subpackages using './*'
   248  	//
   249  	// Resultant list of resources are ordered:
   250  	// - According to the order of sources specified in this array.
   251  	// - When using './*': Subpackages are resolved in alphanumerical order before package resources.
   252  	//
   253  	// When omitted, defaults to './*'.
   254  	// Sources []string `yaml:"sources,omitempty"`
   255  
   256  	// Following fields define the sequence of functions in the pipeline.
   257  	// Input of the first function is the resolved sources.
   258  	// Input of the second function is the output of the first function, and so on.
   259  	// Order of operation: mutators, validators
   260  
   261  	// Mutators defines a list of of KRM functions that mutate resources.
   262  	Mutators []Function `yaml:"mutators,omitempty" json:"mutators,omitempty"`
   263  
   264  	// Validators defines a list of KRM functions that validate resources.
   265  	// Validators are not permitted to mutate resources.
   266  	Validators []Function `yaml:"validators,omitempty" json:"validators,omitempty"`
   267  }
   268  
   269  // String returns the string representation of Pipeline struct
   270  // The string returned is the struct content in Go default format.
   271  func (p *Pipeline) String() string {
   272  	return fmt.Sprintf("%+v", *p)
   273  }
   274  
   275  // IsEmpty returns true if the pipeline doesn't contain any functions in any of
   276  // the function chains (mutators, validators).
   277  func (p *Pipeline) IsEmpty() bool {
   278  	if p == nil {
   279  		return true
   280  	}
   281  	if len(p.Mutators) == 0 && len(p.Validators) == 0 {
   282  		return true
   283  	}
   284  	return false
   285  }
   286  
   287  // Function specifies a KRM function.
   288  // +kubebuilder:object:generate=true
   289  type Function struct {
   290  	// `Image` specifies the function container image.
   291  	// It can either be fully qualified, e.g.:
   292  	//
   293  	//	image: gcr.io/kpt-fn/set-labels
   294  	//
   295  	// Optionally, kpt can be configured to use a image
   296  	// registry host-path that will be used to resolve the image path in case
   297  	// the image path is missing (Defaults to gcr.io/kpt-fn).
   298  	// e.g. The following resolves to gcr.io/kpt-fn/set-labels:
   299  	//
   300  	//	image: set-labels
   301  	Image string `yaml:"image,omitempty" json:"image,omitempty"`
   302  
   303  	// Exec specifies the function binary executable.
   304  	// The executable can be fully qualified or it must exists in the $PATH e.g:
   305  	//
   306  	// 	 exec: set-namespace
   307  	// 	 exec: /usr/local/bin/my-custom-fn
   308  	Exec string `yaml:"exec,omitempty" json:"exec,omitempty"`
   309  
   310  	// `ConfigPath` specifies a slash-delimited relative path to a file in the current directory
   311  	// containing a KRM resource used as the function config. This resource is
   312  	// excluded when resolving 'sources', and as a result cannot be operated on
   313  	// by the pipeline.
   314  	ConfigPath string `yaml:"configPath,omitempty" json:"configPath,omitempty"`
   315  
   316  	// `ConfigMap` is a convenient way to specify a function config of kind ConfigMap.
   317  	ConfigMap map[string]string `yaml:"configMap,omitempty" json:"configMap,omitempty"`
   318  
   319  	// `Name` is used to uniquely identify the function declaration
   320  	// this is primarily used for merging function declaration with upstream counterparts
   321  	Name string `yaml:"name,omitempty" json:"name,omitempty"`
   322  
   323  	// `Selectors` are used to specify resources on which the function should be executed
   324  	// if not specified, all resources are selected
   325  	Selectors []Selector `yaml:"selectors,omitempty" json:"selectors,omitempty"`
   326  
   327  	// `Exclude` are used to specify resources on which the function should NOT be executed.
   328  	// If not specified, all resources selected by `Selectors` are selected.
   329  	Exclusions []Selector `yaml:"exclude,omitempty" json:"exclude,omitempty"`
   330  }
   331  
   332  // Selector specifies the selection criteria
   333  // please update IsEmpty method if more properties are added
   334  // +kubebuilder:object:generate=true
   335  type Selector struct {
   336  	// APIVersion of the target resources
   337  	APIVersion string `yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
   338  	// Kind of the target resources
   339  	Kind string `yaml:"kind,omitempty" json:"kind,omitempty"`
   340  	// Name of the target resources
   341  	Name string `yaml:"name,omitempty" json:"name,omitempty"`
   342  	// Namespace of the target resources
   343  	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
   344  	// Labels on the target resources
   345  	Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
   346  	// Annotations on the target resources
   347  	Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
   348  }
   349  
   350  // IsEmpty returns true of none of the selection criteria is specified
   351  func (s Selector) IsEmpty() bool {
   352  	return s.APIVersion == "" &&
   353  		s.Namespace == "" &&
   354  		s.Name == "" &&
   355  		s.Kind == "" &&
   356  		len(s.Labels) == 0 &&
   357  		len(s.Annotations) == 0
   358  }
   359  
   360  // Inventory encapsulates the parameters for the inventory resource applied to a cluster.
   361  // All of the the parameters are required if any are set.
   362  type Inventory struct {
   363  	// Namespace for the inventory resource.
   364  	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
   365  	// Name of the inventory resource.
   366  	Name string `yaml:"name,omitempty" json:"name,omitempty"`
   367  	// Unique label to identify inventory resource in cluster.
   368  	InventoryID string            `yaml:"inventoryID,omitempty" json:"inventoryID,omitempty"`
   369  	Labels      map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
   370  	Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
   371  }
   372  
   373  func (i Inventory) IsValid() bool {
   374  	// Name, Namespace InventoryID are required inventory fields, so we check these 3 fields.
   375  	return i.Name != "" && i.Namespace != "" && i.InventoryID != ""
   376  }
   377  
   378  type Status struct {
   379  	Conditions []Condition `yaml:"conditions,omitempty" json:"conditions,omitempty"`
   380  }
   381  
   382  type Condition struct {
   383  	Type string `yaml:"type" json:"type"`
   384  
   385  	Status ConditionStatus `yaml:"status" json:"status"`
   386  
   387  	Reason string `yaml:"reason,omitempty" json:"reason,omitempty"`
   388  
   389  	Message string `yaml:"message,omitempty" json:"message,omitempty"`
   390  }
   391  
   392  type ConditionStatus string
   393  
   394  const (
   395  	ConditionTrue    ConditionStatus = "True"
   396  	ConditionFalse   ConditionStatus = "False"
   397  	ConditionUnknown ConditionStatus = "Unknown"
   398  )