github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/internal/errors/resolver/live.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 resolver
    16  
    17  import (
    18  	"fmt"
    19  
    20  	initialization "github.com/GoogleContainerTools/kpt/commands/live/init"
    21  	"github.com/GoogleContainerTools/kpt/internal/cmdutil"
    22  	"github.com/GoogleContainerTools/kpt/internal/errors"
    23  	"github.com/GoogleContainerTools/kpt/internal/pkg"
    24  	"github.com/GoogleContainerTools/kpt/pkg/live"
    25  	"sigs.k8s.io/cli-utils/pkg/inventory"
    26  	"sigs.k8s.io/cli-utils/pkg/manifestreader"
    27  	"sigs.k8s.io/cli-utils/pkg/print/common"
    28  )
    29  
    30  //nolint:gochecknoinits
    31  func init() {
    32  	AddErrorResolver(&liveErrorResolver{})
    33  }
    34  
    35  const (
    36  	noInventoryObjErrorMsg = `
    37  Error: Package uninitialized. Please run "kpt live init" command.
    38  
    39  The package needs to be initialized to generate the template
    40  which will store state for resource sets. This state is
    41  necessary to perform functionality such as deleting an entire
    42  package or automatically deleting omitted resources (pruning).
    43  `
    44  	multipleInventoryObjErrorMsg = `
    45  Error: Package has multiple inventory object templates.
    46  
    47  The package should have one and only one inventory object template.
    48  `
    49  
    50  	//nolint:lll
    51  	noResourceGroupCRDMsg = `
    52  Error: The ResourceGroup CRD was not found in the cluster. Please install it either by using the '--install-resource-group' flag or the 'kpt live install-resource-group' command.
    53  `
    54  
    55  	//nolint:lll
    56  	invInfoAlreadyExistsMsg = `
    57  Error: Inventory information has already been added to the package. Changing it after a package has been applied to the cluster can lead to undesired results. Use the --force flag to suppress this error.
    58  `
    59  
    60  	//nolint:lll
    61  	invInfoInRGAlreadyExistsMsg = `
    62  Error: Inventory information has already been added to the package ResourceGroup object. Changing it after a package has been applied to the cluster can lead to undesired results. Use the --force flag to suppress this error.
    63  `
    64  
    65  	//nolint:lll
    66  	invInfoInKfAlreadyExistsMsg = `
    67  Error: Inventory information has already been added to the package Kptfile object. Please consider migrating to a standalone resourcegroup object using the 'kpt live migrate' command.
    68  `
    69  
    70  	multipleResourceGroupsMsg = `
    71  Error: Multiple ResourceGroup objects found. Please make sure at most one ResourceGroup object exists within the package.
    72  `
    73  )
    74  
    75  // liveErrorResolver is an implementation of the ErrorResolver interface
    76  // that can resolve error types used in the live functionality.
    77  type liveErrorResolver struct{}
    78  
    79  func (*liveErrorResolver) Resolve(err error) (ResolvedResult, bool) {
    80  	var noInventoryObjError *inventory.NoInventoryObjError
    81  	if errors.As(err, &noInventoryObjError) {
    82  		msg := noInventoryObjErrorMsg
    83  		return ResolvedResult{Message: msg}, true
    84  	}
    85  
    86  	var multipleInventoryObjError *inventory.MultipleInventoryObjError
    87  	if errors.As(err, &multipleInventoryObjError) {
    88  		msg := multipleInventoryObjErrorMsg
    89  		return ResolvedResult{Message: msg}, true
    90  	}
    91  
    92  	var resourceGroupCRDInstallError *cmdutil.ResourceGroupCRDInstallError
    93  	if errors.As(err, &resourceGroupCRDInstallError) {
    94  		msg := "Error: Unable to install the ResourceGroup CRD."
    95  
    96  		cause := resourceGroupCRDInstallError.Err
    97  		msg += fmt.Sprintf("\nDetails: %v", cause)
    98  
    99  		return ResolvedResult{Message: msg}, true
   100  	}
   101  
   102  	var noResourceGroupCRDError *cmdutil.NoResourceGroupCRDError
   103  	if errors.As(err, &noResourceGroupCRDError) {
   104  		msg := noResourceGroupCRDMsg
   105  		return ResolvedResult{Message: msg}, true
   106  	}
   107  
   108  	var invExistsError *initialization.InvExistsError
   109  	if errors.As(err, &invExistsError) {
   110  		msg := invInfoAlreadyExistsMsg
   111  		return ResolvedResult{Message: msg}, true
   112  	}
   113  
   114  	var invInfoInRGAlreadyExistsError *initialization.InvInRGExistsError
   115  	if errors.As(err, &invInfoInRGAlreadyExistsError) {
   116  		msg := invInfoInRGAlreadyExistsMsg
   117  		return ResolvedResult{Message: msg}, true
   118  	}
   119  
   120  	var invInKfExistsError *initialization.InvInKfExistsError
   121  	if errors.As(err, &invInKfExistsError) {
   122  		msg := invInfoInKfAlreadyExistsMsg
   123  		return ResolvedResult{Message: msg}, true
   124  	}
   125  
   126  	var multipleResourceGroupsError *pkg.MultipleResourceGroupsError
   127  	if errors.As(err, &multipleResourceGroupsError) {
   128  		msg := multipleResourceGroupsMsg
   129  		return ResolvedResult{Message: msg}, true
   130  	}
   131  
   132  	var inventoryInfoValidationError *live.InventoryInfoValidationError
   133  	if errors.As(err, &inventoryInfoValidationError) {
   134  		msg := "Error: The inventory information is not valid."
   135  		msg += " Please update the information in the ResourceGroup file or provide information with the command line flags."
   136  		msg += " To generate the inventory information the first time, use the 'kpt live init' command."
   137  
   138  		msg += "\nDetails:\n"
   139  		for _, v := range inventoryInfoValidationError.Violations {
   140  			msg += fmt.Sprintf("%s\n", v.Reason)
   141  		}
   142  
   143  		return ResolvedResult{Message: msg}, true
   144  	}
   145  
   146  	var unknownTypesError *manifestreader.UnknownTypesError
   147  	if errors.As(err, &unknownTypesError) {
   148  		msg := fmt.Sprintf("Error: %d resource types could not be found in the cluster or as CRDs among the applied resources.", len(unknownTypesError.GroupVersionKinds))
   149  		msg += "\n\nResource types:\n"
   150  		for _, gvk := range unknownTypesError.GroupVersionKinds {
   151  			msg += fmt.Sprintf("%s\n", gvk)
   152  		}
   153  
   154  		return ResolvedResult{Message: msg}, true
   155  	}
   156  
   157  	var resultError *common.ResultError
   158  	if errors.As(err, &resultError) {
   159  		return ResolvedResult{
   160  			Message:  "", // Printer summary now replaces ResultError message
   161  			ExitCode: 3,
   162  		}, true
   163  	}
   164  
   165  	return ResolvedResult{}, false
   166  }