diff --git a/api/v1beta1/compassmanagermapping_types.go b/api/v1beta1/compassmanagermapping_types.go index ae3496d..c031b7b 100644 --- a/api/v1beta1/compassmanagermapping_types.go +++ b/api/v1beta1/compassmanagermapping_types.go @@ -18,8 +18,8 @@ type CompassManagerMapping struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec CompassManagerMappingSpec `json:"spec,omitempty"` Status CompassManagerMappingStatus `json:"status,omitempty"` + Spec CompassManagerMappingSpec `json:"spec,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 971a85c..36ecebd 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -14,8 +14,8 @@ func (in *CompassManagerMapping) DeepCopyInto(out *CompassManagerMapping) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec out.Status = in.Status + out.Spec = in.Spec } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CompassManagerMapping. diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 1aea135..0ba0d9c 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -4,5 +4,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: mvshao/compass-manager newTag: latest + newName: compass-manager diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 90f4605..8821f7e 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -30,6 +30,8 @@ rules: - delete - get - list + - update + - watch - apiGroups: - operator.kyma-project.io resources: diff --git a/controllers/compassmanager_controller.go b/controllers/compassmanager_controller.go index 39db60f..3633e91 100644 --- a/controllers/compassmanager_controller.go +++ b/controllers/compassmanager_controller.go @@ -23,16 +23,20 @@ import ( ) const ( - KymaNameLabel = "operator.kyma-project.io/kyma-name" - BrokerPlanIDLabel = "kyma-project.io/broker-plan-id" - BrokerPlanNameLabel = "kyma-project.io/broker-plan-name" - GlobalAccountIDLabel = "kyma-project.io/global-account-id" - BrokerInstanceIDLabel = "kyma-project.io/instance-id" - ShootNameLabel = "kyma-project.io/shoot-name" - SubaccountIDLabel = "kyma-project.io/subaccount-id" - ComppassIDLabel = "kyma-project.io/compass-runtime-id" - ManagedByLabel = "operator.kyma-project.io/managed-by" + AnnotationIDForMigration = "compass-runtime-id-for-migration" + + LabelBrokerInstanceID = "kyma-project.io/instance-id" + LabelBrokerPlanID = "kyma-project.io/broker-plan-id" + LabelBrokerPlanName = "kyma-project.io/broker-plan-name" + LabelComppassID = "kyma-project.io/compass-runtime-id" + LabelGlobalAccountID = "kyma-project.io/global-account-id" + LabelKymaName = "operator.kyma-project.io/kyma-name" + LabelManagedBy = "operator.kyma-project.io/managed-by" + LabelShootName = "kyma-project.io/shoot-name" + LabelSubaccountID = "kyma-project.io/subaccount-id" + ApplicationConnectorModuleName = "application-connector-module" + // KubeconfigKey is the name of the key in the secret storing cluster credentials. // The secret is created by KEB: https://github.com/kyma-project/control-plane/blob/main/components/kyma-environment-broker/internal/process/steps/lifecycle_manager_kubeconfig.go KubeconfigKey = "config" @@ -40,7 +44,7 @@ const ( //+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch //+kubebuilder:rbac:groups=operator.kyma-project.io,resources=kymas,verbs=get;list;watch -//+kubebuilder:rbac:groups=operator.kyma-project.io,resources=compassmanagermappings,verbs=create;get;list;delete +//+kubebuilder:rbac:groups=operator.kyma-project.io,resources=compassmanagermappings,verbs=create;get;list;delete;watch;update //+kubebuilder:rbac:groups=operator.kyma-project.io,resources=kymas/status,verbs=get //+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch @@ -103,10 +107,26 @@ func (cm *CompassManagerReconciler) Reconcile(ctx context.Context, req ctrl.Requ kymaLabels, err := cm.getKymaLabels(req.NamespacedName) if err != nil { cm.Log.Warnf("Failed to obtain labels from Kyma resource %s: %v.", req.Name, err) - return ctrl.Result{RequeueAfter: cm.requeueTime}, err + return ctrl.Result{}, err + } + + kymaAnnotations, err := cm.getKymaAnnotations(req.NamespacedName) + if err != nil { + cm.Log.Warnf("Failed to obtain annotations from Kyma resource %s: %v.", req.Name, err) + return ctrl.Result{}, err } compassRuntimeID, err := cm.getRuntimeIDFromCompassMapping(req.Name, req.Namespace) + + if migrationCompassRuntimeID, ok := kymaAnnotations[AnnotationIDForMigration]; compassRuntimeID == "" && ok { + cm.Log.Infof("Configuring compass for already registered Kyma resource %s.", req.Name) + cmerr := cm.upsertCompassMappingResource(migrationCompassRuntimeID, req.Namespace, kymaLabels) + if cmerr != nil { + return ctrl.Result{RequeueAfter: cm.requeueTime}, errors.Wrap(cmerr, "failed to create Compass Manager Mapping for an already registered Kyma") + } + return ctrl.Result{}, nil + } + if err != nil { return ctrl.Result{RequeueAfter: cm.requeueTime}, err } @@ -144,7 +164,7 @@ func (cm *CompassManagerReconciler) Reconcile(ctx context.Context, req ctrl.Requ func (cm *CompassManagerReconciler) getKubeconfig(kymaName string) (string, error) { secretList := &corev1.SecretList{} labelSelector := labels.SelectorFromSet(map[string]string{ - KymaNameLabel: kymaName, + LabelKymaName: kymaName, }) err := cm.Client.List(context.Background(), secretList, &client.ListOptions{ @@ -163,6 +183,22 @@ func (cm *CompassManagerReconciler) getKubeconfig(kymaName string) (string, erro return string(secret.Data[KubeconfigKey]), nil } +func (cm *CompassManagerReconciler) getKymaAnnotations(objKey types.NamespacedName) (map[string]string, error) { + instance := &kyma.Kyma{} + + err := cm.Client.Get(context.Background(), objKey, instance) + if err != nil { + return nil, err + } + + a := instance.GetAnnotations() + if a == nil { + a = make(map[string]string) + } + + return a, nil +} + func (cm *CompassManagerReconciler) getKymaLabels(objKey types.NamespacedName) (map[string]string, error) { instance := &kyma.Kyma{} @@ -180,17 +216,17 @@ func (cm *CompassManagerReconciler) getKymaLabels(objKey types.NamespacedName) ( } func (cm *CompassManagerReconciler) upsertCompassMappingResource(compassRuntimeID, namespace string, kymaLabels map[string]string) error { - kymaName := kymaLabels[KymaNameLabel] + kymaName := kymaLabels[LabelKymaName] compassMapping := &v1beta1.CompassManagerMapping{} compassMapping.Name = kymaName compassMapping.Namespace = namespace compassMappingLabels := make(map[string]string) - compassMappingLabels[KymaNameLabel] = kymaLabels[KymaNameLabel] - compassMappingLabels[ComppassIDLabel] = compassRuntimeID - compassMappingLabels[GlobalAccountIDLabel] = kymaLabels[GlobalAccountIDLabel] - compassMappingLabels[SubaccountIDLabel] = kymaLabels[SubaccountIDLabel] - compassMappingLabels[ManagedByLabel] = "compass-manager" + compassMappingLabels[LabelKymaName] = kymaLabels[LabelKymaName] + compassMappingLabels[LabelComppassID] = compassRuntimeID + compassMappingLabels[LabelGlobalAccountID] = kymaLabels[LabelGlobalAccountID] + compassMappingLabels[LabelSubaccountID] = kymaLabels[LabelSubaccountID] + compassMappingLabels[LabelManagedBy] = "compass-manager" compassMapping.SetLabels(compassMappingLabels) @@ -215,7 +251,7 @@ func (cm *CompassManagerReconciler) upsertCompassMappingResource(compassRuntimeI func (cm *CompassManagerReconciler) getRuntimeIDFromCompassMapping(kymaName string, namespace string) (string, error) { mappingList := &v1beta1.CompassManagerMappingList{} labelSelector := labels.SelectorFromSet(map[string]string{ - KymaNameLabel: kymaName, + LabelKymaName: kymaName, }) err := cm.Client.List(context.Background(), mappingList, &client.ListOptions{ @@ -231,7 +267,7 @@ func (cm *CompassManagerReconciler) getRuntimeIDFromCompassMapping(kymaName stri return "", nil } - return mappingList.Items[0].GetLabels()[ComppassIDLabel], nil + return mappingList.Items[0].GetLabels()[LabelComppassID], nil } // SetupWithManager sets up the controller with the Manager. @@ -287,12 +323,12 @@ func (cm *CompassManagerReconciler) needsToBeReconciled(obj runtime.Object) bool func createCompassRuntimeLabels(kymaLabels map[string]string) map[string]interface{} { runtimeLabels := make(map[string]interface{}) runtimeLabels["director_connection_managed_by"] = "compass-manager" - runtimeLabels["broker_instance_id"] = kymaLabels[BrokerInstanceIDLabel] - runtimeLabels["gardenerClusterName"] = kymaLabels[ShootNameLabel] - runtimeLabels["subaccount_id"] = kymaLabels[SubaccountIDLabel] - runtimeLabels["global_account_id"] = kymaLabels[GlobalAccountIDLabel] - runtimeLabels["broker_plan_id"] = kymaLabels[BrokerPlanIDLabel] - runtimeLabels["broker_plan_name"] = kymaLabels[BrokerPlanNameLabel] + runtimeLabels["broker_instance_id"] = kymaLabels[LabelBrokerInstanceID] + runtimeLabels["gardenerClusterName"] = kymaLabels[LabelShootName] + runtimeLabels["subaccount_id"] = kymaLabels[LabelSubaccountID] + runtimeLabels["global_account_id"] = kymaLabels[LabelGlobalAccountID] + runtimeLabels["broker_plan_id"] = kymaLabels[LabelBrokerPlanID] + runtimeLabels["broker_plan_name"] = kymaLabels[LabelBrokerPlanName] return runtimeLabels } diff --git a/controllers/compassmanager_controller_test.go b/controllers/compassmanager_controller_test.go index 5e571ce..e7876bd 100644 --- a/controllers/compassmanager_controller_test.go +++ b/controllers/compassmanager_controller_test.go @@ -27,6 +27,29 @@ var _ = Describe("Compass Manager controller", func() { kymaCustomResourceLabels := make(map[string]string) kymaCustomResourceLabels["operator.kyma-project.io/managed-by"] = "lifecycle-manager" + Context("Kyma was already registered, but doesn't have a Compass Mapping", func() { + It("creates the compass mapping without registering runtime again", func() { + const kymaName = "preregistered" + const preRegisteredID = "preregistered-id" + + secret := createCredentialsSecret(kymaName, kymaCustomResourceNamespace) + Expect(k8sClient.Create(context.Background(), &secret)).To(Succeed()) + + By("Create Kyma Resource") + kymaCR := createKymaResource(kymaName) + kymaCR.Annotations["compass-runtime-id-for-migration"] = preRegisteredID + Expect(k8sClient.Create(context.Background(), &kymaCR)).To(Succeed()) + + Eventually(func() string { + label, err := getCompassMappingCompassID(kymaCR.Name) + if err != nil { + return err.Error() + } + return label + }, clientTimeout, clientInterval).Should(Equal(preRegisteredID)) + }) + }) + Context("Secret with Kubeconfig is correctly created, and assigned to Kyma resource", func() { DescribeTable("Register Runtime in the Director, and configure Compass Runtime Agent", func(kymaName string) { By("Create secret with credentials") @@ -38,7 +61,7 @@ var _ = Describe("Compass Manager controller", func() { Expect(k8sClient.Create(context.Background(), &kymaCR)).To(Succeed()) Eventually(func() bool { - label, err := getCompassMappingLabel(kymaCR.Name, ComppassIDLabel, kymaCustomResourceNamespace) + label, err := getCompassMappingCompassID(kymaCR.Name) return err == nil && label != "" }, clientTimeout, clientInterval).Should(BeTrue()) @@ -57,7 +80,7 @@ var _ = Describe("Compass Manager controller", func() { Expect(k8sClient.Create(context.Background(), &kymaCR)).To(Succeed()) Consistently(func() bool { - label, err := getCompassMappingLabel(kymaCR.Name, ComppassIDLabel, kymaCustomResourceNamespace) + label, err := getCompassMappingCompassID(kymaCR.Name) return errors.IsNotFound(err) && label == "" }, clientTimeout, clientInterval).Should(BeTrue()) @@ -67,7 +90,7 @@ var _ = Describe("Compass Manager controller", func() { Expect(k8sClient.Create(context.Background(), &secret)).To(Succeed()) Eventually(func() bool { - label, err := getCompassMappingLabel(kymaCR.Name, ComppassIDLabel, kymaCustomResourceNamespace) + label, err := getCompassMappingCompassID(kymaCR.Name) return err == nil && label != "" }, clientTimeout, clientInterval).Should(BeTrue()) @@ -121,9 +144,9 @@ func createNamespace(name string) error { func createKymaResource(name string) kyma.Kyma { kymaCustomResourceLabels := make(map[string]string) - kymaCustomResourceLabels[GlobalAccountIDLabel] = "globalAccount" - kymaCustomResourceLabels[ShootNameLabel] = name - kymaCustomResourceLabels[KymaNameLabel] = name + kymaCustomResourceLabels[LabelGlobalAccountID] = "globalAccount" + kymaCustomResourceLabels[LabelShootName] = name + kymaCustomResourceLabels[LabelKymaName] = name kymaModules := make([]kyma.Module, 1) kymaModules[0].Name = ApplicationConnectorModuleName @@ -134,9 +157,10 @@ func createKymaResource(name string) kyma.Kyma { APIVersion: kymaCustomResourceAPIVersion, }, ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: kymaCustomResourceNamespace, - Labels: kymaCustomResourceLabels, + Name: name, + Namespace: kymaCustomResourceNamespace, + Labels: kymaCustomResourceLabels, + Annotations: make(map[string]string), }, Spec: kyma.KymaSpec{ Channel: "regular", @@ -160,9 +184,9 @@ func createCredentialsSecret(kymaName, namespace string) corev1.Secret { } } -func getCompassMappingLabel(kymaName, labelName, namespace string) (string, error) { +func getCompassMappingCompassID(kymaName string) (string, error) { var obj v1beta1.CompassManagerMapping - key := types.NamespacedName{Name: kymaName, Namespace: namespace} + key := types.NamespacedName{Name: kymaName, Namespace: kymaCustomResourceNamespace} err := cm.Client.Get(context.Background(), key, &obj) if err != nil { @@ -170,7 +194,7 @@ func getCompassMappingLabel(kymaName, labelName, namespace string) (string, erro } labels := obj.GetLabels() - return labels[labelName], nil + return labels[LabelComppassID], nil } // Feature (refreshing token) is implemented but according to our discussions, it will be a part of another PR diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 6f025b7..c6d69f0 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -115,11 +115,6 @@ var _ = AfterSuite(func() { }) func prepareMockFunctions(c *mocks.Configurator, r *mocks.Registrator) { - compassLabelsAllGood := createCompassRuntimeLabels(map[string]string{ShootNameLabel: "all-good", GlobalAccountIDLabel: "globalAccount"}) - compassLabelsConfigureFails := createCompassRuntimeLabels(map[string]string{ShootNameLabel: "configure-fails", GlobalAccountIDLabel: "globalAccount"}) - compassLabelsRegistrationFails := createCompassRuntimeLabels(map[string]string{ShootNameLabel: "registration-fails", GlobalAccountIDLabel: "globalAccount"}) - compassLabelsEmptyKubeconfig := createCompassRuntimeLabels(map[string]string{ShootNameLabel: "empty-kubeconfig", GlobalAccountIDLabel: "globalAccount"}) - // Feature (refreshing token) is implemented but according to our discussions, it will be a part of another PR // compassLabelsRefreshToken := createCompassRuntimeLabels(map[string]string{ShootNameLabel: "refresh-token", GlobalAccountIDLabel: "globalAccount"}) // refreshedToken := graphql.OneTimeTokenForRuntimeExt{ @@ -128,19 +123,31 @@ func prepareMockFunctions(c *mocks.Configurator, r *mocks.Registrator) { // RawEncoded: "rawEncodedToken", //} + // It handles `compass-runtime-id-for-migration` + compassLabelsRegistered := createCompassRuntimeLabels(map[string]string{LabelShootName: "preregistered", LabelGlobalAccountID: "globalAccount"}) + r.On("RegisterInCompass", compassLabelsRegistered).Return("id-preregistered-incorrect", nil) + // failing test case + c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-preregistered", "id-preregistered-incorrect").Return(nil) + // succeeding test case + c.On("ConfigureCompassRuntimeAgent", "id-preregistered-incorrect", "preregistered").Return(errors.New("This shouldn't be called")) + + compassLabelsAllGood := createCompassRuntimeLabels(map[string]string{LabelShootName: "all-good", LabelGlobalAccountID: "globalAccount"}) r.On("RegisterInCompass", compassLabelsAllGood).Return("id-all-good", nil) c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-all-good", "id-all-good").Return(nil) + compassLabelsConfigureFails := createCompassRuntimeLabels(map[string]string{LabelShootName: "configure-fails", LabelGlobalAccountID: "globalAccount"}) // The first call to ConfigureRuntimeAgent fails, but the second is successful r.On("RegisterInCompass", compassLabelsConfigureFails).Return("id-configure-fails", nil) c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-configure-fails", "id-configure-fails").Return(errors.New("error during configuration of Compass Runtime Agent CR")).Once() c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-configure-fails", "id-configure-fails").Return(nil).Once() + compassLabelsRegistrationFails := createCompassRuntimeLabels(map[string]string{LabelShootName: "registration-fails", LabelGlobalAccountID: "globalAccount"}) // The first call to RegisterInCompass fails, but the second is successful. r.On("RegisterInCompass", compassLabelsRegistrationFails).Return("", errors.New("error during registration")).Once() r.On("RegisterInCompass", compassLabelsRegistrationFails).Return("registration-fails", nil).Once() c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-registration-fails", "registration-fails").Return(nil) + compassLabelsEmptyKubeconfig := createCompassRuntimeLabels(map[string]string{LabelShootName: "empty-kubeconfig", LabelGlobalAccountID: "globalAccount"}) r.On("RegisterInCompass", compassLabelsEmptyKubeconfig).Return("id-empty-kubeconfig", nil) c.On("ConfigureCompassRuntimeAgent", "kubeconfig-data-empty-kubeconfig", "id-empty-kubeconfig").Return(nil) diff --git a/go.mod b/go.mod index 4bacb3a..881695c 100644 --- a/go.mod +++ b/go.mod @@ -107,13 +107,13 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.9.3 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index 0a75c38..69f9d9f 100644 --- a/go.sum +++ b/go.sum @@ -572,8 +572,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -624,8 +624,8 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -677,14 +677,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -693,8 +693,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=