github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/pkg/live/apply-crd-task.go (about) 1 // Copyright 2021 Google LLC 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 live 16 17 import ( 18 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 19 "k8s.io/cli-runtime/pkg/resource" 20 cmdutil "k8s.io/kubectl/pkg/cmd/util" 21 "k8s.io/kubectl/pkg/util" 22 "sigs.k8s.io/cli-utils/pkg/apply/event" 23 "sigs.k8s.io/cli-utils/pkg/apply/taskrunner" 24 "sigs.k8s.io/cli-utils/pkg/object" 25 ) 26 27 // ApplyCRDTask encapsulates information necessary to apply a 28 // Custom Resource Definition (CRD) as a task within a task queue. 29 // Implements the Task interface. 30 type ApplyCRDTask struct { 31 factory cmdutil.Factory 32 crd *unstructured.Unstructured 33 } 34 35 func (a *ApplyCRDTask) Name() string { 36 return "apply-rg-crd" 37 } 38 39 func (a *ApplyCRDTask) Action() event.ResourceAction { 40 return event.ApplyAction 41 } 42 43 func (a *ApplyCRDTask) Identifiers() object.ObjMetadataSet { 44 return object.UnstructuredSetToObjMetadataSet([]*unstructured.Unstructured{a.crd}) 45 } 46 47 // NewApplyCRDTask returns a pointer to an ApplyCRDTask struct, 48 // containing fields to run the task. 49 func NewApplyCRDTask(factory cmdutil.Factory, crd *unstructured.Unstructured) *ApplyCRDTask { 50 return &ApplyCRDTask{ 51 factory: factory, 52 crd: crd, 53 } 54 } 55 56 // Start function is called to start the task running. 57 func (a *ApplyCRDTask) Start(taskContext *taskrunner.TaskContext) { 58 go func() { 59 mapper, err := a.factory.ToRESTMapper() 60 if err != nil { 61 taskContext.TaskChannel() <- taskrunner.TaskResult{Err: err} 62 return 63 } 64 mapping, err := mapper.RESTMapping(crdGroupKind) 65 if err != nil { 66 taskContext.TaskChannel() <- taskrunner.TaskResult{Err: err} 67 return 68 } 69 client, err := a.factory.UnstructuredClientForMapping(mapping) 70 if err != nil { 71 taskContext.TaskChannel() <- taskrunner.TaskResult{Err: err} 72 return 73 } 74 // Set the "last-applied-annotation" so future applies work correctly. 75 if err := util.CreateApplyAnnotation(a.crd, unstructured.UnstructuredJSONScheme); err != nil { 76 taskContext.TaskChannel() <- taskrunner.TaskResult{Err: err} 77 return 78 } 79 // Apply the CRD to the cluster and ignore already exists error. 80 var clearResourceVersion = false 81 var emptyNamespace = "" 82 helper := resource.NewHelper(client, mapping) 83 _, err = helper.Create(emptyNamespace, clearResourceVersion, a.crd) 84 if err != nil { 85 taskContext.TaskChannel() <- taskrunner.TaskResult{Err: err} 86 return 87 } 88 taskContext.TaskChannel() <- taskrunner.TaskResult{} 89 }() 90 } 91 92 func (a *ApplyCRDTask) Cancel(_ *taskrunner.TaskContext) {} 93 94 func (a *ApplyCRDTask) StatusUpdate(_ *taskrunner.TaskContext, _ object.ObjMetadata) {}