...

Source file src/sigs.k8s.io/cli-utils/pkg/apply/filter/inventory-policy-apply-filter.go

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

     1  // Copyright 2021 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package filter
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    11  	"k8s.io/apimachinery/pkg/api/meta"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    14  	"k8s.io/client-go/dynamic"
    15  	"sigs.k8s.io/cli-utils/pkg/inventory"
    16  	"sigs.k8s.io/cli-utils/pkg/object"
    17  )
    18  
    19  // InventoryPolicyApplyFilter implements ValidationFilter interface to determine
    20  // if an object should be applied based on the cluster object's inventory id,
    21  // the id for the inventory object, and the inventory policy.
    22  type InventoryPolicyApplyFilter struct {
    23  	Client    dynamic.Interface
    24  	Mapper    meta.RESTMapper
    25  	Inv       inventory.Info
    26  	InvPolicy inventory.Policy
    27  }
    28  
    29  // Name returns a filter identifier for logging.
    30  func (ipaf InventoryPolicyApplyFilter) Name() string {
    31  	return "InventoryPolicyApplyFilter"
    32  }
    33  
    34  // Filter returns an inventory.PolicyPreventedActuationError if the object
    35  // apply should be skipped.
    36  func (ipaf InventoryPolicyApplyFilter) Filter(obj *unstructured.Unstructured) error {
    37  	// optimization to avoid unnecessary API calls
    38  	if ipaf.InvPolicy == inventory.PolicyAdoptAll {
    39  		return nil
    40  	}
    41  	// Object must be retrieved from the cluster to get the inventory id.
    42  	clusterObj, err := ipaf.getObject(object.UnstructuredToObjMetadata(obj))
    43  	if err != nil {
    44  		if apierrors.IsNotFound(err) {
    45  			// This simply means the object hasn't been created yet.
    46  			return nil
    47  		}
    48  		return NewFatalError(fmt.Errorf("failed to get current object from cluster: %w", err))
    49  	}
    50  	_, err = inventory.CanApply(ipaf.Inv, clusterObj, ipaf.InvPolicy)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	return nil
    55  }
    56  
    57  // getObject retrieves the passed object from the cluster, or an error if one occurred.
    58  func (ipaf InventoryPolicyApplyFilter) getObject(id object.ObjMetadata) (*unstructured.Unstructured, error) {
    59  	mapping, err := ipaf.Mapper.RESTMapping(id.GroupKind)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	namespacedClient, err := ipaf.Client.Resource(mapping.Resource).Namespace(id.Namespace), nil
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	return namespacedClient.Get(context.TODO(), id.Name, metav1.GetOptions{})
    68  }
    69  

View as plain text