From 5b2f898c41b2ff38f53ce11841ac4492438ce53b Mon Sep 17 00:00:00 2001 From: HeeSeung Date: Sun, 31 Dec 2023 09:07:57 +0900 Subject: [PATCH] =?UTF-8?q?Aviator=20Service=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99=20(#22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NCP Service CRUD 기능 Reconcile func 연동 * refactor: ProvisonSpec 필드 추상화, Status에 ProvisionPhase 추가 * refactor: ncpService Reconciler 객체에 포함시켜 초기화, Verb에서 Provision Status Phase 필드 기반으로 Action 수행하도록 수정 * fix: typo --------- Co-authored-by: 희승 --- api/v1/provision_types.go | 64 +++++++-- api/v1/zz_generated.deepcopy.go | 48 +++++++ config/crd/bases/vm.cloudclub.io_data.yaml | 49 +++++++ .../vm.cloudclub.io_operatingsystems.yaml | 49 +++++++ config/crd/bases/vm.cloudclub.io_plans.yaml | 49 +++++++ .../crd/bases/vm.cloudclub.io_provisions.yaml | 123 ++++++++++++++++++ config/rbac/role.yaml | 115 ++++++++++++++-- config/samples/vm_v1_provision.yaml | 1 - go.mod | 26 ++-- go.sum | 54 ++++++++ internal/controller/constants.go | 9 ++ internal/controller/provision_controller.go | 80 +++++++++++- 12 files changed, 635 insertions(+), 32 deletions(-) create mode 100644 config/crd/bases/vm.cloudclub.io_data.yaml create mode 100644 config/crd/bases/vm.cloudclub.io_operatingsystems.yaml create mode 100644 config/crd/bases/vm.cloudclub.io_plans.yaml create mode 100644 config/crd/bases/vm.cloudclub.io_provisions.yaml create mode 100644 internal/controller/constants.go diff --git a/api/v1/provision_types.go b/api/v1/provision_types.go index 3f45b10..df7f5e4 100644 --- a/api/v1/provision_types.go +++ b/api/v1/provision_types.go @@ -20,22 +20,68 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +type Server struct { + CreateCount int `json:"serverCreateCount,omitempty"` + CreateStartNo int `json:"serverCreateStartNo,omitempty"` + Description string `json:"serverDescription,omitempty"` + ImageNo string `json:"serverImageNo,omitempty"` + ImageProductCode string `json:"serverImageProductCode,omitempty"` + Name string `json:"serverName,omitempty"` + ProductCode string `json:"serverProductCode,omitempty"` + SpecCode string `json:"serverSpecCode,omitempty"` +} + +type BlockStorageMapping struct { + BlockStorageName string `json:"blockStorageMappingBlockStorageName,omitempty"` + BlockStorageSize string `json:"blockStorageMappingBlockStorageSize,omitempty"` + BlockStorageVolumeTypeCode string `json:"blockStorageMappingBlockStorageVolumeTypeCode,omitempty"` + Encrypted string `json:"blockStorageMappingEncrypted,omitempty"` + Order int `json:"blockStorageMappingList,omitempty"` + SnapshotInstanceNo string `json:"blockStorageMappingSnapshotInstanceNo,omitempty"` +} + +type NetworkInterface struct { + IP string `json:"networkInterfaceIp,omitempty"` + No string `json:"networkInterfaceNo,omitempty"` + Order int `json:"networkInterfaceList,omitempty"` + SubnetNo string `json:"networkInterfaceSubnetNo,omitempty"` +} // ProvisionSpec defines the desired state of Provision type ProvisionSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Foo is an example field of Provision. Edit provision_types.go to remove/update - Foo string `json:"foo,omitempty"` + AccessControlGroupNoListN string `json:"accessControlGroupNoList,omitempty"` + AssociateWithPublicIp bool `json:"associateWithPublicIp,omitempty"` + BlockDevicePartitionMountPoint string `json:"blockDevicePartitionMountPoint,omitempty"` + BlockDevicePartitionSize string `json:"blockDevicePartitionSize,omitempty"` + FeeSystemTypeCode string `json:"feeSystemTypeCode,omitempty"` + InitScriptNo string `json:"initScriptNo,omitempty"` + IsEncryptedBaseBlockStorageVolume bool `json:"isEncryptedBaseBlockStorageVolume,omitempty"` + IsProtectServerTermination bool `json:"isProtectServerTermination,omitempty"` + LoginKeyName string `json:"loginKeyName,omitempty"` + MemberServerImageInstanceNo string `json:"memberServerImageInstanceNo,omitempty"` + PlacementGroupNo string `json:"placementGroupNo,omitempty"` + RAIDTypeName string `json:"raidTypeName,omitempty"` + ResponseFormatType string `json:"responseFormatType,omitempty"` + SubnetNo string `json:"subnetNo,omitempty"` + VpcNo string `json:"vpcNo,omitempty"` + Server Server `json:"server,omitempty"` + BlockStorageMapping BlockStorageMapping `json:"blockStorageMapping,omitempty"` + NetworkInterface NetworkInterface `json:"networkInterface,omitempty"` } +type ProvisionPhase string + +const ( + ProvisionPhaseCreate ProvisionPhase = "Create" + ProvisionPhaseUpdate ProvisionPhase = "Update" + ProvisionPhaseStop ProvisionPhase = "Stop" + ProvisionPhaseDelete ProvisionPhase = "Delete" + ProvisionPhaseGet ProvisionPhase = "Get" +) + // ProvisionStatus defines the observed state of Provision type ProvisionStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + Phase ProvisionPhase `json:"phase,omitempty"` } //+kubebuilder:object:root=true diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 147b76a..5df0c3c 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -24,6 +24,21 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BlockStorageMapping) DeepCopyInto(out *BlockStorageMapping) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlockStorageMapping. +func (in *BlockStorageMapping) DeepCopy() *BlockStorageMapping { + if in == nil { + return nil + } + out := new(BlockStorageMapping) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Data) DeepCopyInto(out *Data) { *out = *in @@ -113,6 +128,21 @@ func (in *DataStatus) DeepCopy() *DataStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkInterface) DeepCopyInto(out *NetworkInterface) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkInterface. +func (in *NetworkInterface) DeepCopy() *NetworkInterface { + if in == nil { + return nil + } + out := new(NetworkInterface) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Operatingsystems) DeepCopyInto(out *Operatingsystems) { *out = *in @@ -353,6 +383,9 @@ func (in *ProvisionList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProvisionSpec) DeepCopyInto(out *ProvisionSpec) { *out = *in + out.Server = in.Server + out.BlockStorageMapping = in.BlockStorageMapping + out.NetworkInterface = in.NetworkInterface } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisionSpec. @@ -379,3 +412,18 @@ func (in *ProvisionStatus) DeepCopy() *ProvisionStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Server) DeepCopyInto(out *Server) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Server. +func (in *Server) DeepCopy() *Server { + if in == nil { + return nil + } + out := new(Server) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/vm.cloudclub.io_data.yaml b/config/crd/bases/vm.cloudclub.io_data.yaml new file mode 100644 index 0000000..57786f6 --- /dev/null +++ b/config/crd/bases/vm.cloudclub.io_data.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: data.vm.cloudclub.io +spec: + group: vm.cloudclub.io + names: + kind: Data + listKind: DataList + plural: data + singular: data + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Data is the Schema for the data API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DataSpec defines the desired state of Data + properties: + foo: + description: Foo is an example field of Data. Edit data_types.go to + remove/update + type: string + type: object + status: + description: DataStatus defines the observed state of Data + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/vm.cloudclub.io_operatingsystems.yaml b/config/crd/bases/vm.cloudclub.io_operatingsystems.yaml new file mode 100644 index 0000000..4ff7636 --- /dev/null +++ b/config/crd/bases/vm.cloudclub.io_operatingsystems.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: operatingsystems.vm.cloudclub.io +spec: + group: vm.cloudclub.io + names: + kind: Operatingsystems + listKind: OperatingsystemsList + plural: operatingsystems + singular: operatingsystems + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Operatingsystems is the Schema for the operatingsystems API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: OperatingsystemsSpec defines the desired state of Operatingsystems + properties: + foo: + description: Foo is an example field of Operatingsystems. Edit operatingsystems_types.go + to remove/update + type: string + type: object + status: + description: OperatingsystemsStatus defines the observed state of Operatingsystems + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/vm.cloudclub.io_plans.yaml b/config/crd/bases/vm.cloudclub.io_plans.yaml new file mode 100644 index 0000000..7c98c52 --- /dev/null +++ b/config/crd/bases/vm.cloudclub.io_plans.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: plans.vm.cloudclub.io +spec: + group: vm.cloudclub.io + names: + kind: Plan + listKind: PlanList + plural: plans + singular: plan + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Plan is the Schema for the plans API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PlanSpec defines the desired state of Plan + properties: + foo: + description: Foo is an example field of Plan. Edit plan_types.go to + remove/update + type: string + type: object + status: + description: PlanStatus defines the observed state of Plan + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/vm.cloudclub.io_provisions.yaml b/config/crd/bases/vm.cloudclub.io_provisions.yaml new file mode 100644 index 0000000..dc672d2 --- /dev/null +++ b/config/crd/bases/vm.cloudclub.io_provisions.yaml @@ -0,0 +1,123 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: provisions.vm.cloudclub.io +spec: + group: vm.cloudclub.io + names: + kind: Provision + listKind: ProvisionList + plural: provisions + singular: provision + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Provision is the Schema for the provisions API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ProvisionSpec defines the desired state of Provision + properties: + accessControlGroupNoList: + type: string + associateWithPublicIp: + type: boolean + blockDevicePartitionMountPoint: + type: string + blockDevicePartitionSize: + type: string + blockStorageMapping: + properties: + blockStorageMappingBlockStorageName: + type: string + blockStorageMappingBlockStorageSize: + type: string + blockStorageMappingBlockStorageVolumeTypeCode: + type: string + blockStorageMappingEncrypted: + type: string + blockStorageMappingList: + type: integer + blockStorageMappingSnapshotInstanceNo: + type: string + type: object + feeSystemTypeCode: + type: string + initScriptNo: + type: string + isEncryptedBaseBlockStorageVolume: + type: boolean + isProtectServerTermination: + type: boolean + loginKeyName: + type: string + memberServerImageInstanceNo: + type: string + networkInterface: + properties: + networkInterfaceIp: + type: string + networkInterfaceList: + type: integer + networkInterfaceNo: + type: string + networkInterfaceSubnetNo: + type: string + type: object + placementGroupNo: + type: string + raidTypeName: + type: string + responseFormatType: + type: string + server: + properties: + serverCreateCount: + type: integer + serverCreateStartNo: + type: integer + serverDescription: + type: string + serverImageNo: + type: string + serverImageProductCode: + type: string + serverName: + type: string + serverProductCode: + type: string + serverSpecCode: + type: string + type: object + subnetNo: + type: string + vpcNo: + type: string + type: object + status: + description: ProvisionStatus defines the observed state of Provision + properties: + phase: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index b47bc4c..03c6218 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -1,15 +1,110 @@ +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: manager-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: aviator - app.kubernetes.io/part-of: aviator - app.kubernetes.io/managed-by: kustomize name: manager-role rules: -- apiGroups: [""] - resources: ["pods"] - verbs: ["get", "list", "watch"] +- apiGroups: + - vm.cloudclub.io + resources: + - data + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - vm.cloudclub.io + resources: + - data/finalizers + verbs: + - update +- apiGroups: + - vm.cloudclub.io + resources: + - data/status + verbs: + - get + - patch + - update +- apiGroups: + - vm.cloudclub.io + resources: + - operatingsystems + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - vm.cloudclub.io + resources: + - operatingsystems/finalizers + verbs: + - update +- apiGroups: + - vm.cloudclub.io + resources: + - operatingsystems/status + verbs: + - get + - patch + - update +- apiGroups: + - vm.cloudclub.io + resources: + - plans + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - vm.cloudclub.io + resources: + - plans/finalizers + verbs: + - update +- apiGroups: + - vm.cloudclub.io + resources: + - plans/status + verbs: + - get + - patch + - update +- apiGroups: + - vm.cloudclub.io + resources: + - provisions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - vm.cloudclub.io + resources: + - provisions/finalizers + verbs: + - update +- apiGroups: + - vm.cloudclub.io + resources: + - provisions/status + verbs: + - get + - patch + - update diff --git a/config/samples/vm_v1_provision.yaml b/config/samples/vm_v1_provision.yaml index c567105..e5a20a2 100644 --- a/config/samples/vm_v1_provision.yaml +++ b/config/samples/vm_v1_provision.yaml @@ -9,4 +9,3 @@ metadata: app.kubernetes.io/created-by: aviator name: provision-sample spec: - # TODO(user): Add fields here diff --git a/go.mod b/go.mod index c1fface..1c26f77 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,27 @@ module vm.cloudclub.io -go 1.20 +go 1.21.1 + +toolchain go1.21.4 require ( + github.com/cloud-club/Aviator-service v0.0.0-20231217151335-e0cb2c2047aa + github.com/googleapis/gax-go/v2 v2.12.0 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.10 + github.com/sirupsen/logrus v1.9.0 + google.golang.org/appengine v1.6.7 k8s.io/apimachinery v0.28.3 k8s.io/client-go v0.28.3 sigs.k8s.io/controller-runtime v0.16.3 ) require ( + github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -48,16 +56,18 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/net v0.18.0 // indirect golang.org/x/oauth2 v0.8.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/sys v0.14.0 // indirect + golang.org/x/term v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.9.3 // indirect + golang.org/x/tools v0.15.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/api v0.128.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.56.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 8e8882f..5a42536 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,6 @@ +github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8 h1:rwRvTaHutTdU/cacsKeY6E6yWwnSXCzRbPZaCOSfCks= +github.com/NaverCloudPlatform/ncloud-sdk-go-v2 v1.6.8/go.mod h1:jRp8KZ64MUevBWNqehghhG2oF5/JU3Dmt/Cu7dp1mQE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -7,10 +10,14 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cloud-club/Aviator-service v0.0.0-20231217151335-e0cb2c2047aa h1:yxnDcrG3jNDkeKzg85L8rmrUt1/6yo7MVJadKjNUSFg= +github.com/cloud-club/Aviator-service v0.0.0-20231217151335-e0cb2c2047aa/go.mod h1:cxKHHT+qtSSe3wItn+bOn/1Qlg6ZYLPupaV+cvz8XUs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU= +github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= @@ -52,6 +59,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -98,6 +107,8 @@ github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -113,6 +124,7 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= @@ -125,12 +137,16 @@ go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -138,9 +154,15 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +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/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -148,6 +170,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -155,17 +179,35 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.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/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +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/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -174,20 +216,32 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg= +google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/internal/controller/constants.go b/internal/controller/constants.go new file mode 100644 index 0000000..7875540 --- /dev/null +++ b/internal/controller/constants.go @@ -0,0 +1,9 @@ +package controller + +const ( + apiUrlCreate = "https://ncloud.apigw.ntruss.com/vserver/v2/createServerInstances" + apiUrlDelete = "https://ncloud.apigw.ntruss.com/vserver/v2/terminateServerInstances" + apiUrlGet = "https://ncloud.apigw.ntruss.com/vserver/v2/getMemberServerImageInstanceList" + apiUrlStop = "https://ncloud.apigw.ntruss.com/vserver/v2/stopServerInstances" + apiUrlUpdate = "https://ncloud.apigw.ntruss.com/vserver/v2/changeServerInstanceSpec" +) diff --git a/internal/controller/provision_controller.go b/internal/controller/provision_controller.go index 15956ee..da568e8 100644 --- a/internal/controller/provision_controller.go +++ b/internal/controller/provision_controller.go @@ -19,18 +19,34 @@ package controller import ( "context" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + ncputil "github.com/cloud-club/Aviator-service/pkg" + vmv1 "vm.cloudclub.io/api/v1" ) // ProvisionReconciler reconciles a Provision object type ProvisionReconciler struct { client.Client - Scheme *runtime.Scheme + Scheme *runtime.Scheme + ncpService *ncputil.NcpService +} + +func NewProvisionReconciler( + client client.Client, + scheme *runtime.Scheme, + ncpService *ncputil.NcpService, +) *ProvisionReconciler { + return &ProvisionReconciler{ + Client: client, + Scheme: scheme, + ncpService: ncpService, + } } //+kubebuilder:rbac:groups=vm.cloudclub.io,resources=provisions,verbs=get;list;watch;create;update;patch;delete @@ -47,14 +63,70 @@ type ProvisionReconciler struct { // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.3/pkg/reconcile func (r *ProvisionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) + log := log.FromContext(ctx) + + log.V(0).Info("Reconciling Provision request", "Request", req) + + original := &vmv1.Provision{} + err := r.Get(ctx, req.NamespacedName, original) + if err != nil { + if errors.IsNotFound(err) { + log.V(0).Info("Provision resource not found. Ignoring reconciliation.") + return ctrl.Result{}, nil + } + log.Error(err, "Failed to get Provision resource") + return ctrl.Result{}, err + } - // TODO(user): your logic here + switch original.Status.Phase { + case "", vmv1.ProvisionPhaseCreate: + log.V(0).Info("Creating a new VM") + // create + err := r.ncpService.Server.Create(apiUrlCreate) + if err != nil { + log.Error(err, "Failed to create VM") + return ctrl.Result{}, err + } + case vmv1.ProvisionPhaseUpdate: + // update + log.V(0).Info("Updating an existing VM") + err := r.ncpService.Server.Update(apiUrlUpdate) + if err != nil { + log.Error(err, "Failed to update VM") + return ctrl.Result{}, err + } + case vmv1.ProvisionPhaseStop: + // delete + log.V(0).Info("Stopping an existing VM") + err := r.ncpService.Server.Stop(apiUrlDelete) + if err != nil { + log.Error(err, "Failed to stop VM") + return ctrl.Result{}, err + } + case vmv1.ProvisionPhaseDelete: + // delete + log.V(0).Info("Deleting an existing VM") + err := r.ncpService.Server.Delete(apiUrlDelete) + if err != nil { + log.Error(err, "Failed to delete VM") + return ctrl.Result{}, err + } + case vmv1.ProvisionPhaseGet: + // get info + log.V(0).Info("Getting information for an existing VM") + err := r.ncpService.Server.Get(apiUrlGet) + if err != nil { + log.Error(err, "Failed to get VM information") + return ctrl.Result{}, err + } + default: + log.V(0).Info("No action defined for the current phase") + } return ctrl.Result{}, nil } -// SetupWithManager sets up the controller with the Manager. +// SetupWithManager sets up the controller with the Manager. func (r *ProvisionReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&vmv1.Provision{}).