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