diff --git a/.gitattributes b/.gitattributes index bb041251..4dd16e86 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,3 +3,4 @@ config/crd/bases/*.yaml binary zz_generated_deepcopy.go binary apps/releases/assets/operators/** binary +*.pb.go binary diff --git a/agent/internal/env/env.go b/agent/internal/env/env.go index 0f358822..297deb71 100644 --- a/agent/internal/env/env.go +++ b/agent/internal/env/env.go @@ -5,15 +5,6 @@ import ( ) type Env struct { - // KafkaSASLUser string `env:"KAFKA_SASL_USER" required:"true"` - // KafkaSASLPassword string `env:"KAFKA_SASL_PASSWORD" required:"true"` - // KafkaSASLMechanism redpanda.SASLMechanism `env:"KAFKA_SASL_MECHANISM"` - - // KafkaBrokers string `env:"KAFKA_BROKERS" required:"true"` - // KafkaConsumerGroupId string `env:"KAFKA_CONSUMER_GROUP_ID" required:"true"` - // KafkaIncomingTopic string `env:"KAFKA_INCOMING_TOPIC" required:"true"` - // KafkaErrorOnApplyTopic string `env:"KAFKA_ERROR_ON_APPLY_TOPIC" required:"true"` - GrpcAddr string `env:"GRPC_ADDR" required:"true"` ClusterToken string `env:"CLUSTER_TOKEN" required:"false"` @@ -24,8 +15,8 @@ type Env struct { ClusterName string `env:"CLUSTER_NAME" required:"true"` AccountName string `env:"ACCOUNT_NAME" required:"true"` - HarborSecretName string `env:"HARBOR_SECRET_NAME" required:"true"` - HarborSecretNamespace string `env:"HARBOR_SECRET_NAMESPACE" required:"true"` + ImagePullSecretName string `env:"IMAGE_PULL_SECRET_NAME" required:"true"` + ImagePullSecretNamespace string `env:"IMAGE_PULL_SECRET_NAMESPACE" required:"true"` } func GetEnvOrDie() *Env { diff --git a/agent/main.go b/agent/main.go index 8e645fd2..a6ffd8de 100644 --- a/agent/main.go +++ b/agent/main.go @@ -5,13 +5,14 @@ import ( "encoding/json" "flag" "fmt" + corev1 "k8s.io/api/core/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" "log" "strings" "time" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/rest" @@ -34,7 +35,7 @@ type grpcHandler struct { msgDispatchCli messages.MessageDispatchServiceClient } -func (g *grpcHandler) handleErrorOnApply(ctx context.Context, err error, msg t.AgentMessage) error { +func (g *grpcHandler) handleErrorOnApply(err error, msg t.AgentMessage) error { g.logger.Debugf("[ERROR]: %s", err.Error()) b, err := json.Marshal(t.AgentErrMessage{ @@ -70,12 +71,9 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { mLogger := g.logger.WithKV("gvk", obj.GetObjectKind().GroupVersionKind().String()).WithKV("clusterName", msg.ClusterName).WithKV("accountName", msg.AccountName).WithKV("action", msg.Action) mLogger.Infof("[%d] received message", g.inMemCounter) - // defer func() { - // mLogger.Infof("processed message [%d]", g.inMemCounter) - // }() if len(strings.TrimSpace(msg.AccountName)) == 0 { - return g.handleErrorOnApply(ctx, fmt.Errorf("field 'accountName' must be defined in message"), msg) + return g.handleErrorOnApply(fmt.Errorf("field 'accountName' must be defined in message"), msg) } switch msg.Action { @@ -83,7 +81,7 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { { b, err := yaml.Marshal(msg.Object) if err != nil { - return g.handleErrorOnApply(ctx, err, msg) + return g.handleErrorOnApply(err, msg) } if msg.Action == "apply" { @@ -91,7 +89,7 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { if err != nil { mLogger.Infof("[%d] [error-on-apply]: %s", g.inMemCounter, err.Error()) mLogger.Infof("[%d] failed to process message", g.inMemCounter) - return g.handleErrorOnApply(ctx, err, msg) + return g.handleErrorOnApply(err, msg) } mLogger.Infof("[%d] processed message", g.inMemCounter) return nil @@ -101,7 +99,7 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { err := g.yamlClient.DeleteYAML(ctx, b) if err != nil { mLogger.Infof("[%d] [error-on-delete]: %s", err.Error()) - return g.handleErrorOnApply(ctx, err, msg) + return g.handleErrorOnApply(err, msg) } mLogger.Infof("[%d] processed message", g.inMemCounter) return nil @@ -113,69 +111,107 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { err := fmt.Errorf("invalid action (%s)", msg.Action) mLogger.Infof("[%d] [error]: %s", err.Error()) mLogger.Infof("[%d] failed to process message", g.inMemCounter) - return g.handleErrorOnApply(ctx, err, msg) + return g.handleErrorOnApply(err, msg) } } } -func (g *grpcHandler) ensureAccessToken() error { - if g.ev.AccessToken == "" { - g.logger.Infof("waiting on clusterToken exchange for accessToken") +func (g *grpcHandler) ensureAccessToken(ctx context.Context) error { + if g.ev.AccessToken != "" { + return nil + } - out, err := g.msgDispatchCli.GetAccessToken(context.TODO(), &messages.GetClusterTokenIn{ - ClusterToken: g.ev.ClusterToken, - }) - if err != nil { - return err - } + g.logger.Infof("waiting on clusterToken exchange for accessToken") - s, err := g.yamlClient.K8sClient.CoreV1().Secrets(g.ev.AccessTokenSecretNamespace).Get(context.TODO(), g.ev.AccessTokenSecretName, metav1.GetOptions{}) - if err != nil { - return err - } + out, err := g.msgDispatchCli.GetAccessToken(ctx, &messages.GetClusterTokenIn{ + ClusterToken: g.ev.ClusterToken, + }) + if err != nil { + return err + } - delete(s.Data, "CLUSTER_TOKEN") - s.Data["ACCESS_TOKEN"] = []byte(out.AccessToken) - _, err = g.yamlClient.K8sClient.CoreV1().Secrets(g.ev.AccessTokenSecretNamespace).Update(context.TODO(), s, metav1.UpdateOptions{}) - if err != nil { - return err - } + s, err := g.yamlClient.K8sClient.CoreV1().Secrets(g.ev.AccessTokenSecretNamespace).Get(context.TODO(), g.ev.AccessTokenSecretName, metav1.GetOptions{}) + if err != nil { + return err + } - g.ev.AccessToken = out.AccessToken - - harborSecret, err := yaml.Marshal(corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: g.ev.HarborSecretName, - Namespace: g.ev.HarborSecretNamespace, - }, - Type: corev1.SecretTypeDockerConfigJson, - Data: map[string][]byte{ - ".dockerconfigjson": []byte(out.HarborDockerConfigJson), - }, - }) - if err != nil { - return err - } + delete(s.Data, "CLUSTER_TOKEN") + s.Data["ACCESS_TOKEN"] = []byte(out.AccessToken) + _, err = g.yamlClient.K8sClient.CoreV1().Secrets(g.ev.AccessTokenSecretNamespace).Update(context.TODO(), s, metav1.UpdateOptions{}) + if err != nil { + return err + } + + g.ev.AccessToken = out.AccessToken + return nil - if _, err := g.yamlClient.ApplyYAML(context.TODO(), harborSecret); err != nil { +} + +func (g *grpcHandler) ensureImagePullSecretCreds(ctx context.Context) error { + hs, err := g.yamlClient.K8sClient.CoreV1().Secrets(g.ev.ImagePullSecretNamespace).Get(ctx, g.ev.ImagePullSecretName, metav1.GetOptions{}) + if err != nil { + if !apiErrors.IsNotFound(err) { return err } + g.logger.Infof("image pull secret not found, will now be asking for it from message office") + hs = nil + } + + if hs != nil { + g.logger.Infof("image-pull-secret credentials secret found") + return nil + } + + g.logger.Infof("waiting on image-pull-secret credentials from message office") + + out, err := g.msgDispatchCli.GetDockerCredentials(ctx, &messages.GetDockerCredentialsIn{ + AccessToken: g.ev.AccessToken, + ClusterName: g.ev.ClusterName, + AccountName: g.ev.AccountName, + }) + if err != nil { + return err } - return nil -} -func (g *grpcHandler) run(conn *grpc.ClientConn) error { - if err := g.ensureAccessToken(); err != nil { + imgPullSecret, err := yaml.Marshal(corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: g.ev.ImagePullSecretName, + Namespace: g.ev.ImagePullSecretNamespace, + }, + Type: corev1.SecretTypeDockerConfigJson, + Data: map[string][]byte{ + ".dockerconfigjson": []byte(out.DockerConfigJson), + }, + }) + if err != nil { return err } + if _, err := g.yamlClient.ApplyYAML(ctx, imgPullSecret); err != nil { + return err + } + + g.logger.Infof("image-pull-secret credentials received from message office, and written to k8s secret (%s/%s)", g.ev.ImagePullSecretNamespace, g.ev.ImagePullSecretName) + + return nil +} + +func (g *grpcHandler) run() error { ctx, cf := context.WithCancel(context.TODO()) defer cf() + if err := g.ensureAccessToken(ctx); err != nil { + return err + } + + if err := g.ensureImagePullSecretCreds(ctx); err != nil { + return err + } + errorsCli, err := g.msgDispatchCli.ReceiveErrors(ctx) if err != nil { return err @@ -210,7 +246,10 @@ func (g *grpcHandler) run(conn *grpc.ClientConn) error { return err } - g.handleMessage(msg) + if err := g.handleMessage(msg); err != nil { + g.logger.Errorf(err, "[ERROR] while handling message") + return err + } } } @@ -266,7 +305,7 @@ func main() { logger.Infof("GRPC connection successful") g.msgDispatchCli = messages.NewMessageDispatchServiceClient(cc) - if err := g.run(cc); err != nil { + if err := g.run(); err != nil { logger.Errorf(err, "running grpc sendActions") } diff --git a/apis/crds/v1/project_types.go b/apis/crds/v1/project_types.go index 128a4ad2..c5c9ae0b 100644 --- a/apis/crds/v1/project_types.go +++ b/apis/crds/v1/project_types.go @@ -45,7 +45,11 @@ func (p *Project) GetStatus() *rApi.Status { } func (p *Project) GetEnsuredLabels() map[string]string { - return map[string]string{constants.ProjectNameKey: p.Name} + return map[string]string{ + constants.ProjectNameKey: p.Name, + constants.AccountNameKey: p.Spec.AccountName, + constants.ClusterNameKey: p.Spec.ClusterName, + } } func (p *Project) GetEnsuredAnnotations() map[string]string { diff --git a/grpc-interfaces/grpc/messages/messages.pb.go b/grpc-interfaces/grpc/messages/messages.pb.go index 0c843356..d24e8836 100644 --- a/grpc-interfaces/grpc/messages/messages.pb.go +++ b/grpc-interfaces/grpc/messages/messages.pb.go @@ -135,8 +135,7 @@ type GetClusterTokenOut struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - AccessToken string `protobuf:"bytes,1,opt,name=accessToken,proto3" json:"accessToken,omitempty"` - HarborDockerConfigJson string `protobuf:"bytes,2,opt,name=harborDockerConfigJson,proto3" json:"harborDockerConfigJson,omitempty"` + AccessToken string `protobuf:"bytes,1,opt,name=accessToken,proto3" json:"accessToken,omitempty"` } func (x *GetClusterTokenOut) Reset() { @@ -178,9 +177,112 @@ func (x *GetClusterTokenOut) GetAccessToken() string { return "" } -func (x *GetClusterTokenOut) GetHarborDockerConfigJson() string { +type GetDockerCredentialsIn struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessToken string `protobuf:"bytes,1,opt,name=accessToken,proto3" json:"accessToken,omitempty"` + ClusterName string `protobuf:"bytes,2,opt,name=clusterName,proto3" json:"clusterName,omitempty"` + AccountName string `protobuf:"bytes,3,opt,name=accountName,proto3" json:"accountName,omitempty"` +} + +func (x *GetDockerCredentialsIn) Reset() { + *x = GetDockerCredentialsIn{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDockerCredentialsIn) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDockerCredentialsIn) ProtoMessage() {} + +func (x *GetDockerCredentialsIn) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDockerCredentialsIn.ProtoReflect.Descriptor instead. +func (*GetDockerCredentialsIn) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{3} +} + +func (x *GetDockerCredentialsIn) GetAccessToken() string { + if x != nil { + return x.AccessToken + } + return "" +} + +func (x *GetDockerCredentialsIn) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *GetDockerCredentialsIn) GetAccountName() string { + if x != nil { + return x.AccountName + } + return "" +} + +type GetDockerCredentialsOut struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DockerConfigJson string `protobuf:"bytes,1,opt,name=dockerConfigJson,proto3" json:"dockerConfigJson,omitempty"` +} + +func (x *GetDockerCredentialsOut) Reset() { + *x = GetDockerCredentialsOut{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDockerCredentialsOut) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDockerCredentialsOut) ProtoMessage() {} + +func (x *GetDockerCredentialsOut) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDockerCredentialsOut.ProtoReflect.Descriptor instead. +func (*GetDockerCredentialsOut) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{4} +} + +func (x *GetDockerCredentialsOut) GetDockerConfigJson() string { if x != nil { - return x.HarborDockerConfigJson + return x.DockerConfigJson } return "" } @@ -196,7 +298,7 @@ type Action struct { func (x *Action) Reset() { *x = Action{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -209,7 +311,7 @@ func (x *Action) String() string { func (*Action) ProtoMessage() {} func (x *Action) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -222,7 +324,7 @@ func (x *Action) ProtoReflect() protoreflect.Message { // Deprecated: Use Action.ProtoReflect.Descriptor instead. func (*Action) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{3} + return file_messages_proto_rawDescGZIP(), []int{5} } func (x *Action) GetData() []byte { @@ -246,7 +348,7 @@ type ErrorData struct { func (x *ErrorData) Reset() { *x = ErrorData{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -259,7 +361,7 @@ func (x *ErrorData) String() string { func (*ErrorData) ProtoMessage() {} func (x *ErrorData) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -272,7 +374,7 @@ func (x *ErrorData) ProtoReflect() protoreflect.Message { // Deprecated: Use ErrorData.ProtoReflect.Descriptor instead. func (*ErrorData) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{4} + return file_messages_proto_rawDescGZIP(), []int{6} } func (x *ErrorData) GetAccessToken() string { @@ -317,7 +419,7 @@ type ResourceUpdate struct { func (x *ResourceUpdate) Reset() { *x = ResourceUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -330,7 +432,7 @@ func (x *ResourceUpdate) String() string { func (*ResourceUpdate) ProtoMessage() {} func (x *ResourceUpdate) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -343,7 +445,7 @@ func (x *ResourceUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceUpdate.ProtoReflect.Descriptor instead. func (*ResourceUpdate) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{5} + return file_messages_proto_rawDescGZIP(), []int{7} } func (x *ResourceUpdate) GetAccessToken() string { @@ -388,7 +490,7 @@ type InfraUpdate struct { func (x *InfraUpdate) Reset() { *x = InfraUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -401,7 +503,7 @@ func (x *InfraUpdate) String() string { func (*InfraUpdate) ProtoMessage() {} func (x *InfraUpdate) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -414,7 +516,7 @@ func (x *InfraUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use InfraUpdate.ProtoReflect.Descriptor instead. func (*InfraUpdate) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{6} + return file_messages_proto_rawDescGZIP(), []int{8} } func (x *InfraUpdate) GetAccessToken() string { @@ -459,7 +561,7 @@ type BYOCClientUpdate struct { func (x *BYOCClientUpdate) Reset() { *x = BYOCClientUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -472,7 +574,7 @@ func (x *BYOCClientUpdate) String() string { func (*BYOCClientUpdate) ProtoMessage() {} func (x *BYOCClientUpdate) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -485,7 +587,7 @@ func (x *BYOCClientUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use BYOCClientUpdate.ProtoReflect.Descriptor instead. func (*BYOCClientUpdate) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{7} + return file_messages_proto_rawDescGZIP(), []int{9} } func (x *BYOCClientUpdate) GetAccessToken() string { @@ -525,7 +627,7 @@ type Empty struct { func (x *Empty) Reset() { *x = Empty{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -538,7 +640,7 @@ func (x *Empty) String() string { func (*Empty) ProtoMessage() {} func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -551,7 +653,7 @@ func (x *Empty) ProtoReflect() protoreflect.Message { // Deprecated: Use Empty.ProtoReflect.Descriptor instead. func (*Empty) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{8} + return file_messages_proto_rawDescGZIP(), []int{10} } var File_messages_proto protoreflect.FileDescriptor @@ -569,75 +671,89 @@ var file_messages_proto_rawDesc = []byte{ 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6e, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x6c, + 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x36, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4f, 0x75, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x36, 0x0a, 0x16, 0x68, 0x61, 0x72, 0x62, 0x6f, 0x72, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x16, 0x68, 0x61, 0x72, 0x62, 0x6f, 0x72, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x85, 0x01, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, - 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x90, 0x01, - 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x92, 0x01, 0x0a, 0x10, 0x42, 0x59, 0x4f, 0x43, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xd4, - 0x02, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, - 0x63, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x0b, 0x53, 0x65, 0x6e, - 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x15, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x07, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x27, 0x0a, 0x0d, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x0a, 0x2e, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x35, 0x0a, 0x16, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, - 0x0f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x2f, 0x0a, 0x13, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x73, 0x12, 0x0c, 0x2e, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x39, 0x0a, - 0x18, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x42, 0x59, 0x4f, 0x43, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x11, 0x2e, 0x42, 0x59, 0x4f, 0x43, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x06, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x3b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, + 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0x7e, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x49, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, + 0x45, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x64, 0x6f, + 0x63, 0x6b, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x1c, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x85, 0x01, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x90, 0x01, 0x0a, + 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x8d, 0x01, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x92, 0x01, 0x0a, 0x10, 0x42, 0x59, 0x4f, 0x43, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x32, 0xa1, 0x03, + 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, + 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x6e, 0x1a, 0x13, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x4f, 0x75, 0x74, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4f, 0x75, 0x74, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, + 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x17, 0x2e, + 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x49, 0x6e, 0x1a, 0x18, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x63, 0x6b, + 0x65, 0x72, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x4f, 0x75, 0x74, + 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x15, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x07, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x00, 0x30, 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x0a, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x35, + 0x0a, 0x16, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x0f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x2f, 0x0a, 0x13, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x49, 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x0c, 0x2e, 0x49, + 0x6e, 0x66, 0x72, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x28, 0x01, 0x12, 0x39, 0x0a, 0x18, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, + 0x65, 0x42, 0x59, 0x4f, 0x43, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x11, 0x2e, 0x42, 0x59, 0x4f, 0x43, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x28, + 0x01, 0x42, 0x0f, 0x5a, 0x0d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -652,36 +768,40 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_messages_proto_goTypes = []interface{}{ - (*StreamActionsRequest)(nil), // 0: StreamActionsRequest - (*GetClusterTokenIn)(nil), // 1: GetClusterTokenIn - (*GetClusterTokenOut)(nil), // 2: GetClusterTokenOut - (*Action)(nil), // 3: Action - (*ErrorData)(nil), // 4: ErrorData - (*ResourceUpdate)(nil), // 5: ResourceUpdate - (*InfraUpdate)(nil), // 6: InfraUpdate - (*BYOCClientUpdate)(nil), // 7: BYOCClientUpdate - (*Empty)(nil), // 8: Empty + (*StreamActionsRequest)(nil), // 0: StreamActionsRequest + (*GetClusterTokenIn)(nil), // 1: GetClusterTokenIn + (*GetClusterTokenOut)(nil), // 2: GetClusterTokenOut + (*GetDockerCredentialsIn)(nil), // 3: GetDockerCredentialsIn + (*GetDockerCredentialsOut)(nil), // 4: GetDockerCredentialsOut + (*Action)(nil), // 5: Action + (*ErrorData)(nil), // 6: ErrorData + (*ResourceUpdate)(nil), // 7: ResourceUpdate + (*InfraUpdate)(nil), // 8: InfraUpdate + (*BYOCClientUpdate)(nil), // 9: BYOCClientUpdate + (*Empty)(nil), // 10: Empty } var file_messages_proto_depIdxs = []int32{ - 0, // 0: MessageDispatchService.SendActions:input_type -> StreamActionsRequest - 4, // 1: MessageDispatchService.ReceiveErrors:input_type -> ErrorData - 5, // 2: MessageDispatchService.ReceiveResourceUpdates:input_type -> ResourceUpdate - 6, // 3: MessageDispatchService.ReceiveInfraUpdates:input_type -> InfraUpdate - 7, // 4: MessageDispatchService.ReceiveBYOCClientUpdates:input_type -> BYOCClientUpdate - 1, // 5: MessageDispatchService.GetAccessToken:input_type -> GetClusterTokenIn - 3, // 6: MessageDispatchService.SendActions:output_type -> Action - 8, // 7: MessageDispatchService.ReceiveErrors:output_type -> Empty - 8, // 8: MessageDispatchService.ReceiveResourceUpdates:output_type -> Empty - 8, // 9: MessageDispatchService.ReceiveInfraUpdates:output_type -> Empty - 8, // 10: MessageDispatchService.ReceiveBYOCClientUpdates:output_type -> Empty - 2, // 11: MessageDispatchService.GetAccessToken:output_type -> GetClusterTokenOut - 6, // [6:12] is the sub-list for method output_type - 0, // [0:6] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: MessageDispatchService.GetAccessToken:input_type -> GetClusterTokenIn + 3, // 1: MessageDispatchService.GetDockerCredentials:input_type -> GetDockerCredentialsIn + 0, // 2: MessageDispatchService.SendActions:input_type -> StreamActionsRequest + 6, // 3: MessageDispatchService.ReceiveErrors:input_type -> ErrorData + 7, // 4: MessageDispatchService.ReceiveResourceUpdates:input_type -> ResourceUpdate + 8, // 5: MessageDispatchService.ReceiveInfraUpdates:input_type -> InfraUpdate + 9, // 6: MessageDispatchService.ReceiveBYOCClientUpdates:input_type -> BYOCClientUpdate + 2, // 7: MessageDispatchService.GetAccessToken:output_type -> GetClusterTokenOut + 4, // 8: MessageDispatchService.GetDockerCredentials:output_type -> GetDockerCredentialsOut + 5, // 9: MessageDispatchService.SendActions:output_type -> Action + 10, // 10: MessageDispatchService.ReceiveErrors:output_type -> Empty + 10, // 11: MessageDispatchService.ReceiveResourceUpdates:output_type -> Empty + 10, // 12: MessageDispatchService.ReceiveInfraUpdates:output_type -> Empty + 10, // 13: MessageDispatchService.ReceiveBYOCClientUpdates:output_type -> Empty + 7, // [7:14] is the sub-list for method output_type + 0, // [0:7] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -727,7 +847,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Action); i { + switch v := v.(*GetDockerCredentialsIn); i { case 0: return &v.state case 1: @@ -739,7 +859,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorData); i { + switch v := v.(*GetDockerCredentialsOut); i { case 0: return &v.state case 1: @@ -751,7 +871,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceUpdate); i { + switch v := v.(*Action); i { case 0: return &v.state case 1: @@ -763,7 +883,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InfraUpdate); i { + switch v := v.(*ErrorData); i { case 0: return &v.state case 1: @@ -775,7 +895,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BYOCClientUpdate); i { + switch v := v.(*ResourceUpdate); i { case 0: return &v.state case 1: @@ -787,6 +907,30 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InfraUpdate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BYOCClientUpdate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Empty); i { case 0: return &v.state @@ -805,7 +949,7 @@ func file_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_messages_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/grpc-interfaces/grpc/messages/messages_grpc.pb.go b/grpc-interfaces/grpc/messages/messages_grpc.pb.go index d6e728f9..eb29ec2f 100644 --- a/grpc-interfaces/grpc/messages/messages_grpc.pb.go +++ b/grpc-interfaces/grpc/messages/messages_grpc.pb.go @@ -22,12 +22,13 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type MessageDispatchServiceClient interface { + GetAccessToken(ctx context.Context, in *GetClusterTokenIn, opts ...grpc.CallOption) (*GetClusterTokenOut, error) + GetDockerCredentials(ctx context.Context, in *GetDockerCredentialsIn, opts ...grpc.CallOption) (*GetDockerCredentialsOut, error) SendActions(ctx context.Context, in *StreamActionsRequest, opts ...grpc.CallOption) (MessageDispatchService_SendActionsClient, error) ReceiveErrors(ctx context.Context, opts ...grpc.CallOption) (MessageDispatchService_ReceiveErrorsClient, error) ReceiveResourceUpdates(ctx context.Context, opts ...grpc.CallOption) (MessageDispatchService_ReceiveResourceUpdatesClient, error) ReceiveInfraUpdates(ctx context.Context, opts ...grpc.CallOption) (MessageDispatchService_ReceiveInfraUpdatesClient, error) ReceiveBYOCClientUpdates(ctx context.Context, opts ...grpc.CallOption) (MessageDispatchService_ReceiveBYOCClientUpdatesClient, error) - GetAccessToken(ctx context.Context, in *GetClusterTokenIn, opts ...grpc.CallOption) (*GetClusterTokenOut, error) } type messageDispatchServiceClient struct { @@ -38,6 +39,24 @@ func NewMessageDispatchServiceClient(cc grpc.ClientConnInterface) MessageDispatc return &messageDispatchServiceClient{cc} } +func (c *messageDispatchServiceClient) GetAccessToken(ctx context.Context, in *GetClusterTokenIn, opts ...grpc.CallOption) (*GetClusterTokenOut, error) { + out := new(GetClusterTokenOut) + err := c.cc.Invoke(ctx, "/MessageDispatchService/GetAccessToken", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *messageDispatchServiceClient) GetDockerCredentials(ctx context.Context, in *GetDockerCredentialsIn, opts ...grpc.CallOption) (*GetDockerCredentialsOut, error) { + out := new(GetDockerCredentialsOut) + err := c.cc.Invoke(ctx, "/MessageDispatchService/GetDockerCredentials", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *messageDispatchServiceClient) SendActions(ctx context.Context, in *StreamActionsRequest, opts ...grpc.CallOption) (MessageDispatchService_SendActionsClient, error) { stream, err := c.cc.NewStream(ctx, &MessageDispatchService_ServiceDesc.Streams[0], "/MessageDispatchService/SendActions", opts...) if err != nil { @@ -206,25 +225,17 @@ func (x *messageDispatchServiceReceiveBYOCClientUpdatesClient) CloseAndRecv() (* return m, nil } -func (c *messageDispatchServiceClient) GetAccessToken(ctx context.Context, in *GetClusterTokenIn, opts ...grpc.CallOption) (*GetClusterTokenOut, error) { - out := new(GetClusterTokenOut) - err := c.cc.Invoke(ctx, "/MessageDispatchService/GetAccessToken", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // MessageDispatchServiceServer is the server API for MessageDispatchService service. // All implementations must embed UnimplementedMessageDispatchServiceServer // for forward compatibility type MessageDispatchServiceServer interface { + GetAccessToken(context.Context, *GetClusterTokenIn) (*GetClusterTokenOut, error) + GetDockerCredentials(context.Context, *GetDockerCredentialsIn) (*GetDockerCredentialsOut, error) SendActions(*StreamActionsRequest, MessageDispatchService_SendActionsServer) error ReceiveErrors(MessageDispatchService_ReceiveErrorsServer) error ReceiveResourceUpdates(MessageDispatchService_ReceiveResourceUpdatesServer) error ReceiveInfraUpdates(MessageDispatchService_ReceiveInfraUpdatesServer) error ReceiveBYOCClientUpdates(MessageDispatchService_ReceiveBYOCClientUpdatesServer) error - GetAccessToken(context.Context, *GetClusterTokenIn) (*GetClusterTokenOut, error) mustEmbedUnimplementedMessageDispatchServiceServer() } @@ -232,6 +243,12 @@ type MessageDispatchServiceServer interface { type UnimplementedMessageDispatchServiceServer struct { } +func (UnimplementedMessageDispatchServiceServer) GetAccessToken(context.Context, *GetClusterTokenIn) (*GetClusterTokenOut, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAccessToken not implemented") +} +func (UnimplementedMessageDispatchServiceServer) GetDockerCredentials(context.Context, *GetDockerCredentialsIn) (*GetDockerCredentialsOut, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDockerCredentials not implemented") +} func (UnimplementedMessageDispatchServiceServer) SendActions(*StreamActionsRequest, MessageDispatchService_SendActionsServer) error { return status.Errorf(codes.Unimplemented, "method SendActions not implemented") } @@ -247,9 +264,6 @@ func (UnimplementedMessageDispatchServiceServer) ReceiveInfraUpdates(MessageDisp func (UnimplementedMessageDispatchServiceServer) ReceiveBYOCClientUpdates(MessageDispatchService_ReceiveBYOCClientUpdatesServer) error { return status.Errorf(codes.Unimplemented, "method ReceiveBYOCClientUpdates not implemented") } -func (UnimplementedMessageDispatchServiceServer) GetAccessToken(context.Context, *GetClusterTokenIn) (*GetClusterTokenOut, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetAccessToken not implemented") -} func (UnimplementedMessageDispatchServiceServer) mustEmbedUnimplementedMessageDispatchServiceServer() { } @@ -264,6 +278,42 @@ func RegisterMessageDispatchServiceServer(s grpc.ServiceRegistrar, srv MessageDi s.RegisterService(&MessageDispatchService_ServiceDesc, srv) } +func _MessageDispatchService_GetAccessToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetClusterTokenIn) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageDispatchServiceServer).GetAccessToken(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/MessageDispatchService/GetAccessToken", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageDispatchServiceServer).GetAccessToken(ctx, req.(*GetClusterTokenIn)) + } + return interceptor(ctx, in, info, handler) +} + +func _MessageDispatchService_GetDockerCredentials_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDockerCredentialsIn) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MessageDispatchServiceServer).GetDockerCredentials(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/MessageDispatchService/GetDockerCredentials", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MessageDispatchServiceServer).GetDockerCredentials(ctx, req.(*GetDockerCredentialsIn)) + } + return interceptor(ctx, in, info, handler) +} + func _MessageDispatchService_SendActions_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(StreamActionsRequest) if err := stream.RecvMsg(m); err != nil { @@ -389,24 +439,6 @@ func (x *messageDispatchServiceReceiveBYOCClientUpdatesServer) Recv() (*BYOCClie return m, nil } -func _MessageDispatchService_GetAccessToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetClusterTokenIn) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MessageDispatchServiceServer).GetAccessToken(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/MessageDispatchService/GetAccessToken", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MessageDispatchServiceServer).GetAccessToken(ctx, req.(*GetClusterTokenIn)) - } - return interceptor(ctx, in, info, handler) -} - // MessageDispatchService_ServiceDesc is the grpc.ServiceDesc for MessageDispatchService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -418,6 +450,10 @@ var MessageDispatchService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetAccessToken", Handler: _MessageDispatchService_GetAccessToken_Handler, }, + { + MethodName: "GetDockerCredentials", + Handler: _MessageDispatchService_GetDockerCredentials_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/grpc-interfaces/messages.proto b/grpc-interfaces/messages.proto index 147086a7..22c4020c 100644 --- a/grpc-interfaces/messages.proto +++ b/grpc-interfaces/messages.proto @@ -2,12 +2,15 @@ syntax = "proto3"; option go_package = "grpc/messages"; service MessageDispatchService { + rpc GetAccessToken(GetClusterTokenIn) returns (GetClusterTokenOut) {} + rpc GetDockerCredentials(GetDockerCredentialsIn) returns (GetDockerCredentialsOut) {} + rpc SendActions (StreamActionsRequest) returns (stream Action) {} + rpc ReceiveErrors(stream ErrorData) returns (Empty) {} rpc ReceiveResourceUpdates (stream ResourceUpdate) returns (Empty) {} rpc ReceiveInfraUpdates (stream InfraUpdate) returns (Empty) {} rpc ReceiveBYOCClientUpdates (stream BYOCClientUpdate) returns (Empty) {} - rpc GetAccessToken(GetClusterTokenIn) returns (GetClusterTokenOut) {} } message StreamActionsRequest { @@ -22,7 +25,16 @@ message GetClusterTokenIn { message GetClusterTokenOut { string accessToken = 1; - string harborDockerConfigJson = 2; +} + +message GetDockerCredentialsIn { + string accessToken = 1; + string clusterName = 2; + string accountName = 3; +} + +message GetDockerCredentialsOut { + string dockerConfigJson = 1; } message Action { diff --git a/operators/project/internal/controllers/project/controller.go b/operators/project/internal/controllers/project/controller.go index 5e4f8b55..ddf4fe65 100644 --- a/operators/project/internal/controllers/project/controller.go +++ b/operators/project/internal/controllers/project/controller.go @@ -3,6 +3,7 @@ package project import ( "context" "fmt" + appsv1 "k8s.io/api/apps/v1" "time" corev1 "k8s.io/api/core/v1" @@ -12,6 +13,9 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" v1 "github.com/kloudlite/operator/apis/crds/v1" "github.com/kloudlite/operator/operators/project/internal/env" @@ -192,6 +196,7 @@ func (r *Reconciler) ensureEnvRouteSwitcher(req *rApi.Request[*v1.Project]) step d := &v1.App{ObjectMeta: metav1.ObjectMeta{Name: "env-route-switcher", Namespace: obj.Spec.TargetNamespace}} if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, d, func() error { + d.SetOwnerReferences([]metav1.OwnerReference{fn.AsOwner(obj, true)}) d.Spec = v1.AppSpec{ DisplayName: "env router switcher", Replicas: 0, @@ -261,10 +266,19 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e r.yamlClient = kubectl.NewYAMLClientOrDie(mgr.GetConfig()) builder := ctrl.NewControllerManagedBy(mgr).For(&v1.Project{}) - builder.Owns(&corev1.Namespace{}) builder.Owns(&corev1.ServiceAccount{}) builder.Owns(&rbacv1.Role{}) builder.Owns(&rbacv1.RoleBinding{}) + builder.Owns(&appsv1.Deployment{}) + + builder.Watches(&source.Kind{ + Type: &corev1.Namespace{}, + }, handler.EnqueueRequestsFromMapFunc(func(obj client.Object) []reconcile.Request { + if v, ok := obj.GetLabels()[constants.ProjectNameKey]; ok { + return []reconcile.Request{{NamespacedName: fn.NN("", v)}} + } + return nil + })) builder.WithEventFilter(rApi.ReconcileFilter()) return builder.Complete(r) diff --git a/operators/resource-watcher/internal/controllers/watch-and-update/controller.go b/operators/resource-watcher/internal/controllers/watch-and-update/controller.go index 74133db1..0deb3d1a 100644 --- a/operators/resource-watcher/internal/controllers/watch-and-update/controller.go +++ b/operators/resource-watcher/internal/controllers/watch-and-update/controller.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + corev1 "k8s.io/api/core/v1" "log" "strings" "time" @@ -45,6 +46,7 @@ type Reconciler struct { dispatchResourceUpdates func(ctx context.Context, stu t.ResourceUpdate) error dispatchInfraUpdates func(ctx context.Context, stu t.ResourceUpdate) error dispatchBYOCClientUpdates func(ctx context.Context, stu t.ResourceUpdate) error + accessToken string } func (r *Reconciler) GetName() string { @@ -68,8 +70,10 @@ func (r *Reconciler) SendResourceEvents(ctx context.Context, obj client.Object, case strings.HasSuffix(obj.GetObjectKind().GroupVersionKind().Group, "infra.kloudlite.io"): { if err := r.dispatchInfraUpdates(ctx, t.ResourceUpdate{ - ClusterName: obj.GetLabels()[constants.ClusterNameKey], - AccountName: obj.GetLabels()[constants.AccountNameKey], + // ClusterName: obj.GetLabels()[constants.ClusterNameKey], + // AccountName: obj.GetLabels()[constants.AccountNameKey], + ClusterName: r.Env.ClusterName, + AccountName: r.Env.AccountName, Object: m, }); err != nil { return ctrl.Result{}, err @@ -97,8 +101,10 @@ func (r *Reconciler) SendResourceEvents(ctx context.Context, obj client.Object, case strings.HasSuffix(obj.GetObjectKind().GroupVersionKind().Group, "kloudlite.io"): { if err := r.dispatchResourceUpdates(ctx, t.ResourceUpdate{ - ClusterName: obj.GetLabels()[constants.ClusterNameKey], - AccountName: obj.GetLabels()[constants.AccountNameKey], + // ClusterName: obj.GetLabels()[constants.ClusterNameKey], + // AccountName: obj.GetLabels()[constants.AccountNameKey], + ClusterName: r.Env.ClusterName, + AccountName: r.Env.AccountName, Object: m, }); err != nil { return ctrl.Result{}, err @@ -132,6 +138,17 @@ func (r *Reconciler) SendResourceEvents(ctx context.Context, obj client.Object, // +kubebuilder:rbac:groups=watcher.kloudlite.io,resources=statuswatchers/finalizers,verbs=update func (r *Reconciler) Reconcile(ctx context.Context, oReq ctrl.Request) (ctrl.Result, error) { + if r.accessToken == "" { + r.logger.Infof("trying to read accessToken") + var clusterIdentity corev1.Secret + if err := r.Get(ctx, fn.NN(r.Env.ClusterIdentitySecretNamespace, r.Env.ClusterIdentitySecretName), &clusterIdentity); err != nil { + r.logger.Infof("waiting to read accessToken, retrying every 2s till then") + return ctrl.Result{RequeueAfter: 2 * time.Second}, nil + } + r.accessToken = string(clusterIdentity.Data["ACCESS_TOKEN"]) + r.logger.Infof("successfully retrieved accessToken") + } + var wName types.WrappedName if err := json.Unmarshal([]byte(oReq.Name), &wName); err != nil { return ctrl.Result{}, nil @@ -215,7 +232,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e return err } if err = mds.Send(&messages.ResourceUpdate{ - AccessToken: r.Env.AccessToken, + AccessToken: r.accessToken, ClusterName: r.Env.ClusterName, AccountName: r.Env.AccountName, Message: b, @@ -238,7 +255,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e } if err = infraMessagesCli.Send(&messages.InfraUpdate{ - AccessToken: r.Env.AccessToken, + AccessToken: r.accessToken, ClusterName: r.Env.ClusterName, AccountName: r.Env.AccountName, Message: b, @@ -261,7 +278,7 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e } if err = byocClientUpdatesCli.Send(&messages.BYOCClientUpdate{ - AccessToken: r.Env.AccessToken, + AccessToken: r.accessToken, ClusterName: r.Env.ClusterName, AccountName: r.Env.AccountName, Message: b, diff --git a/operators/resource-watcher/internal/env/env.go b/operators/resource-watcher/internal/env/env.go index 649cdbaa..734a6ac5 100644 --- a/operators/resource-watcher/internal/env/env.go +++ b/operators/resource-watcher/internal/env/env.go @@ -14,7 +14,10 @@ type Env struct { AccountName string `env:"ACCOUNT_NAME" required:"true"` ClusterName string `env:"CLUSTER_NAME" required:"true"` - AccessToken string `env:"ACCESS_TOKEN" required:"true"` + //AccessToken string `env:"ACCESS_TOKEN" required:"true"` + + ClusterIdentitySecretName string `env:"CLUSTER_IDENTITY_SECRET_NAME" required:"true"` + ClusterIdentitySecretNamespace string `env:"CLUSTER_IDENTITY_SECRET_NAMESPACE" required:"true"` OperatorsNamespace string `env:"OPERATORS_NAMESPACE" required:"true"` }