...

Source file src/sigs.k8s.io/cli-utils/pkg/apply/task/inv_add_task.go

Documentation: sigs.k8s.io/cli-utils/pkg/apply/task

     1  // Copyright 2021 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package task
     5  
     6  import (
     7  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
     8  	"k8s.io/apimachinery/pkg/runtime/schema"
     9  	"k8s.io/klog/v2"
    10  	"sigs.k8s.io/cli-utils/pkg/apply/event"
    11  	"sigs.k8s.io/cli-utils/pkg/apply/taskrunner"
    12  	"sigs.k8s.io/cli-utils/pkg/common"
    13  	"sigs.k8s.io/cli-utils/pkg/inventory"
    14  	"sigs.k8s.io/cli-utils/pkg/object"
    15  )
    16  
    17  var (
    18  	namespaceGVKv1 = schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"}
    19  )
    20  
    21  // InvAddTask encapsulates structures necessary to add/merge inventory
    22  // into the cluster. The InvAddTask should add/merge inventory references
    23  // before the actual object is applied.
    24  type InvAddTask struct {
    25  	TaskName  string
    26  	InvClient inventory.Client
    27  	InvInfo   inventory.Info
    28  	Objects   object.UnstructuredSet
    29  	DryRun    common.DryRunStrategy
    30  }
    31  
    32  func (i *InvAddTask) Name() string {
    33  	return i.TaskName
    34  }
    35  
    36  func (i *InvAddTask) Action() event.ResourceAction {
    37  	return event.InventoryAction
    38  }
    39  
    40  func (i *InvAddTask) Identifiers() object.ObjMetadataSet {
    41  	return object.UnstructuredSetToObjMetadataSet(i.Objects)
    42  }
    43  
    44  // Start updates the inventory by merging the locally applied objects
    45  // into the current inventory.
    46  func (i *InvAddTask) Start(taskContext *taskrunner.TaskContext) {
    47  	go func() {
    48  		klog.V(2).Infof("inventory add task starting (name: %q)", i.Name())
    49  		if err := inventory.ValidateNoInventory(i.Objects); err != nil {
    50  			i.sendTaskResult(taskContext, err)
    51  			return
    52  		}
    53  		// Ensures the namespace exists before applying the inventory object into it.
    54  		if invNamespace := inventoryNamespaceInSet(i.InvInfo, i.Objects); invNamespace != nil {
    55  			klog.V(4).Infof("applying inventory namespace %s", invNamespace.GetName())
    56  			if err := i.InvClient.ApplyInventoryNamespace(invNamespace, i.DryRun); err != nil {
    57  				i.sendTaskResult(taskContext, err)
    58  				return
    59  			}
    60  		}
    61  		klog.V(4).Infof("merging %d local objects into inventory", len(i.Objects))
    62  		currentObjs := object.UnstructuredSetToObjMetadataSet(i.Objects)
    63  		_, err := i.InvClient.Merge(i.InvInfo, currentObjs, i.DryRun)
    64  		i.sendTaskResult(taskContext, err)
    65  	}()
    66  }
    67  
    68  // Cancel is not supported by the InvAddTask.
    69  func (i *InvAddTask) Cancel(_ *taskrunner.TaskContext) {}
    70  
    71  // StatusUpdate is not supported by the InvAddTask.
    72  func (i *InvAddTask) StatusUpdate(_ *taskrunner.TaskContext, _ object.ObjMetadata) {}
    73  
    74  // inventoryNamespaceInSet returns the the namespace the passed inventory
    75  // object will be applied to, or nil if this namespace object does not exist
    76  // in the passed slice "infos" or the inventory object is cluster-scoped.
    77  func inventoryNamespaceInSet(inv inventory.Info, objs object.UnstructuredSet) *unstructured.Unstructured {
    78  	if inv == nil {
    79  		return nil
    80  	}
    81  	invNamespace := inv.Namespace()
    82  
    83  	for _, obj := range objs {
    84  		gvk := obj.GetObjectKind().GroupVersionKind()
    85  		if gvk == namespaceGVKv1 && obj.GetName() == invNamespace {
    86  			inventory.AddInventoryIDAnnotation(obj, inv)
    87  			return obj
    88  		}
    89  	}
    90  	return nil
    91  }
    92  
    93  func (i *InvAddTask) sendTaskResult(taskContext *taskrunner.TaskContext, err error) {
    94  	klog.V(2).Infof("inventory add task completing (name: %q)", i.Name())
    95  	taskContext.TaskChannel() <- taskrunner.TaskResult{
    96  		Err: err,
    97  	}
    98  }
    99  

View as plain text