1 // Copyright 2020 The Kubernetes Authors. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package common 5 6 import ( 7 "fmt" 8 9 "k8s.io/apimachinery/pkg/util/rand" 10 cmdutil "k8s.io/kubectl/pkg/cmd/util" 11 ) 12 13 const ( 14 // InventoryLabel is the label stored on the ConfigMap 15 // inventory object. The value of the label is a unique 16 // identifier (by default a UUID), representing the set of 17 // objects applied at the same time as the inventory object. 18 // This inventory object is used for pruning and deletion. 19 InventoryLabel = "cli-utils.sigs.k8s.io/inventory-id" 20 // InventoryHash defines an annotation which stores the hash of 21 // the set of objects applied at the same time as the inventory 22 // object. This annotation is set on the inventory object at the 23 // time of the apply. The hash is computed from the sorted strings 24 // of the applied object's metadata (ObjMetadata). The hash is 25 // used as a suffix of the inventory object name. Example: 26 // inventory-1e5824fb 27 InventoryHash = "cli-utils.sigs.k8s.io/inventory-hash" 28 // Resource lifecycle annotation key for "on-remove" operations. 29 OnRemoveAnnotation = "cli-utils.sigs.k8s.io/on-remove" 30 // Resource lifecycle annotation value to prevent deletion. 31 OnRemoveKeep = "keep" 32 // Maximum random number, non-inclusive, eight digits. 33 maxRandInt = 100000000 34 // DefaultFieldManager is default owner of applied fields in 35 // server-side apply. 36 DefaultFieldManager = "kubectl" 37 38 // LifecycleDeletionAnnotation is the lifecycle annotation key for deletion operation. 39 LifecycleDeleteAnnotation = "client.lifecycle.config.k8s.io/deletion" 40 41 // PreventDeletion is the value used with LifecycleDeletionAnnotation 42 // to prevent deleting a resource. 43 PreventDeletion = "detach" 44 ) 45 46 // RandomStr returns an eight-digit (with leading zeros) string of a 47 // random number. 48 func RandomStr() string { 49 randomInt := rand.Intn(maxRandInt) // nolint:gosec 50 return fmt.Sprintf("%08d", randomInt) 51 } 52 53 // NoDeletion checks the passed in annotation key and value and returns 54 // true if that matches with the prevent deletion annotation. 55 func NoDeletion(key, value string) bool { 56 m := map[string]string{ 57 LifecycleDeleteAnnotation: PreventDeletion, 58 OnRemoveAnnotation: OnRemoveKeep, 59 } 60 if val, found := m[key]; found { 61 return val == value 62 } 63 return false 64 } 65 66 var Strategies = []DryRunStrategy{DryRunClient, DryRunServer} 67 68 //go:generate stringer -type=DryRunStrategy 69 type DryRunStrategy int 70 71 const ( 72 // DryRunNone indicates the client will make all mutating calls 73 DryRunNone DryRunStrategy = iota 74 75 // DryRunClient, or client-side dry-run, indicates the client will prevent 76 // making mutating calls such as CREATE, PATCH, and DELETE 77 DryRunClient 78 79 // DryRunServer, or server-side dry-run, indicates the client will send 80 // mutating calls to the APIServer with the dry-run parameter to prevent 81 // persisting changes. 82 // 83 // Note that clients sending server-side dry-run calls should verify that 84 // the APIServer and the resource supports server-side dry-run, and otherwise 85 // clients should fail early. 86 // 87 // If a client sends a server-side dry-run call to an APIServer that doesn't 88 // support server-side dry-run, then the APIServer will persist changes inadvertently. 89 DryRunServer 90 ) 91 92 // ClientDryRun returns true if input drs is DryRunClient 93 // 94 //nolint:stylecheck // Prevent lint errors on receiver names caused by string generation above 95 func (drs DryRunStrategy) ClientDryRun() bool { 96 return drs == DryRunClient 97 } 98 99 // ServerDryRun returns true if input drs is DryRunServer 100 func (drs DryRunStrategy) ServerDryRun() bool { 101 return drs == DryRunServer 102 } 103 104 // ClientOrServerDryRun returns true if input drs is either client or server dry run 105 func (drs DryRunStrategy) ClientOrServerDryRun() bool { 106 return drs == DryRunClient || drs == DryRunServer 107 } 108 109 // Strategy returns the 110 func (drs DryRunStrategy) Strategy() cmdutil.DryRunStrategy { 111 switch drs { 112 case DryRunClient: 113 return cmdutil.DryRunClient 114 case DryRunServer: 115 return cmdutil.DryRunServer 116 default: 117 return cmdutil.DryRunNone 118 } 119 } 120 121 // ServerSideOptions encapsulates the fields to implement server-side apply. 122 type ServerSideOptions struct { 123 // ServerSideApply means the merge patch is calculated on the API server instead of the client. 124 ServerSideApply bool 125 126 // ForceConflicts overwrites the fields when applying if the field manager differs. 127 ForceConflicts bool 128 129 // FieldManager identifies the client "owner" of the applied fields (e.g. kubectl) 130 FieldManager string 131 } 132