github.com/GoogleContainerTools/skaffold/v2@v2.13.2/pkg/diag/validator/config_connector.go (about) 1 /* 2 Copyright 2021 The Skaffold Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package validator 18 19 import ( 20 "context" 21 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 24 "k8s.io/apimachinery/pkg/runtime/schema" 25 "k8s.io/client-go/dynamic" 26 "k8s.io/client-go/kubernetes" 27 kstatus "sigs.k8s.io/cli-utils/pkg/kstatus/status" 28 29 "github.com/GoogleContainerTools/skaffold/v2/proto/v1" 30 ) 31 32 var _ Validator = (*ConfigConnectorValidator)(nil) 33 34 // ConfigConnectorValidator implements the Validator interface for Config Connector resources 35 type ConfigConnectorValidator struct { 36 resourceSelector *CustomResourceSelector 37 } 38 39 // NewConfigConnectorValidator initializes a ConfigConnectorValidator 40 func NewConfigConnectorValidator(k kubernetes.Interface, d dynamic.Interface, gvk schema.GroupVersionKind) *ConfigConnectorValidator { 41 return &ConfigConnectorValidator{resourceSelector: NewCustomResourceSelector(k, d, gvk)} 42 } 43 44 // Validate implements the Validate method for Validator interface 45 func (ccv *ConfigConnectorValidator) Validate(ctx context.Context, ns string, opts metav1.ListOptions) ([]Resource, error) { 46 resources, err := ccv.resourceSelector.Select(ctx, ns, opts) 47 if err != nil { 48 return []Resource{}, err 49 } 50 var rs []Resource 51 for _, r := range resources.Items { 52 status, ae := getConfigConnectorStatus(r) 53 // TODO: add recommendations from error codes 54 // TODO: add resource logs 55 rs = append(rs, NewResourceFromObject(&r, Status(status), ae, nil)) 56 } 57 return rs, nil 58 } 59 60 func getConfigConnectorStatus(res unstructured.Unstructured) (kstatus.Status, *proto.ActionableErr) { 61 result, err := kstatus.Compute(&res) 62 if err != nil || result == nil { 63 return kstatus.UnknownStatus, &proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: "unable to check resource status"} 64 } 65 var ae proto.ActionableErr 66 switch result.Status { 67 case kstatus.CurrentStatus: 68 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS} 69 case kstatus.InProgressStatus: 70 // TODO: config connector resource status doesn't distinguish between resource that is making progress towards reconciling from one that is doomed. 71 // This is tracked in b/187759279 internally. As such to avoid stalling the status check phase until timeout in case of a failed resource, 72 // we report an error if there's any message reported without the status being success. This can cause skaffold to fail even when resources 73 // are rightly in an InProgress state, say while adding new nodes. 74 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_CONFIG_CONNECTOR_IN_PROGRESS, Message: result.Message} 75 case kstatus.FailedStatus: 76 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_CONFIG_CONNECTOR_FAILED, Message: result.Message} 77 case kstatus.TerminatingStatus: 78 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_CONFIG_CONNECTOR_TERMINATING, Message: result.Message} 79 case kstatus.NotFoundStatus: 80 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_CONFIG_CONNECTOR_NOT_FOUND, Message: result.Message} 81 case kstatus.UnknownStatus: 82 ae = proto.ActionableErr{ErrCode: proto.StatusCode_STATUSCHECK_UNKNOWN, Message: result.Message} 83 } 84 return result.Status, &ae 85 }