From 0eff8742a82aee5c9e9911b2ae5f7730bd03c9c6 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 25 Aug 2023 16:40:52 +0530 Subject: [PATCH 01/35] wip --- api/appStore/InstalledAppRestHandler.go | 12 ++-- api/bean/AppView.go | 8 ++- api/helm-app/applist.pb.go | 30 +++++++--- api/helm-app/applist.proto | 1 + api/restHandler/AppListingRestHandler.go | 8 ++- go.mod | 6 +- go.sum | 10 +--- pkg/appStore/bean/bean.go | 6 ++ .../repository/InstalledAppRepository.go | 12 ++++ .../repository/InstalledAppVersionHistory.go | 17 +++--- .../service/AppStoreDeploymentService.go | 49 ++++++++++++++++- .../deployment/service/InstalledAppService.go | 33 +++++++++-- .../tool/AppStoreDeploymentHelmService.go | 1 + util/k8s/K8sUtil.go | 3 +- util/mocks/rbac/EnforcerUtil.go | 2 +- .../common-lib/blob-storage/AwsS3Blob.go | 55 ++++++++++++++++++- .../blob-storage/BlobStorageService.go | 36 ++++++++++++ .../common-lib/pubsub-lib/JetStreamUtil.go | 5 ++ vendor/modules.txt | 6 +- wire_gen.go | 2 +- 20 files changed, 246 insertions(+), 56 deletions(-) diff --git a/api/appStore/InstalledAppRestHandler.go b/api/appStore/InstalledAppRestHandler.go index a795497a43..2909ef047c 100644 --- a/api/appStore/InstalledAppRestHandler.go +++ b/api/appStore/InstalledAppRestHandler.go @@ -576,11 +576,11 @@ func (handler *InstalledAppRestHandlerImpl) FetchAppDetailsForInstalledApp(w htt return } //rback block ends here - resourceTreeAndNotesContainer := bean2.ResourceTreeAndNotesContainer{} + resourceTreeAndNotesContainer := bean2.AppDetailsContainer{} resourceTreeAndNotesContainer.ResourceTree = map[string]interface{}{} if len(installedApp.App.AppName) > 0 && len(installedApp.Environment.Name) > 0 { - err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp) + err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, "") if installedApp.DeploymentAppType == util2.PIPELINE_DEPLOYMENT_TYPE_ACD { apiError, ok := err.(*util2.ApiError) if ok && apiError != nil { @@ -691,11 +691,11 @@ func (handler *InstalledAppRestHandlerImpl) FetchResourceTree(w http.ResponseWri return } - resourceTreeAndNotesContainer := bean2.ResourceTreeAndNotesContainer{} + resourceTreeAndNotesContainer := bean2.AppDetailsContainer{} resourceTreeAndNotesContainer.ResourceTree = map[string]interface{}{} if len(installedApp.App.AppName) > 0 && len(installedApp.Environment.Name) > 0 { - err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp) + err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, appDetail.HelmReleaseInstallStatus) if installedApp.DeploymentAppType == util2.PIPELINE_DEPLOYMENT_TYPE_ACD { //resource tree has been fetched now prepare to sync application deployment status with this resource tree call handler.syncDeploymentStatusWithResourceTreeCall(appDetail) @@ -786,10 +786,10 @@ func (handler *InstalledAppRestHandlerImpl) FetchResourceTreeForACDApp(w http.Re common.WriteJsonResp(w, err, appDetail, http.StatusOK) } -func (handler *InstalledAppRestHandlerImpl) fetchResourceTree(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer *bean2.ResourceTreeAndNotesContainer, installedApp repository.InstalledApps) error { +func (handler *InstalledAppRestHandlerImpl) fetchResourceTree(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer *bean2.AppDetailsContainer, installedApp repository.InstalledApps, helmReleaseInstallStatus string) error { ctx := r.Context() cn, _ := w.(http.CloseNotifier) - err := handler.installedAppService.FetchResourceTree(ctx, cn, resourceTreeAndNotesContainer, installedApp) + err := handler.installedAppService.FetchResourceTree(ctx, cn, resourceTreeAndNotesContainer, installedApp, helmReleaseInstallStatus) return err } diff --git a/api/bean/AppView.go b/api/bean/AppView.go index c99f43bd73..1824ffe168 100644 --- a/api/bean/AppView.go +++ b/api/bean/AppView.go @@ -169,6 +169,7 @@ type DeploymentDetailContainer struct { DeploymentAppDeleteRequest bool `json:"deploymentAppDeleteRequest"` Description string `json:"description" validate:"max=40"` IsVirtualEnvironment bool `json:"isVirtualEnvironment"` + HelmReleaseInstallStatus string `json:"-"` } type AppDetailContainer struct { @@ -179,9 +180,10 @@ type AppDetailContainer struct { ResourceTree map[string]interface{} `json:"resourceTree,omitempty"` Notes string `json:"notes,omitempty"` } -type ResourceTreeAndNotesContainer struct { - ResourceTree map[string]interface{} `json:"resourceTree,omitempty"` - Notes string `json:"notes,omitempty"` +type AppDetailsContainer struct { + ResourceTree map[string]interface{} `json:"resourceTree,omitempty"` + Notes string `json:"notes,omitempty"` + ReleaseStatus map[string]interface{} `json:"releaseStatus"` } type Notes struct { Notes string `json:"gitOpsNotes,omitempty"` diff --git a/api/helm-app/applist.pb.go b/api/helm-app/applist.pb.go index 61005442b6..1a3dcd9fa1 100644 --- a/api/helm-app/applist.pb.go +++ b/api/helm-app/applist.pb.go @@ -2322,13 +2322,14 @@ type InstallReleaseRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ReleaseIdentifier *ReleaseIdentifier `protobuf:"bytes,1,opt,name=releaseIdentifier,proto3" json:"releaseIdentifier,omitempty"` - ChartName string `protobuf:"bytes,2,opt,name=chartName,proto3" json:"chartName,omitempty"` - ChartVersion string `protobuf:"bytes,3,opt,name=chartVersion,proto3" json:"chartVersion,omitempty"` - ValuesYaml string `protobuf:"bytes,4,opt,name=valuesYaml,proto3" json:"valuesYaml,omitempty"` - ChartRepository *ChartRepository `protobuf:"bytes,5,opt,name=chartRepository,proto3" json:"chartRepository,omitempty"` - K8SVersion string `protobuf:"bytes,6,opt,name=K8sVersion,proto3" json:"K8sVersion,omitempty"` - HistoryMax int32 `protobuf:"varint,7,opt,name=historyMax,proto3" json:"historyMax,omitempty"` + ReleaseIdentifier *ReleaseIdentifier `protobuf:"bytes,1,opt,name=releaseIdentifier,proto3" json:"releaseIdentifier,omitempty"` + ChartName string `protobuf:"bytes,2,opt,name=chartName,proto3" json:"chartName,omitempty"` + ChartVersion string `protobuf:"bytes,3,opt,name=chartVersion,proto3" json:"chartVersion,omitempty"` + ValuesYaml string `protobuf:"bytes,4,opt,name=valuesYaml,proto3" json:"valuesYaml,omitempty"` + ChartRepository *ChartRepository `protobuf:"bytes,5,opt,name=chartRepository,proto3" json:"chartRepository,omitempty"` + K8SVersion string `protobuf:"bytes,6,opt,name=K8sVersion,proto3" json:"K8sVersion,omitempty"` + HistoryMax int32 `protobuf:"varint,7,opt,name=historyMax,proto3" json:"historyMax,omitempty"` + InstallAppVersionHistoryId int32 `protobuf:"varint,8,opt,name=installAppVersionHistoryId,proto3" json:"installAppVersionHistoryId,omitempty"` } func (x *InstallReleaseRequest) Reset() { @@ -2412,6 +2413,13 @@ func (x *InstallReleaseRequest) GetHistoryMax() int32 { return 0 } +func (x *InstallReleaseRequest) GetInstallAppVersionHistoryId() int32 { + if x != nil { + return x.InstallAppVersionHistoryId + } + return 0 +} + type InstallReleaseResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3365,7 +3373,7 @@ var file_api_helm_app_applist_proto_rawDesc = []byte{ 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x22, 0xb7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, + 0x64, 0x22, 0xf7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, @@ -3384,7 +3392,11 @@ var file_api_helm_app_applist_proto_rawDesc = []byte{ 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x22, 0x32, 0x0a, 0x16, 0x49, + 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x12, 0x3e, 0x0a, 0x1a, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x1a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x22, 0x32, 0x0a, 0x16, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, diff --git a/api/helm-app/applist.proto b/api/helm-app/applist.proto index 34faafdf39..6413e68173 100644 --- a/api/helm-app/applist.proto +++ b/api/helm-app/applist.proto @@ -262,6 +262,7 @@ message InstallReleaseRequest { ChartRepository chartRepository = 5; string K8sVersion = 6; int32 historyMax = 7; + int32 installAppVersionHistoryId = 8; } message InstallReleaseResponse { diff --git a/api/restHandler/AppListingRestHandler.go b/api/restHandler/AppListingRestHandler.go index 3513a037c5..e87ab21c3d 100644 --- a/api/restHandler/AppListingRestHandler.go +++ b/api/restHandler/AppListingRestHandler.go @@ -1345,10 +1345,10 @@ func (handler AppListingRestHandlerImpl) RedirectToLinkouts(w http.ResponseWrite } http.Redirect(w, r, link, http.StatusOK) } -func (handler AppListingRestHandlerImpl) fetchResourceTreeFromInstallAppService(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer bean.ResourceTreeAndNotesContainer, installedApps repository.InstalledApps) (bean.ResourceTreeAndNotesContainer, error) { +func (handler AppListingRestHandlerImpl) fetchResourceTreeFromInstallAppService(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer bean.AppDetailsContainer, installedApps repository.InstalledApps) (bean.AppDetailsContainer, error) { rctx := r.Context() cn, _ := w.(http.CloseNotifier) - err := handler.installedAppService.FetchResourceTree(rctx, cn, &resourceTreeAndNotesContainer, installedApps) + err := handler.installedAppService.FetchResourceTree(rctx, cn, &resourceTreeAndNotesContainer, installedApps, "") return resourceTreeAndNotesContainer, err } func (handler AppListingRestHandlerImpl) GetHostUrlsByBatch(w http.ResponseWriter, r *http.Request) { @@ -1420,7 +1420,7 @@ func (handler AppListingRestHandlerImpl) GetHostUrlsByBatch(w http.ResponseWrite common.WriteJsonResp(w, err, "App not found in database", http.StatusBadRequest) return } - resourceTreeAndNotesContainer := bean.ResourceTreeAndNotesContainer{} + resourceTreeAndNotesContainer := bean.AppDetailsContainer{} resourceTreeAndNotesContainer, err = handler.fetchResourceTreeFromInstallAppService(w, r, resourceTreeAndNotesContainer, *installedApp) if err != nil { common.WriteJsonResp(w, fmt.Errorf("error in fetching resource tree"), nil, http.StatusInternalServerError) @@ -1591,7 +1591,9 @@ func (handler AppListingRestHandlerImpl) fetchResourceTree(w http.ResponseWriter } if detail != nil { resourceTree = util2.InterfaceToMapAdapter(detail.ResourceTreeResponse) + releaseStatus := util2.InterfaceToMapAdapter(detail.ReleaseStatus) applicationStatus := detail.ApplicationStatus + resourceTree["releaseStatus"] = releaseStatus resourceTree["status"] = applicationStatus if applicationStatus == application.Healthy { status, err := handler.appListingService.ISLastReleaseStopType(appId, envId) diff --git a/go.mod b/go.mod index 5e5f69c028..e29ddb9bcb 100644 --- a/go.mod +++ b/go.mod @@ -15,13 +15,14 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/davecgh/go-spew v1.1.1 github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53 - github.com/devtron-labs/common-lib v0.0.0-20230407072229-d4f665f5ca12 + github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2 github.com/evanphx/json-patch v5.6.0+incompatible github.com/go-pg/pg v6.15.1+incompatible github.com/go-resty/resty/v2 v2.7.0 github.com/gogo/protobuf v1.3.2 github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 github.com/google/go-cmp v0.5.9 github.com/google/go-github v17.0.0+incompatible @@ -140,7 +141,6 @@ require ( github.com/go-xorm/xorm v0.7.9 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-github/v41 v41.0.0 // indirect @@ -233,14 +233,12 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/exp v0.0.0-20220602145555-4a0574d9293f // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.5.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect - golang.org/x/tools v0.1.12 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.101.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 315bb949ee..7cf573ce70 100644 --- a/go.sum +++ b/go.sum @@ -282,8 +282,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADG github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53 h1:oHDpsCsuYiL+u5TEhilKNLGhH9lwRNkIqrzhHQA6d3c= github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53/go.mod h1:ozNfT8WcruiSgnUbyp48WVfc41++W6xYXhKFp67lNTU= -github.com/devtron-labs/common-lib v0.0.0-20230407072229-d4f665f5ca12 h1:tcwNgAWTzalItF5XT0WxicRvY4wzz/o0HYLMVLxsxjg= -github.com/devtron-labs/common-lib v0.0.0-20230407072229-d4f665f5ca12/go.mod h1:R24nOqgk4buk9zv+BXzORfObZsOe3NE9P55KrZXGX9k= +github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 h1:BNyGu3HBIiHDNo2rbk/tv75O3rt9dSY/9OkGPhwD/8s= +github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327/go.mod h1:R24nOqgk4buk9zv+BXzORfObZsOe3NE9P55KrZXGX9k= github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2 h1:/IEIsJTxDZ3hv8uOoCaqdWCXqcv7nCAgX9AP/v84dUY= github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2/go.mod h1:l85jxWHlcSo910hdUfRycL40yGzC6glE93V1sVxVPto= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -326,7 +326,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -568,7 +567,6 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -1325,8 +1323,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1624,8 +1620,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 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= diff --git a/pkg/appStore/bean/bean.go b/pkg/appStore/bean/bean.go index be1991aa06..8c28cae270 100644 --- a/pkg/appStore/bean/bean.go +++ b/pkg/appStore/bean/bean.go @@ -370,3 +370,9 @@ type PushChartToGitRequestDTO struct { TempChartRefDir string UserId int32 } + +type HelmInstallNatsMessage struct { + InstallAppVersionHistoryId int + Message string + IsReleaseInstalled bool +} diff --git a/pkg/appStore/deployment/repository/InstalledAppRepository.go b/pkg/appStore/deployment/repository/InstalledAppRepository.go index cf67e81fb3..0e2529083c 100644 --- a/pkg/appStore/deployment/repository/InstalledAppRepository.go +++ b/pkg/appStore/deployment/repository/InstalledAppRepository.go @@ -71,6 +71,7 @@ type InstalledAppRepository interface { GetArgoPipelinesHavingLatestTriggerStuckInNonTerminalStatusesForAppStore(getPipelineDeployedBeforeMinutes int, getPipelineDeployedWithinHours int) ([]*InstalledAppVersions, error) GetArgoPipelinesHavingTriggersStuckInLastPossibleNonTerminalTimelinesForAppStore(pendingSinceSeconds int, timeForDegradation int) ([]*InstalledAppVersions, error) + GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, error) } type InstalledAppRepositoryImpl struct { @@ -658,3 +659,14 @@ func (impl InstalledAppRepositoryImpl) GetArgoPipelinesHavingTriggersStuckInLast } return installedAppVersions, nil } + +func (impl InstalledAppRepositoryImpl) GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, error) { + var helmReleaseStatusConfig string + queryString := `select helm_release_status_config from installed_app_version_history inner join installed_app_versions on installed_app_version_history.installed_app_version_id=installed_app_versions.id inner join installed_apps on installed_apps.id=installed_app_versions.installed_app_id where installed_apps.id=? order by installed_app_version_history.created_on desc limit 1;` + _, err := impl.dbConnection.Query(&helmReleaseStatusConfig, queryString) + if err != nil { + impl.Logger.Errorw("error in GetAllGitOpsDeploymentAppName", "err", err) + return helmReleaseStatusConfig, err + } + return helmReleaseStatusConfig, nil +} diff --git a/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go b/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go index 5cc2322585..d9cca40180 100644 --- a/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go +++ b/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go @@ -34,14 +34,15 @@ func NewInstalledAppVersionHistoryRepositoryImpl(Logger *zap.SugaredLogger, dbCo } type InstalledAppVersionHistory struct { - TableName struct{} `sql:"installed_app_version_history" pg:",discard_unknown_columns"` - Id int `sql:"id,pk"` - InstalledAppVersionId int `sql:"installed_app_version_id,notnull"` - ValuesYamlRaw string `sql:"values_yaml_raw"` - Status string `sql:"status"` - GitHash string `sql:"git_hash"` - StartedOn time.Time `sql:"started_on,type:timestamptz"` - FinishedOn time.Time `sql:"finished_on,type:timestamptz"` + TableName struct{} `sql:"installed_app_version_history" pg:",discard_unknown_columns"` + Id int `sql:"id,pk"` + InstalledAppVersionId int `sql:"installed_app_version_id,notnull"` + ValuesYamlRaw string `sql:"values_yaml_raw"` + Status string `sql:"status"` + GitHash string `sql:"git_hash"` + StartedOn time.Time `sql:"started_on,type:timestamptz"` + FinishedOn time.Time `sql:"finished_on,type:timestamptz"` + HelmReleaseStatusConfig string `sql: "helm_release_status"` sql.AuditLog } diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 725d836dfc..a1851551b4 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -19,9 +19,11 @@ package service import ( "context" + "encoding/json" "errors" "fmt" "github.com/caarlos0/env/v6" + pubsub "github.com/devtron-labs/common-lib/pubsub-lib" client "github.com/devtron-labs/devtron/api/helm-app" openapi "github.com/devtron-labs/devtron/api/helm-app/openapiClient" openapi2 "github.com/devtron-labs/devtron/api/openapi/openapiClient" @@ -72,6 +74,7 @@ type AppStoreDeploymentService interface { UpdateProjectHelmApp(updateAppRequest *appStoreBean.UpdateProjectHelmAppDTO) error UpdateNotesForInstalledApp(installAppId int, notes string) (bool, error) UpdatePreviousDeploymentStatusForAppStore(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, triggeredAt time.Time, err error) error + SubscribeHelmInstallStatus() error } type DeploymentServiceTypeConfig struct { @@ -102,6 +105,7 @@ type AppStoreDeploymentServiceImpl struct { gitOpsRepository repository2.GitOpsConfigRepository deploymentTypeConfig *DeploymentServiceTypeConfig ChartTemplateService util.ChartTemplateService + pubSubClient *pubsub.PubSubClientServiceImpl } func NewAppStoreDeploymentServiceImpl(logger *zap.SugaredLogger, installedAppRepository repository.InstalledAppRepository, @@ -112,8 +116,9 @@ func NewAppStoreDeploymentServiceImpl(logger *zap.SugaredLogger, installedAppRep clusterService cluster.ClusterService, helmAppService client.HelmAppService, appStoreDeploymentCommonService appStoreDeploymentCommon.AppStoreDeploymentCommonService, globalEnvVariables *util2.GlobalEnvVariables, installedAppRepositoryHistory repository.InstalledAppVersionHistoryRepository, gitOpsRepository repository2.GitOpsConfigRepository, attributesService attributes.AttributesService, - deploymentTypeConfig *DeploymentServiceTypeConfig, ChartTemplateService util.ChartTemplateService) *AppStoreDeploymentServiceImpl { - return &AppStoreDeploymentServiceImpl{ + deploymentTypeConfig *DeploymentServiceTypeConfig, ChartTemplateService util.ChartTemplateService, pubSubClient *pubsub.PubSubClientServiceImpl) *AppStoreDeploymentServiceImpl { + + appStoreDeploymentServiceImpl := &AppStoreDeploymentServiceImpl{ logger: logger, installedAppRepository: installedAppRepository, appStoreApplicationVersionRepository: appStoreApplicationVersionRepository, @@ -131,7 +136,13 @@ func NewAppStoreDeploymentServiceImpl(logger *zap.SugaredLogger, installedAppRep gitOpsRepository: gitOpsRepository, deploymentTypeConfig: deploymentTypeConfig, ChartTemplateService: ChartTemplateService, + pubSubClient: pubSubClient, + } + err := appStoreDeploymentServiceImpl.SubscribeHelmInstallStatus() + if err != nil { + return nil } + return appStoreDeploymentServiceImpl } func (impl AppStoreDeploymentServiceImpl) AppStoreDeployOperationDB(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, tx *pg.Tx, skipAppCreation bool) (*appStoreBean.InstallAppVersionDTO, error) { @@ -1678,3 +1689,37 @@ func (impl AppStoreDeploymentServiceImpl) UpdatePreviousDeploymentStatusForAppSt } return nil } + +func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { + + callback := func(msg *pubsub.PubSubMsg) { + + impl.logger.Debug("received helm install status event") + impl.logger.Debugw("HELM_INSTALL_STATUS", "data", msg.Data) + helmInstallNatsMessage := &appStoreBean.HelmInstallNatsMessage{} + err := json.Unmarshal([]byte(msg.Data), helmInstallNatsMessage) + if err != nil { + impl.logger.Errorw("error in unmarshalling helm install status nats message", "err", err) + return + } + + installedAppVersionHistory, err := impl.installedAppRepositoryHistory.GetInstalledAppVersionHistory(helmInstallNatsMessage.InstallAppVersionHistoryId) + if err != nil { + impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) + } + + installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data + _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(installedAppVersionHistory, nil) + if err != nil { + impl.logger.Errorw("error in updating helm release status data in installedAppVersionHistoryRepository", "err", err) + return + } + } + + err := impl.pubSubClient.Subscribe(pubsub.HELM_CHART_INSTALL_STATUS_TOPIC, callback) + if err != nil { + impl.logger.Error(err) + return err + } + return nil +} diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index d7c83171c0..cb3e7e723e 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -91,7 +91,7 @@ type InstalledAppService interface { DeployDefaultChartOnCluster(bean *cluster2.ClusterBean, userId int32) (bool, error) FindAppDetailsForAppstoreApplication(installedAppId, envId int) (bean2.AppDetailContainer, error) UpdateInstalledAppVersionStatus(application *v1alpha1.Application) (bool, error) - FetchResourceTree(rctx context.Context, cn http.CloseNotifier, resourceTreeAndNotesContainer *bean2.ResourceTreeAndNotesContainer, installedApp repository2.InstalledApps) error + FetchResourceTree(rctx context.Context, cn http.CloseNotifier, resourceTreeAndNotesContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string) error MarkGitOpsInstalledAppsDeletedIfArgoAppIsDeleted(installedAppId int, envId int) error CheckAppExistsByInstalledAppId(installedAppId int) (*repository2.InstalledApps, error) FindNotesForArgoApplication(installedAppId, envId int) (string, string, error) @@ -840,6 +840,11 @@ func (impl *InstalledAppServiceImpl) FindAppDetailsForAppstoreApplication(instal impl.logger.Error(err) return bean2.AppDetailContainer{}, err } + helmReleaseInstallStatus, err := impl.installedAppRepository.GetHelmReleaseStatusConfigByInstalledAppId(installedAppVerison.InstalledAppId) + if err != nil { + impl.logger.Errorw("error in getting helm release status from db", "err", err) + return bean2.AppDetailContainer{}, err + } deploymentContainer := bean2.DeploymentDetailContainer{ InstalledAppId: installedAppVerison.InstalledApp.Id, AppId: installedAppVerison.InstalledApp.App.Id, @@ -858,6 +863,7 @@ func (impl *InstalledAppServiceImpl) FindAppDetailsForAppstoreApplication(instal DeploymentAppType: installedAppVerison.InstalledApp.DeploymentAppType, DeploymentAppDeleteRequest: installedAppVerison.InstalledApp.DeploymentAppDeleteRequest, IsVirtualEnvironment: installedAppVerison.InstalledApp.Environment.IsVirtualEnvironment, + HelmReleaseInstallStatus: helmReleaseInstallStatus, } userInfo, err := impl.userService.GetByIdIncludeDeleted(installedAppVerison.AuditLog.UpdatedBy) if err != nil { @@ -1075,7 +1081,7 @@ func (impl InstalledAppServiceImpl) GetInstalledAppVersionHistoryValues(installe values.ValuesYaml = versionHistory.ValuesYamlRaw return values, err } -func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn http.CloseNotifier, resourceTreeAndNotesContainer *bean2.ResourceTreeAndNotesContainer, installedApp repository2.InstalledApps) error { +func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn http.CloseNotifier, appDetailsContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string) error { var err error var resourceTree map[string]interface{} deploymentAppName := fmt.Sprintf("%s-%s", installedApp.App.AppName, installedApp.Environment.Name) @@ -1095,11 +1101,30 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h if err != nil { impl.logger.Errorw("error in fetching app detail", "err", err) } + if detail != nil { resourceTree = util3.InterfaceToMapAdapter(detail.ResourceTreeResponse) resourceTree["status"] = detail.ApplicationStatus - resourceTreeAndNotesContainer.Notes = detail.ChartMetadata.Notes + appDetailsContainer.Notes = detail.ChartMetadata.Notes + releaseStatus := util3.InterfaceToMapAdapter(detail.ReleaseStatus) + appDetailsContainer.ReleaseStatus = releaseStatus impl.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", installedApp.App.AppName, "env", installedApp.Environment.Name) + } else { + releaseStatus := &client.ReleaseStatus{} + if len(helmReleaseInstallStatus) > 0 { + helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} + err := json.Unmarshal([]byte(helmReleaseInstallStatus), helmInstallStatus) + if err != nil { + impl.logger.Errorw("error in unmarshalling helm release install status") + } + if !helmInstallStatus.IsReleaseInstalled { + releaseStatus.Status = "Release Install Failed" + releaseStatus.Description = helmInstallStatus.Message + releaseStatus.Message = "Release for this app doesn't exist" + } + } + releaseStatusMap := util3.InterfaceToMapAdapter(detail.ReleaseStatus) + appDetailsContainer.ReleaseStatus = releaseStatusMap } } if resourceTree != nil { @@ -1109,7 +1134,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h } else { resourceTree["serverVersion"] = version.String() } - resourceTreeAndNotesContainer.ResourceTree = resourceTree + appDetailsContainer.ResourceTree = resourceTree } return err } diff --git a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go index cb81a0c867..48671d2b54 100644 --- a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go +++ b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go @@ -92,6 +92,7 @@ func (impl AppStoreDeploymentHelmServiceImpl) InstallApp(installAppVersionReques ReleaseNamespace: installAppVersionRequest.Namespace, ReleaseName: installAppVersionRequest.AppName, }, + InstallAppVersionHistoryId: int32(installAppVersionRequest.InstalledAppVersionHistoryId), } _, err = impl.helmAppService.InstallRelease(ctx, installAppVersionRequest.ClusterId, installReleaseRequest) diff --git a/util/k8s/K8sUtil.go b/util/k8s/K8sUtil.go index 7deb389fa5..2fcf79bce6 100644 --- a/util/k8s/K8sUtil.go +++ b/util/k8s/K8sUtil.go @@ -638,8 +638,9 @@ func (impl K8sUtil) GetK8sInClusterRestConfig() (*rest.Config, error) { return restConfig, nil } else { clusterConfig, err := rest.InClusterConfig() + impl.logger.Debugw("fetched cluster config", "clusterConfig", clusterConfig) if err != nil { - impl.logger.Errorw("error in fetch default cluster config", "err", err) + impl.logger.Errorw("error in fetch default cluster config", "err", err, "clusterConfig", clusterConfig) return nil, err } return clusterConfig, nil diff --git a/util/mocks/rbac/EnforcerUtil.go b/util/mocks/rbac/EnforcerUtil.go index 344ba93254..ce32315bc6 100644 --- a/util/mocks/rbac/EnforcerUtil.go +++ b/util/mocks/rbac/EnforcerUtil.go @@ -7,7 +7,7 @@ package mock_rbac import ( reflect "reflect" - application "github.com/devtron-labs/devtron/client/k8s/application" + application "github.com/devtron-labs/devtron/util/k8s" pipelineConfig "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" bean "github.com/devtron-labs/devtron/pkg/bean" gomock "github.com/golang/mock/gomock" diff --git a/vendor/github.com/devtron-labs/common-lib/blob-storage/AwsS3Blob.go b/vendor/github.com/devtron-labs/common-lib/blob-storage/AwsS3Blob.go index b8c51995b8..6c41651ddf 100644 --- a/vendor/github.com/devtron-labs/common-lib/blob-storage/AwsS3Blob.go +++ b/vendor/github.com/devtron-labs/common-lib/blob-storage/AwsS3Blob.go @@ -1,6 +1,8 @@ package blob_storage import ( + "bytes" + "context" "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -51,7 +53,7 @@ func (impl *AwsS3Blob) DownloadBlob(request *BlobStorageRequest, downloadSuccess return downloadSuccess, numBytes, err } -//TODO KB need to verify for versioning not enabled +// TODO KB need to verify for versioning not enabled func downLoadFromS3(file *os.File, request *BlobStorageRequest, sess *session.Session) (success bool, bytesSize int64, err error) { svc := s3.New(sess) s3BaseConfig := request.AwsS3BaseConfig @@ -107,3 +109,54 @@ func downLoadFromS3(file *os.File, request *BlobStorageRequest, sess *session.Se return true, numBytes, nil } + +func (impl *AwsS3Blob) DeleteObjectFromBlob(request *BlobStorageRequest) error { + s3BaseConfig := request.AwsS3BaseConfig + var cmdArgs []string + destinationFileString := fmt.Sprintf("s3://%s/%s", s3BaseConfig.BucketName, request.DestinationKey) + cmdArgs = append(cmdArgs, "s3", "rm", destinationFileString) + if s3BaseConfig.EndpointUrl != "" { + cmdArgs = append(cmdArgs, "--endpoint-url", s3BaseConfig.EndpointUrl) + } + if s3BaseConfig.Region != "" { + cmdArgs = append(cmdArgs, "--region", s3BaseConfig.Region) + } + command := exec.Command("aws", cmdArgs...) + err := utils.RunCommand(command) + return err +} +func (impl *AwsS3Blob) UploadWithSession(request *BlobStorageRequest) (*s3manager.UploadOutput, error) { + + s3BaseConfig := request.AwsS3BaseConfig + awsCfg := &aws.Config{ + Region: aws.String(s3BaseConfig.Region), + } + if s3BaseConfig.AccessKey != "" { + awsCfg.Credentials = credentials.NewStaticCredentials(s3BaseConfig.AccessKey, s3BaseConfig.Passkey, "") + } + + if s3BaseConfig.EndpointUrl != "" { // to handle s3 compatible storage + awsCfg.Endpoint = aws.String(s3BaseConfig.EndpointUrl) + awsCfg.DisableSSL = aws.Bool(s3BaseConfig.IsInSecure) + awsCfg.S3ForcePathStyle = aws.Bool(true) + } + content, err := os.ReadFile(request.SourceKey) + if err != nil { + log.Println("error in reading source file", "sourceFile", request.SourceKey, "destinationKey", request.DestinationKey) + return nil, err + } + s3Session := session.New(awsCfg) + uploader := s3manager.NewUploader(s3Session) + input := &s3manager.UploadInput{ + Bucket: aws.String(s3BaseConfig.BucketName), // bucket's name + Key: aws.String(request.DestinationKey), // files destination location + Body: bytes.NewReader(content), // content of the file + } + output, err := uploader.UploadWithContext(context.Background(), input) + if err != nil { + log.Println("error in uploading file to S3", "err", err, "sourceKey", request.SourceKey, "destinationKey", request.DestinationKey) + return nil, err + } + return output, err + +} diff --git a/vendor/github.com/devtron-labs/common-lib/blob-storage/BlobStorageService.go b/vendor/github.com/devtron-labs/common-lib/blob-storage/BlobStorageService.go index 3c7cca2506..9288d1bacb 100644 --- a/vendor/github.com/devtron-labs/common-lib/blob-storage/BlobStorageService.go +++ b/vendor/github.com/devtron-labs/common-lib/blob-storage/BlobStorageService.go @@ -12,6 +12,7 @@ import ( type BlobStorageService interface { PutWithCommand(request *BlobStorageRequest) error Get(request *BlobStorageRequest) (bool, error) + DeleteObjectForS3(request *BlobStorageRequest) error } type BlobStorageServiceImpl struct { @@ -76,3 +77,38 @@ func (impl *BlobStorageServiceImpl) Get(request *BlobStorageRequest) (bool, int6 return downloadSuccess, numBytes, err } + +// TODO: Have not Tested it +func (impl *BlobStorageServiceImpl) DeleteObjectForS3(request *BlobStorageRequest) error { + if request.StorageType == BLOB_STORAGE_S3 { + awsS3Blob := AwsS3Blob{} + err := awsS3Blob.DeleteObjectFromBlob(request) + if err != nil { + impl.logger.Errorw("error in deleting object from S3", "err", err, "DestinationKey", request.DestinationKey, "StorageType", request.StorageType) + return err + } + } + + return nil +} + +func (impl *BlobStorageServiceImpl) UploadToBlobWithSession(request *BlobStorageRequest) error { + var err error + switch request.StorageType { + case BLOB_STORAGE_S3: + awsS3Blob := AwsS3Blob{} + _, err = awsS3Blob.UploadWithSession(request) + case BLOB_STORAGE_AZURE: + azureBlob := AzureBlob{} + err = azureBlob.UploadBlob(context.Background(), request.DestinationKey, request.AzureBlobBaseConfig, request.SourceKey, request.AzureBlobBaseConfig.BlobContainerName) + case BLOB_STORAGE_GCP: + gcpBlob := GCPBlob{} + err = gcpBlob.UploadBlob(request) + default: + return fmt.Errorf("blob-storage %s not supported", request.StorageType) + } + if err != nil { + log.Println(" -----> push err", err) + } + return err +} diff --git a/vendor/github.com/devtron-labs/common-lib/pubsub-lib/JetStreamUtil.go b/vendor/github.com/devtron-labs/common-lib/pubsub-lib/JetStreamUtil.go index cddf055e2d..4abab475b6 100644 --- a/vendor/github.com/devtron-labs/common-lib/pubsub-lib/JetStreamUtil.go +++ b/vendor/github.com/devtron-labs/common-lib/pubsub-lib/JetStreamUtil.go @@ -83,6 +83,9 @@ const ( CD_BULK_DEPLOY_TRIGGER_TOPIC string = "CD-BULK-DEPLOY-TRIGGER" CD_BULK_DEPLOY_TRIGGER_GROUP string = "CD-BULK-DEPLOY-TRIGGER-GROUP-1" CD_BULK_DEPLOY_TRIGGER_DURABLE string = "CD-BULK-DEPLOY-TRIGGER-DURABLE-1" + HELM_CHART_INSTALL_STATUS_TOPIC string = "HELM-CHART-INSTALL-STATUS-TOPIC" + HELM_CHART_INSTALL_STATUS_GROUP string = "HELM-CHART-INSTALL-STATUS-GROUP" + HELM_CHART_INSTALL_STATUS_DURABLE string = "HELM-CHART-INSTALL-STATUS-DURABLE" ) type NatsTopic struct { @@ -119,6 +122,7 @@ var natsTopicMapping = map[string]NatsTopic{ DEVTRON_TEST_TOPIC: {topicName: DEVTRON_TEST_TOPIC, streamName: DEVTRON_TEST_STREAM, queueName: DEVTRON_TEST_QUEUE, consumerName: DEVTRON_TEST_CONSUMER}, TOPIC_CI_SCAN: {topicName: TOPIC_CI_SCAN, streamName: IMAGE_SCANNER_STREAM, queueName: TOPIC_CI_SCAN_GRP, consumerName: TOPIC_CI_SCAN_DURABLE}, ARGO_PIPELINE_STATUS_UPDATE_TOPIC: {topicName: ARGO_PIPELINE_STATUS_UPDATE_TOPIC, streamName: ORCHESTRATOR_STREAM, queueName: ARGO_PIPELINE_STATUS_UPDATE_GROUP, consumerName: ARGO_PIPELINE_STATUS_UPDATE_DURABLE}, + HELM_CHART_INSTALL_STATUS_TOPIC: {topicName: HELM_CHART_INSTALL_STATUS_TOPIC, streamName: ORCHESTRATOR_STREAM, queueName: HELM_CHART_INSTALL_STATUS_GROUP, consumerName: HELM_CHART_INSTALL_STATUS_DURABLE}, } var NatsStreamWiseConfigMapping = map[string]NatsStreamConfig{ @@ -146,6 +150,7 @@ var NatsConsumerWiseConfigMapping = map[string]NatsConsumerConfig{ BULK_DEPLOY_DURABLE: {}, BULK_APPSTORE_DEPLOY_DURABLE: {}, CD_BULK_DEPLOY_TRIGGER_DURABLE: {}, + HELM_CHART_INSTALL_STATUS_DURABLE: {}, } func getConsumerConfigMap(jsonString string) map[string]NatsConsumerConfig { diff --git a/vendor/modules.txt b/vendor/modules.txt index b381ae0289..7656ca2869 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -327,7 +327,7 @@ github.com/devtron-labs/authenticator/jwt github.com/devtron-labs/authenticator/middleware github.com/devtron-labs/authenticator/oidc github.com/devtron-labs/authenticator/password -# github.com/devtron-labs/common-lib v0.0.0-20230407072229-d4f665f5ca12 +# github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 ## explicit; go 1.18 github.com/devtron-labs/common-lib/blob-storage github.com/devtron-labs/common-lib/pubsub-lib @@ -1060,8 +1060,6 @@ golang.org/x/crypto/ssh/knownhosts ## explicit; go 1.18 golang.org/x/exp/maps golang.org/x/exp/rand -# golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 -## explicit; go 1.17 # golang.org/x/net v0.7.0 ## explicit; go 1.17 golang.org/x/net/context @@ -1118,8 +1116,6 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.0.0-20220922220347-f3bd1da661af ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.1.12 -## explicit; go 1.18 # golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 ## explicit; go 1.17 golang.org/x/xerrors diff --git a/wire_gen.go b/wire_gen.go index 7663ccf8c1..3b6fd83ddd 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -366,7 +366,7 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - appStoreDeploymentServiceImpl := service.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentArgoCdServiceImpl, environmentServiceImpl, clusterServiceImplExtended, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl) + appStoreDeploymentServiceImpl := service.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentArgoCdServiceImpl, environmentServiceImpl, clusterServiceImplExtended, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl, pubSubClientServiceImpl) k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sUtil, clusterServiceImplExtended) manifestPushConfigRepositoryImpl := repository9.NewManifestPushConfigRepository(sugaredLogger, db) gitOpsManifestPushServiceImpl := app2.NewGitOpsManifestPushServiceImpl(sugaredLogger, chartTemplateServiceImpl, chartServiceImpl, gitOpsConfigRepositoryImpl, gitFactory, pipelineStatusTimelineServiceImpl) From ebb2c486e0ad9fa8e4193a72837ee60ee8415fe1 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 25 Aug 2023 18:08:11 +0530 Subject: [PATCH 02/35] wip --- cmd/external-app/wire.go | 2 ++ cmd/external-app/wire_gen.go | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/external-app/wire.go b/cmd/external-app/wire.go index 0b934358c5..43cd4403c2 100644 --- a/cmd/external-app/wire.go +++ b/cmd/external-app/wire.go @@ -5,6 +5,7 @@ package main import ( "github.com/devtron-labs/authenticator/middleware" + pubsub_lib "github.com/devtron-labs/common-lib/pubsub-lib" "github.com/devtron-labs/devtron/api/apiToken" appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment" appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover" @@ -179,6 +180,7 @@ func InitializeApp() (*App, error) { security2.NewScanToolMetadataRepositoryImpl, wire.Bind(new(security2.ScanToolMetadataRepository), new(*security2.ScanToolMetadataRepositoryImpl)), + pubsub_lib.NewPubSubClientServiceImpl, ) return &App{}, nil } diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go index 5fe7a68031..bdc377353b 100644 --- a/cmd/external-app/wire_gen.go +++ b/cmd/external-app/wire_gen.go @@ -10,6 +10,7 @@ import ( "github.com/devtron-labs/authenticator/apiToken" "github.com/devtron-labs/authenticator/client" "github.com/devtron-labs/authenticator/middleware" + "github.com/devtron-labs/common-lib/pubsub-lib" apiToken2 "github.com/devtron-labs/devtron/api/apiToken" "github.com/devtron-labs/devtron/api/appStore/deployment" "github.com/devtron-labs/devtron/api/appStore/discover" @@ -271,7 +272,8 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - appStoreDeploymentServiceImpl := service3.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentHelmServiceImpl, environmentServiceImpl, clusterServiceImpl, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl) + pubSubClientServiceImpl := pubsub_lib.NewPubSubClientServiceImpl(sugaredLogger) + appStoreDeploymentServiceImpl := service3.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentHelmServiceImpl, environmentServiceImpl, clusterServiceImpl, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl, pubSubClientServiceImpl) appStoreDeploymentRestHandlerImpl := appStoreDeployment.NewAppStoreDeploymentRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, validate, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, helmUserServiceImpl, attributesServiceImpl) appStoreDeploymentRouterImpl := appStoreDeployment.NewAppStoreDeploymentRouterImpl(appStoreDeploymentRestHandlerImpl) posthogClient, err := telemetry.NewPosthogClient(sugaredLogger) From 625dc8f860bddbbbcec23053b3751eb5319f922e Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 28 Aug 2023 02:46:18 +0530 Subject: [PATCH 03/35] wip --- .../repository/InstalledAppRepository.go | 4 +- .../service/AppStoreDeploymentService.go | 39 +++++++------------ .../deployment/service/InstalledAppService.go | 2 +- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/pkg/appStore/deployment/repository/InstalledAppRepository.go b/pkg/appStore/deployment/repository/InstalledAppRepository.go index 0e2529083c..8216bdeb99 100644 --- a/pkg/appStore/deployment/repository/InstalledAppRepository.go +++ b/pkg/appStore/deployment/repository/InstalledAppRepository.go @@ -662,8 +662,8 @@ func (impl InstalledAppRepositoryImpl) GetArgoPipelinesHavingTriggersStuckInLast func (impl InstalledAppRepositoryImpl) GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, error) { var helmReleaseStatusConfig string - queryString := `select helm_release_status_config from installed_app_version_history inner join installed_app_versions on installed_app_version_history.installed_app_version_id=installed_app_versions.id inner join installed_apps on installed_apps.id=installed_app_versions.installed_app_id where installed_apps.id=? order by installed_app_version_history.created_on desc limit 1;` - _, err := impl.dbConnection.Query(&helmReleaseStatusConfig, queryString) + queryString := `select helm_release_status_config from installed_app_version_history inner join installed_app_versions on installed_app_version_history.installed_app_version_id=installed_app_versions.id inner join installed_apps on installed_apps.id=installed_app_versions.installed_app_id where installed_apps.id = ? order by installed_app_version_history.created_on desc limit 1;` + _, err := impl.dbConnection.Query(&helmReleaseStatusConfig, queryString, installedAppVersionHistoryId) if err != nil { impl.Logger.Errorw("error in GetAllGitOpsDeploymentAppName", "err", err) return helmReleaseStatusConfig, err diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index a1851551b4..192c04cff1 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -285,23 +285,21 @@ func (impl AppStoreDeploymentServiceImpl) AppStoreDeployOperationDB(installAppVe installAppVersionRequest.InstalledAppVersionId = installedAppVersions.Id installAppVersionRequest.Id = installedAppVersions.Id - if installAppVersionRequest.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_ACD || installAppVersionRequest.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_MANIFEST_DOWNLOAD { - installedAppVersionHistory := &repository.InstalledAppVersionHistory{} - installedAppVersionHistory.InstalledAppVersionId = installedAppVersions.Id - installedAppVersionHistory.ValuesYamlRaw = installAppVersionRequest.ValuesOverrideYaml - installedAppVersionHistory.CreatedBy = installAppVersionRequest.UserId - installedAppVersionHistory.CreatedOn = time.Now() - installedAppVersionHistory.UpdatedBy = installAppVersionRequest.UserId - installedAppVersionHistory.UpdatedOn = time.Now() - installedAppVersionHistory.StartedOn = time.Now() - installedAppVersionHistory.Status = pipelineConfig.WorkflowInProgress - _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) - if err != nil { - impl.logger.Errorw("error while fetching from db", "error", err) - return nil, err - } - installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id + installedAppVersionHistory := &repository.InstalledAppVersionHistory{} + installedAppVersionHistory.InstalledAppVersionId = installedAppVersions.Id + installedAppVersionHistory.ValuesYamlRaw = installAppVersionRequest.ValuesOverrideYaml + installedAppVersionHistory.CreatedBy = installAppVersionRequest.UserId + installedAppVersionHistory.CreatedOn = time.Now() + installedAppVersionHistory.UpdatedBy = installAppVersionRequest.UserId + installedAppVersionHistory.UpdatedOn = time.Now() + installedAppVersionHistory.StartedOn = time.Now() + installedAppVersionHistory.Status = pipelineConfig.WorkflowInProgress + _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) + if err != nil { + impl.logger.Errorw("error while fetching from db", "error", err) + return nil, err } + installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id if installAppVersionRequest.DefaultClusterComponent { clusterInstalledAppsModel := &repository.ClusterInstalledApps{ @@ -1070,14 +1068,6 @@ func (impl AppStoreDeploymentServiceImpl) installAppPostDbOperation(installAppVe } } - if installAppVersionRequest.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_HELM { - err = impl.UpdateInstallAppVersionHistory(installAppVersionRequest) - if err != nil { - impl.logger.Errorw("error on creating history for chart deployment", "error", err) - return err - } - } - return nil } @@ -1706,6 +1696,7 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { installedAppVersionHistory, err := impl.installedAppRepositoryHistory.GetInstalledAppVersionHistory(helmInstallNatsMessage.InstallAppVersionHistoryId) if err != nil { impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) + return } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index cb3e7e723e..33de9da560 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1123,7 +1123,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h releaseStatus.Message = "Release for this app doesn't exist" } } - releaseStatusMap := util3.InterfaceToMapAdapter(detail.ReleaseStatus) + releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap } } From 6f161c771a6bac5a82d3ba57bf5e3aa81929f234 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 28 Aug 2023 17:31:29 +0530 Subject: [PATCH 04/35] wip --- .../service/AppStoreDeploymentService.go | 34 +++++++++---------- .../deployment/service/InstalledAppService.go | 7 ---- .../tool/AppStoreDeploymentHelmService.go | 13 +++---- .../gitops/AppStoreDeploymentArgoCdService.go | 4 +-- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 192c04cff1..f1f45a6ff8 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -64,7 +64,7 @@ type AppStoreDeploymentService interface { DeleteInstalledApp(ctx context.Context, installAppVersionRequest *appStoreBean.InstallAppVersionDTO) (*appStoreBean.InstallAppVersionDTO, error) LinkHelmApplicationToChartStore(ctx context.Context, request *openapi.UpdateReleaseWithChartLinkingRequest, appIdentifier *client.AppIdentifier, userId int32) (*openapi.UpdateReleaseResponse, bool, error) RollbackApplication(ctx context.Context, request *openapi2.RollbackReleaseRequest, installedApp *appStoreBean.InstallAppVersionDTO, userId int32) (bool, error) - UpdateInstallAppVersionHistory(installAppVersionRequest *appStoreBean.InstallAppVersionDTO) error + UpdateInstallAppVersionHistory(installAppVersionRequest *appStoreBean.InstallAppVersionDTO) (*repository.InstalledAppVersionHistory, error) GetDeploymentHistory(ctx context.Context, installedApp *appStoreBean.InstallAppVersionDTO) (*client.DeploymentHistoryAndInstalledAppInfo, error) GetDeploymentHistoryInfo(ctx context.Context, installedApp *appStoreBean.InstallAppVersionDTO, installedAppVersionHistoryId int) (*openapi.HelmAppDeploymentManifestDetail, error) UpdateInstalledApp(ctx context.Context, installAppVersionRequest *appStoreBean.InstallAppVersionDTO) (*appStoreBean.InstallAppVersionDTO, error) @@ -515,11 +515,11 @@ func (impl AppStoreDeploymentServiceImpl) UpdateInstalledAppVersionHistoryStatus return nil } -func (impl AppStoreDeploymentServiceImpl) UpdateInstallAppVersionHistory(installAppVersionRequest *appStoreBean.InstallAppVersionDTO) error { +func (impl AppStoreDeploymentServiceImpl) UpdateInstallAppVersionHistory(installAppVersionRequest *appStoreBean.InstallAppVersionDTO) (*repository.InstalledAppVersionHistory, error) { dbConnection := impl.installedAppRepository.GetConnection() tx, err := dbConnection.Begin() if err != nil { - return err + return nil, err } // Rollback tx on error. defer tx.Rollback() @@ -533,17 +533,17 @@ func (impl AppStoreDeploymentServiceImpl) UpdateInstallAppVersionHistory(install installedAppVersionHistory.UpdatedOn = time.Now() installedAppVersionHistory.GitHash = installAppVersionRequest.GitHash installedAppVersionHistory.Status = "Unknown" - _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) + installedAppVersionHistory, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) if err != nil { impl.logger.Errorw("error while fetching from db", "error", err) - return err + return nil, err } err = tx.Commit() if err != nil { impl.logger.Errorw("error while committing transaction to db", "error", err) - return err + return nil, err } - return nil + return installedAppVersionHistory, nil } func (impl AppStoreDeploymentServiceImpl) UpdateInstalledAppVersionHistoryWithGitHash(installAppVersionRequest *appStoreBean.InstallAppVersionDTO) error { dbConnection := impl.installedAppRepository.GetConnection() @@ -1419,8 +1419,15 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex impl.logger.Errorw("error while creating installed app version history for updating installed app", "error", err) return nil, err } - installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id _ = impl.appStoreDeploymentArgoCdService.SaveTimelineForACDHelmApps(installAppVersionRequest, pipelineConfig.TIMELINE_STATUS_DEPLOYMENT_INITIATED, "Deployment initiated successfully.", tx) + } else { + // create build history for chart on default component deployed via helm + installedAppVersionHistory, err := impl.UpdateInstallAppVersionHistory(installAppVersionRequest) + if err != nil { + impl.logger.Errorw("error on creating history for chart deployment", "error", err, "installedAppVersion", installedAppVersion) + return nil, err + } + installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id } manifest, err := impl.appStoreDeploymentCommonService.GenerateManifest(installAppVersionRequest) @@ -1509,14 +1516,14 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex if installAppVersionRequest.PerformACDDeployment { if monoRepoMigrationRequired { // update repo details on ArgoCD as repo is changed - err = impl.appStoreDeploymentArgoCdService.UpdateChartInfo(installAppVersionRequest, gitOpsResponse.ChartGitAttribute, ctx) + err = impl.appStoreDeploymentArgoCdService.UpdateChartInfo(installAppVersionRequest, gitOpsResponse.ChartGitAttribute, 0, ctx) if err != nil { impl.logger.Errorw("error in acd patch request", "err", err) return nil, err } } } else if installAppVersionRequest.PerformHelmDeployment { - err = impl.appStoreDeploymentHelmService.UpdateChartInfo(installAppVersionRequest, gitOpsResponse.ChartGitAttribute, ctx) + err = impl.appStoreDeploymentHelmService.UpdateChartInfo(installAppVersionRequest, gitOpsResponse.ChartGitAttribute, installAppVersionRequest.InstalledAppVersionHistoryId, ctx) if err != nil { if err != nil { impl.logger.Errorw("error in helm update request", "err", err) @@ -1551,13 +1558,6 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex impl.logger.Errorw("error on creating history for chart deployment", "error", err) return nil, err } - } else { - // create build history for chart on default component deployed via helm - err = impl.UpdateInstallAppVersionHistory(installAppVersionRequest) - if err != nil { - impl.logger.Errorw("error on creating history for chart deployment", "error", err, "installedAppVersion", installedAppVersion) - return nil, err - } } return installAppVersionRequest, nil diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 33de9da560..c18b230e03 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -557,13 +557,6 @@ func (impl InstalledAppServiceImpl) performDeployStage(installedAppVersionId int impl.logger.Errorw("error on updating history for chart deployment", "error", err, "installedAppVersion", installedAppVersion) return nil, err } - } else { - // create build history for chart on default component deployed via helm - err = impl.appStoreDeploymentService.UpdateInstallAppVersionHistory(installedAppVersion) - if err != nil { - impl.logger.Errorw("error on creating history for chart deployment", "error", err, "installedAppVersion", installedAppVersion) - return nil, err - } } return installedAppVersion, nil diff --git a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go index 48671d2b54..f8045e863f 100644 --- a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go +++ b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go @@ -35,7 +35,7 @@ type AppStoreDeploymentHelmService interface { DeleteDeploymentApp(ctx context.Context, appName string, environmentName string, installAppVersionRequest *appStoreBean.InstallAppVersionDTO) error UpdateInstalledAppAndPipelineStatusForFailedDeploymentStatus(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, triggeredAt time.Time, err error) error SaveTimelineForACDHelmApps(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, status string, statusDetail string, tx *pg.Tx) error - UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, ctx context.Context) error + UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, installedAppVersionHistoryId int, ctx context.Context) error } type AppStoreDeploymentHelmServiceImpl struct { @@ -61,8 +61,8 @@ func NewAppStoreDeploymentHelmServiceImpl(logger *zap.SugaredLogger, helmAppServ } } -func (impl AppStoreDeploymentHelmServiceImpl) UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, ctx context.Context) error { - err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml) +func (impl AppStoreDeploymentHelmServiceImpl) UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, installedAppVersionHistoryId int, ctx context.Context) error { + err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml, installedAppVersionHistoryId) if err != nil { impl.Logger.Errorw("error in updating helm app", "err", err) return err @@ -268,7 +268,7 @@ func (impl *AppStoreDeploymentHelmServiceImpl) OnUpdateRepoInInstalledApp(ctx co } } - err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml) + err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml, 0) if err != nil { return installAppVersionRequest, err } @@ -342,7 +342,7 @@ func (impl *AppStoreDeploymentHelmServiceImpl) UpdateInstalledApp(ctx context.Co } if !noTargetFound { // update chart application already called, hence skipping - err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml) + err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml, 0) if err != nil { return nil, err } @@ -350,7 +350,7 @@ func (impl *AppStoreDeploymentHelmServiceImpl) UpdateInstalledApp(ctx context.Co return installAppVersionRequest, nil } -func (impl *AppStoreDeploymentHelmServiceImpl) updateApplicationWithChartInfo(ctx context.Context, installedAppId int, appStoreApplicationVersionId int, valuesOverrideYaml string) error { +func (impl *AppStoreDeploymentHelmServiceImpl) updateApplicationWithChartInfo(ctx context.Context, installedAppId int, appStoreApplicationVersionId int, valuesOverrideYaml string, installAppVersionHistoryId int) error { installedApp, err := impl.installedAppRepository.GetInstalledApp(installedAppId) if err != nil { @@ -380,6 +380,7 @@ func (impl *AppStoreDeploymentHelmServiceImpl) updateApplicationWithChartInfo(ct Username: chartRepo.UserName, Password: chartRepo.Password, }, + InstallAppVersionHistoryId: int32(installAppVersionHistoryId), }, SourceAppType: client.SOURCE_HELM_APP, } diff --git a/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go b/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go index 8b91871b4e..19792cb790 100644 --- a/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go +++ b/pkg/appStore/deployment/tool/gitops/AppStoreDeploymentArgoCdService.go @@ -54,7 +54,7 @@ type AppStoreDeploymentArgoCdService interface { DeleteDeploymentApp(ctx context.Context, appName string, environmentName string, installAppVersionRequest *appStoreBean.InstallAppVersionDTO) error UpdateInstalledAppAndPipelineStatusForFailedDeploymentStatus(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, triggeredAt time.Time, err error) error SaveTimelineForACDHelmApps(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, status string, statusDetail string, tx *pg.Tx) error - UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, ctx context.Context) error + UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, installedAppVersionHistoryId int, ctx context.Context) error } type AppStoreDeploymentArgoCdServiceImpl struct { @@ -108,7 +108,7 @@ func NewAppStoreDeploymentArgoCdServiceImpl(logger *zap.SugaredLogger, appStoreD } // UpdateChartInfo this will update chart info in acd app, needed when repo for an app is changed -func (impl AppStoreDeploymentArgoCdServiceImpl) UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, ctx context.Context) error { +func (impl AppStoreDeploymentArgoCdServiceImpl) UpdateChartInfo(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ChartGitAttribute *util.ChartGitAttribute, installedAppVersionHistoryId int, ctx context.Context) error { installAppVersionRequest, err := impl.patchAcdApp(ctx, installAppVersionRequest, ChartGitAttribute) if err != nil { return err From 5d928909e1dfcf6057e62b56d0ddb773b895a79e Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 28 Aug 2023 19:47:24 +0530 Subject: [PATCH 05/35] wip --- api/helm-app/applist.pb.go | 826 +++++++++--------- api/helm-app/applist.proto | 1 + .../deployment/service/InstalledAppService.go | 8 +- scripts/sql/166_helm_async_install.down.sql | 2 + scripts/sql/166_helm_async_install.up.sql | 3 + 5 files changed, 430 insertions(+), 410 deletions(-) create mode 100644 scripts/sql/166_helm_async_install.down.sql create mode 100644 scripts/sql/166_helm_async_install.up.sql diff --git a/api/helm-app/applist.pb.go b/api/helm-app/applist.pb.go index 1a3dcd9fa1..24bfea97c8 100644 --- a/api/helm-app/applist.pb.go +++ b/api/helm-app/applist.pb.go @@ -451,6 +451,7 @@ type AppDetail struct { ChartMetadata *ChartMetadata `protobuf:"bytes,7,opt,name=chartMetadata,proto3" json:"chartMetadata,omitempty"` ResourceTreeResponse *ResourceTreeResponse `protobuf:"bytes,8,opt,name=resourceTreeResponse,proto3" json:"resourceTreeResponse,omitempty"` EnvironmentDetails *EnvironmentDetails `protobuf:"bytes,9,opt,name=environmentDetails,proto3" json:"environmentDetails,omitempty"` + ReleaseExist bool `protobuf:"varint,10,opt,name=ReleaseExist,proto3" json:"ReleaseExist,omitempty"` } func (x *AppDetail) Reset() { @@ -527,6 +528,13 @@ func (x *AppDetail) GetEnvironmentDetails() *EnvironmentDetails { return nil } +func (x *AppDetail) GetReleaseExist() bool { + if x != nil { + return x.ReleaseExist + } + return false +} + type AppStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3109,7 +3117,7 @@ var file_api_helm_app_applist_proto_rawDesc = []byte{ 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x22, 0xf5, 0x02, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x65, 0x72, 0x22, 0x99, 0x03, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x34, @@ -3132,421 +3140,423 @@ var file_api_helm_app_applist_proto_rawDesc = []byte{ 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x12, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x39, 0x0a, 0x09, 0x41, 0x70, - 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x63, 0x0a, 0x0d, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb7, 0x01, 0x0a, 0x0d, 0x43, - 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, - 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x68, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, - 0x6f, 0x74, 0x65, 0x73, 0x22, 0x6b, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, - 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, - 0x73, 0x12, 0x2e, 0x0a, 0x0b, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0xf5, 0x03, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x0a, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x52, 0x0a, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x73, - 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0c, 0x69, 0x73, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x12, 0x28, - 0x0a, 0x0f, 0x63, 0x61, 0x6e, 0x42, 0x65, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x42, 0x65, 0x48, 0x69, - 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x49, 0x74, 0x65, - 0x6d, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0f, 0x20, - 0x03, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x34, 0x0a, 0x08, 0x49, 0x6e, 0x66, - 0x6f, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x40, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x22, 0x90, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3b, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, - 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x66, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0xdc, 0x01, 0x0a, - 0x0b, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, - 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, - 0x4e, 0x65, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x4e, 0x65, 0x77, - 0x12, 0x49, 0x0a, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, - 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x4c, 0x0a, 0x16, 0x45, - 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, - 0x73, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x87, 0x01, 0x0a, 0x10, 0x48, 0x69, - 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, - 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x7e, - 0x0a, 0x0f, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x22, 0x3d, - 0x0a, 0x11, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x81, 0x02, - 0x0a, 0x17, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x34, 0x0a, 0x0d, 0x63, 0x68, 0x61, - 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x0d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x22, 0x0a, 0x0c, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, - 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x42, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x42, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x22, 0x62, 0x0a, 0x18, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, - 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x41, - 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, - 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x85, 0x02, 0x0a, 0x0b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, - 0x64, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, 0x70, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, - 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x26, 0x0a, - 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x72, - 0x67, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, - 0x64, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, - 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0xd2, 0x01, - 0x0a, 0x0d, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x34, 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x22, 0x35, 0x0a, 0x17, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x6e, - 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x18, 0x55, 0x6e, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, - 0x97, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x72, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, - 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xcc, 0x01, 0x0a, 0x15, 0x55, 0x70, - 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, - 0x61, 0x6d, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x4d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, - 0x72, 0x79, 0x4d, 0x61, 0x78, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x68, - 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x32, 0x0a, 0x16, 0x55, 0x70, 0x67, 0x72, - 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x89, 0x01, 0x0a, - 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, + 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x22, 0x39, + 0x0a, 0x09, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x63, 0x0a, 0x0d, 0x52, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb7, + 0x01, 0x0a, 0x0d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, + 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x68, 0x6f, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x22, 0x6b, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x23, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, + 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x0b, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x50, 0x6f, 0x64, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0b, 0x70, 0x6f, 0x64, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf5, 0x03, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x2c, + 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, + 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x3f, 0x0a, 0x0e, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, + 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x22, + 0x0a, 0x0c, 0x69, 0x73, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, + 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x61, 0x6e, 0x42, 0x65, 0x48, 0x69, 0x62, 0x65, 0x72, + 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, + 0x42, 0x65, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x04, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x49, 0x6e, 0x66, + 0x6f, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x34, 0x0a, + 0x08, 0x49, 0x6e, 0x66, 0x6f, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x40, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x90, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, + 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, + 0x22, 0xdc, 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x64, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, + 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x69, 0x73, 0x4e, 0x65, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, + 0x73, 0x4e, 0x65, 0x77, 0x12, 0x49, 0x0a, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, + 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x13, 0x65, 0x70, 0x68, 0x65, + 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, + 0x4c, 0x0a, 0x16, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22, 0x87, 0x01, + 0x0a, 0x10, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x34, 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x10, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x10, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x22, 0x7e, 0x0a, 0x0f, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x73, 0x67, 0x22, 0x3d, 0x0a, 0x11, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0x81, 0x02, 0x0a, 0x17, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x34, 0x0a, + 0x0d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x63, 0x6b, 0x65, + 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3a, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x42, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x42, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x62, 0x0a, 0x18, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x46, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x48, + 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x85, 0x02, 0x0a, 0x0b, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x11, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, + 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x65, 0x64, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x65, 0x72, + 0x67, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4a, 0x73, 0x6f, + 0x6e, 0x22, 0xd2, 0x01, 0x0a, 0x0d, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x10, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x35, 0x0a, 0x17, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, + 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, + 0x18, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xcc, 0x01, + 0x0a, 0x15, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, + 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0c, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x32, 0x0a, 0x16, + 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x22, 0x89, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2c, + 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x18, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, + 0x6d, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x59, 0x61, 0x6d, 0x6c, 0x22, 0x6f, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0xf7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, + 0x61, 0x6d, 0x6c, 0x12, 0x3a, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x43, + 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0f, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1e, 0x0a, 0x0a, 0x4b, 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4b, 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1e, 0x0a, 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x12, + 0x3e, 0x0a, 0x1a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x1a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x22, + 0x32, 0x0a, 0x16, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x22, 0x29, 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x74, + 0x0a, 0x16, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x11, 0x64, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x18, 0x44, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, - 0x22, 0x6f, 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x22, 0xf7, 0x02, 0x0a, 0x15, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, + 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0xaf, 0x01, 0x0a, 0x18, + 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x1c, 0x0a, - 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x63, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, - 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, - 0x3a, 0x0a, 0x0f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x68, 0x61, 0x72, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x4b, - 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x4b, 0x38, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x68, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x61, 0x78, 0x12, 0x3e, 0x0a, 0x1a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x1a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x41, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x22, 0x32, 0x0a, 0x16, 0x49, + 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x35, 0x0a, + 0x19, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x22, 0x28, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x49, + 0x0a, 0x03, 0x47, 0x76, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x6d, 0x0a, 0x0e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x03, 0x67, + 0x76, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x04, 0x2e, 0x47, 0x76, 0x6b, 0x52, 0x03, + 0x67, 0x76, 0x6b, 0x12, 0x43, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, + 0x37, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x54, 0x72, 0x65, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x2a, + 0x0a, 0x12, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x32, 0xf6, 0x09, 0x0a, 0x12, 0x41, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x39, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, + 0x64, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x11, 0x2e, 0x41, + 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x00, 0x12, 0x2f, 0x0a, + 0x0c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, + 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x34, + 0x0a, 0x09, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, + 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, + 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0b, 0x55, 0x6e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, + 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x14, + 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, + 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, + 0x72, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, + 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, + 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x10, 0x55, 0x6e, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, + 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x1a, 0x19, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, + 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x2e, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, - 0x29, 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x74, 0x0a, 0x16, 0x52, 0x6f, - 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x1b, 0x55, 0x70, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x12, 0x49, 0x73, 0x52, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0x45, 0x0a, 0x15, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x4d, - 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0xaf, 0x01, 0x0a, 0x18, 0x48, 0x65, 0x6c, 0x6d, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, - 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x31, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x68, 0x61, - 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x72, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x19, 0x48, 0x65, 0x6c, - 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x22, 0x28, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x49, 0x0a, 0x03, 0x47, 0x76, - 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x6d, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x03, 0x67, 0x76, 0x6b, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x04, 0x2e, 0x47, 0x76, 0x6b, 0x52, 0x03, 0x67, 0x76, 0x6b, 0x12, - 0x43, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x72, 0x65, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0c, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x52, 0x0c, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, - 0x39, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x43, 0x68, - 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x32, 0xf6, 0x09, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, - 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x0f, 0x2e, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, 0x70, - 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, - 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x70, - 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, - 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, - 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x48, 0x69, - 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48, 0x69, 0x62, - 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x36, 0x0a, 0x0b, 0x55, 0x6e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x12, - 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, - 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x00, - 0x12, 0x32, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, - 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, - 0x66, 0x6f, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x65, 0x73, 0x69, 0x72, - 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x2e, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x44, 0x65, 0x73, - 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x10, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x19, - 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, - 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x19, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, - 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x69, 0x65, 0x72, 0x1a, 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x17, 0x2e, 0x52, 0x6f, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x1d, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, + 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x48, 0x65, + 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x1b, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x68, 0x61, 0x72, 0x74, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, - 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x12, 0x49, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, - 0x73, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x2e, 0x52, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, - 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x17, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, - 0x68, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x54, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x1d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x1d, 0x55, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, - 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x55, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, - 0x76, 0x74, 0x72, 0x6f, 0x6e, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x6c, - 0x69, 0x6e, 0x6b, 0x2f, 0x62, 0x65, 0x61, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x52, 0x0a, 0x1d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x74, 0x72, 0x6f, 0x6e, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6b, + 0x75, 0x62, 0x65, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x62, 0x65, 0x61, 0x6e, 0x2f, 0x67, 0x72, 0x70, + 0x63, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/helm-app/applist.proto b/api/helm-app/applist.proto index 6413e68173..a3efbcdd80 100644 --- a/api/helm-app/applist.proto +++ b/api/helm-app/applist.proto @@ -76,6 +76,7 @@ message AppDetail{ ChartMetadata chartMetadata = 7; ResourceTreeResponse resourceTreeResponse = 8; EnvironmentDetails environmentDetails = 9; + bool ReleaseExist = 10; } message AppStatus{ diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index c18b230e03..33555031ec 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1095,7 +1095,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h impl.logger.Errorw("error in fetching app detail", "err", err) } - if detail != nil { + if detail != nil && detail.ReleaseExist { resourceTree = util3.InterfaceToMapAdapter(detail.ResourceTreeResponse) resourceTree["status"] = detail.ApplicationStatus appDetailsContainer.Notes = detail.ChartMetadata.Notes @@ -1111,10 +1111,14 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h impl.logger.Errorw("error in unmarshalling helm release install status") } if !helmInstallStatus.IsReleaseInstalled { - releaseStatus.Status = "Release Install Failed" + releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release for this app doesn't exist" } + } else { + releaseStatus.Status = "Unknown" + releaseStatus.Description = "Release not found" + releaseStatus.Message = "Release not found " } releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap diff --git a/scripts/sql/166_helm_async_install.down.sql b/scripts/sql/166_helm_async_install.down.sql new file mode 100644 index 0000000000..8ee320f48b --- /dev/null +++ b/scripts/sql/166_helm_async_install.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE installed_app_version_history +DROP COLUMN IF EXISTS helm_release_status_config; \ No newline at end of file diff --git a/scripts/sql/166_helm_async_install.up.sql b/scripts/sql/166_helm_async_install.up.sql new file mode 100644 index 0000000000..3a84d223b2 --- /dev/null +++ b/scripts/sql/166_helm_async_install.up.sql @@ -0,0 +1,3 @@ +alter table installed_app_version_history + add column helm_release_status_config text; + From 74978cc2a0e0761caa5d5ca7a62c9d50d793fe7e Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Wed, 30 Aug 2023 12:56:47 +0530 Subject: [PATCH 06/35] fix update --- App.go | 2 +- .../service/AppStoreDeploymentService.go | 47 ++++++++----------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/App.go b/App.go index be7ea192a3..16ec1458d5 100644 --- a/App.go +++ b/App.go @@ -83,7 +83,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8080 //TODO: extract from environment variable + port := 8081 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index f1f45a6ff8..ea384575af 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -535,7 +535,7 @@ func (impl AppStoreDeploymentServiceImpl) UpdateInstallAppVersionHistory(install installedAppVersionHistory.Status = "Unknown" installedAppVersionHistory, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) if err != nil { - impl.logger.Errorw("error while fetching from db", "error", err) + impl.logger.Errorw("error while creating installed app version history", "error", err) return nil, err } err = tx.Commit() @@ -1399,36 +1399,29 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex installAppVersionRequest.EnvironmentName = installedApp.Environment.Name installAppVersionRequest.Environment = &installedApp.Environment + // creating installed app version history installAppVersionHistoryStatus := "Unknown" if util.IsAcdApp(installedApp.DeploymentAppType) || util.IsManifestDownload(installedApp.DeploymentAppType) { installAppVersionHistoryStatus = pipelineConfig.WorkflowInProgress - installedAppVersionHistory := &repository.InstalledAppVersionHistory{ - InstalledAppVersionId: installedAppVersion.Id, - ValuesYamlRaw: installAppVersionRequest.ValuesOverrideYaml, - StartedOn: time.Now(), - Status: installAppVersionHistoryStatus, - AuditLog: sql.AuditLog{ - CreatedOn: time.Now(), - CreatedBy: installAppVersionRequest.UserId, - UpdatedOn: time.Now(), - UpdatedBy: installAppVersionRequest.UserId, - }, - } - _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) - if err != nil { - impl.logger.Errorw("error while creating installed app version history for updating installed app", "error", err) - return nil, err - } - _ = impl.appStoreDeploymentArgoCdService.SaveTimelineForACDHelmApps(installAppVersionRequest, pipelineConfig.TIMELINE_STATUS_DEPLOYMENT_INITIATED, "Deployment initiated successfully.", tx) - } else { - // create build history for chart on default component deployed via helm - installedAppVersionHistory, err := impl.UpdateInstallAppVersionHistory(installAppVersionRequest) - if err != nil { - impl.logger.Errorw("error on creating history for chart deployment", "error", err, "installedAppVersion", installedAppVersion) - return nil, err - } - installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id } + installedAppVersionHistory := &repository.InstalledAppVersionHistory{ + InstalledAppVersionId: installedAppVersion.Id, + ValuesYamlRaw: installAppVersionRequest.ValuesOverrideYaml, + StartedOn: time.Now(), + Status: installAppVersionHistoryStatus, + AuditLog: sql.AuditLog{ + CreatedOn: time.Now(), + CreatedBy: installAppVersionRequest.UserId, + UpdatedOn: time.Now(), + UpdatedBy: installAppVersionRequest.UserId, + }, + } + _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) + if err != nil { + impl.logger.Errorw("error while creating installed app version history for updating installed app", "error", err) + return nil, err + } + _ = impl.appStoreDeploymentArgoCdService.SaveTimelineForACDHelmApps(installAppVersionRequest, pipelineConfig.TIMELINE_STATUS_DEPLOYMENT_INITIATED, "Deployment initiated successfully.", tx) manifest, err := impl.appStoreDeploymentCommonService.GenerateManifest(installAppVersionRequest) if err != nil { From ccb238528197c297b88a1acfb2970a509910fa8e Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Wed, 30 Aug 2023 13:15:33 +0530 Subject: [PATCH 07/35] wip --- .../deployment/service/AppStoreDeploymentService.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index ea384575af..ac2dd6c457 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1399,11 +1399,8 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex installAppVersionRequest.EnvironmentName = installedApp.Environment.Name installAppVersionRequest.Environment = &installedApp.Environment - // creating installed app version history installAppVersionHistoryStatus := "Unknown" - if util.IsAcdApp(installedApp.DeploymentAppType) || util.IsManifestDownload(installedApp.DeploymentAppType) { - installAppVersionHistoryStatus = pipelineConfig.WorkflowInProgress - } + installAppVersionHistoryStatus = pipelineConfig.WorkflowInProgress installedAppVersionHistory := &repository.InstalledAppVersionHistory{ InstalledAppVersionId: installedAppVersion.Id, ValuesYamlRaw: installAppVersionRequest.ValuesOverrideYaml, @@ -1421,6 +1418,7 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex impl.logger.Errorw("error while creating installed app version history for updating installed app", "error", err) return nil, err } + installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id _ = impl.appStoreDeploymentArgoCdService.SaveTimelineForACDHelmApps(installAppVersionRequest, pipelineConfig.TIMELINE_STATUS_DEPLOYMENT_INITIATED, "Deployment initiated successfully.", tx) manifest, err := impl.appStoreDeploymentCommonService.GenerateManifest(installAppVersionRequest) From 07f6954a8d4181de01f9f1eb01ab3bc20b1764d0 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Wed, 30 Aug 2023 14:56:29 +0530 Subject: [PATCH 08/35] wip --- App.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App.go b/App.go index 16ec1458d5..be7ea192a3 100644 --- a/App.go +++ b/App.go @@ -83,7 +83,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8081 //TODO: extract from environment variable + port := 8080 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) From 477430754552591622c5087f711fc5966a73db81 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 11 Sep 2023 02:21:56 +0530 Subject: [PATCH 09/35] wip --- .../deployment/service/AppStoreDeploymentService.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index ac2dd6c457..138fb04a6f 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1060,14 +1060,6 @@ func (impl AppStoreDeploymentServiceImpl) installAppPostDbOperation(installAppVe } } - if installAppVersionRequest.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_MANIFEST_DOWNLOAD { - err = impl.UpdateInstalledAppVersionHistoryStatus(installAppVersionRequest, pipelineConfig.WorkflowSucceeded) - if err != nil { - impl.logger.Errorw("error on creating history for chart deployment", "error", err) - return err - } - } - return nil } @@ -1689,7 +1681,9 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) return } - + if !helmInstallNatsMessage.IsReleaseInstalled { + installedAppVersionHistory.Status = "Failed" + } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(installedAppVersionHistory, nil) if err != nil { From 98284099aa138f90a02e9c71940af99583e44ab9 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 11 Sep 2023 02:43:53 +0530 Subject: [PATCH 10/35] pr review changes --- .../deployment/service/InstalledAppService.go | 41 +++++++++++-------- scripts/sql/166_helm_async_install.up.sql | 2 + 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index e61fa6fd6f..4453c477e1 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1103,23 +1103,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h appDetailsContainer.ReleaseStatus = releaseStatus impl.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", installedApp.App.AppName, "env", installedApp.Environment.Name) } else { - releaseStatus := &client.ReleaseStatus{} - if len(helmReleaseInstallStatus) > 0 { - helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} - err := json.Unmarshal([]byte(helmReleaseInstallStatus), helmInstallStatus) - if err != nil { - impl.logger.Errorw("error in unmarshalling helm release install status") - } - if !helmInstallStatus.IsReleaseInstalled { - releaseStatus.Status = "Failed" - releaseStatus.Description = helmInstallStatus.Message - releaseStatus.Message = "Release for this app doesn't exist" - } - } else { - releaseStatus.Status = "Unknown" - releaseStatus.Description = "Release not found" - releaseStatus.Message = "Release not found " - } + releaseStatus := impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap } @@ -1136,6 +1120,29 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h return err } +func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus string) *client.ReleaseStatus { + //release status is sent in resource tree call and is shown on UI as helm config apply status + releaseStatus := &client.ReleaseStatus{} + if len(helmReleaseInstallStatus) > 0 { + helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} + err := json.Unmarshal([]byte(helmReleaseInstallStatus), helmInstallStatus) + if err != nil { + impl.logger.Errorw("error in unmarshalling helm release install status") + return releaseStatus + } + if !helmInstallStatus.IsReleaseInstalled { + releaseStatus.Status = "Failed" + releaseStatus.Description = helmInstallStatus.Message + releaseStatus.Message = "Release for this app doesn't exist" + } + } else { + releaseStatus.Status = "Unknown" + releaseStatus.Description = "Release not found" + releaseStatus.Message = "Release not found " + } + return releaseStatus +} + func (impl InstalledAppServiceImpl) MarkGitOpsInstalledAppsDeletedIfArgoAppIsDeleted(installedAppId int, envId int) error { apiError := &util.ApiError{} installedApp, err := impl.installedAppRepository.GetGitOpsInstalledAppsWhereArgoAppDeletedIsTrue(installedAppId, envId) diff --git a/scripts/sql/166_helm_async_install.up.sql b/scripts/sql/166_helm_async_install.up.sql index 3a84d223b2..5e87ac2cf2 100644 --- a/scripts/sql/166_helm_async_install.up.sql +++ b/scripts/sql/166_helm_async_install.up.sql @@ -1,3 +1,5 @@ + alter table installed_app_version_history add column helm_release_status_config text; +-- helm_release_status_config - {InstallAppVersionHistoryId: "", ReleaseInstalled: "true/false", Message: "failure reason" } From aa58994091fa5c21a7a737fd3c0dc9c3a14a1bb2 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 11 Sep 2023 10:53:49 +0530 Subject: [PATCH 11/35] wip --- pkg/appStore/deployment/service/AppStoreDeploymentService.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 138fb04a6f..550a06818e 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1667,8 +1667,7 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { callback := func(msg *pubsub.PubSubMsg) { - impl.logger.Debug("received helm install status event") - impl.logger.Debugw("HELM_INSTALL_STATUS", "data", msg.Data) + impl.logger.Debug("received helm install status event - HELM_INSTALL_STATUS", "data", msg.Data) helmInstallNatsMessage := &appStoreBean.HelmInstallNatsMessage{} err := json.Unmarshal([]byte(msg.Data), helmInstallNatsMessage) if err != nil { From c1f5feb0b7eb252f8c5e457d59e2d797f5bcaea7 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 11 Sep 2023 11:26:10 +0530 Subject: [PATCH 12/35] wip --- .../service/AppStoreDeploymentService.go | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 550a06818e..d4f0e4f12a 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -75,6 +75,7 @@ type AppStoreDeploymentService interface { UpdateNotesForInstalledApp(installAppId int, notes string) (bool, error) UpdatePreviousDeploymentStatusForAppStore(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, triggeredAt time.Time, err error) error SubscribeHelmInstallStatus() error + UpdateInstallAppVersionHistoryStatus(installedAppVersionHistoryId int, status string) error } type DeploymentServiceTypeConfig struct { @@ -1059,6 +1060,13 @@ func (impl AppStoreDeploymentServiceImpl) installAppPostDbOperation(installAppVe return err } } + if util.IsHelmApp(installAppVersionRequest.DeploymentAppType) { + err = impl.UpdateInstallAppVersionHistoryStatus(installAppVersionRequest.InstalledAppVersionHistoryId, "Succeeded") + if err != nil { + impl.logger.Errorw("error in updating installed app version history status for helm app") + return err + } + } return nil } @@ -1698,3 +1706,26 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { } return nil } + +func (impl AppStoreDeploymentServiceImpl) UpdateInstallAppVersionHistoryStatus(installedAppVersionHistoryId int, status string) error { + dbConnection := impl.installedAppRepository.GetConnection() + tx, err := dbConnection.Begin() + if err != nil { + return err + } + // Rollback tx on error. + defer tx.Rollback() + savedInstalledAppVersionHistory, err := impl.installedAppRepositoryHistory.GetInstalledAppVersionHistory(installedAppVersionHistoryId) + savedInstalledAppVersionHistory.Status = status + _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(savedInstalledAppVersionHistory, tx) + if err != nil { + impl.logger.Errorw("error while fetching from db", "error", err) + return err + } + err = tx.Commit() + if err != nil { + impl.logger.Errorw("error while committing transaction to db", "error", err) + return err + } + return nil +} From 885292b25cb0b027812038acddea2120754c00d3 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Mon, 11 Sep 2023 11:47:57 +0530 Subject: [PATCH 13/35] wip --- .../deployment/service/AppStoreDeploymentService.go | 10 ++-------- pkg/appStore/deployment/service/InstalledAppService.go | 6 ++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index d4f0e4f12a..9d3459b687 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1060,14 +1060,6 @@ func (impl AppStoreDeploymentServiceImpl) installAppPostDbOperation(installAppVe return err } } - if util.IsHelmApp(installAppVersionRequest.DeploymentAppType) { - err = impl.UpdateInstallAppVersionHistoryStatus(installAppVersionRequest.InstalledAppVersionHistoryId, "Succeeded") - if err != nil { - impl.logger.Errorw("error in updating installed app version history status for helm app") - return err - } - } - return nil } @@ -1690,6 +1682,8 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { } if !helmInstallNatsMessage.IsReleaseInstalled { installedAppVersionHistory.Status = "Failed" + } else if helmInstallNatsMessage.IsReleaseInstalled { + installedAppVersionHistory.Status = "Succeeded" } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(installedAppVersionHistory, nil) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 4453c477e1..5608119f9d 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1103,6 +1103,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h appDetailsContainer.ReleaseStatus = releaseStatus impl.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", installedApp.App.AppName, "env", installedApp.Environment.Name) } else { + // case when helm release is not created releaseStatus := impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap @@ -1134,6 +1135,11 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release for this app doesn't exist" + } else { + // there can be a case when helm release is created but we are not able to fetch it + releaseStatus.Status = "Unknown" + releaseStatus.Description = "Unable to fetch release for app" + releaseStatus.Message = "Unable to fetch release for app" } } else { releaseStatus.Status = "Unknown" From 266f3860fe1be3fc30981a770124558e9ba750d9 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 14 Sep 2023 17:00:21 +0530 Subject: [PATCH 14/35] not marking previous deployment failed --- pkg/appStore/bean/bean.go | 1 + .../deployment/service/AppStoreDeploymentService.go | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/appStore/bean/bean.go b/pkg/appStore/bean/bean.go index 8c28cae270..581f7905d3 100644 --- a/pkg/appStore/bean/bean.go +++ b/pkg/appStore/bean/bean.go @@ -375,4 +375,5 @@ type HelmInstallNatsMessage struct { InstallAppVersionHistoryId int Message string IsReleaseInstalled bool + ErrorInInstallation bool } diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 9d3459b687..d4286d62bd 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1655,6 +1655,9 @@ func (impl AppStoreDeploymentServiceImpl) UpdateProjectHelmApp(updateAppRequest func (impl AppStoreDeploymentServiceImpl) UpdatePreviousDeploymentStatusForAppStore(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, triggeredAt time.Time, err error) error { //creating pipeline status timeline for deployment failed + if !util.IsAcdApp(installAppVersionRequest.DeploymentAppType) { + return nil + } err1 := impl.appStoreDeploymentArgoCdService.UpdateInstalledAppAndPipelineStatusForFailedDeploymentStatus(installAppVersionRequest, triggeredAt, err) if err1 != nil { impl.logger.Errorw("error in updating previous deployment status for appStore", "err", err1, "installAppVersionRequest", installAppVersionRequest) @@ -1680,9 +1683,10 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) return } - if !helmInstallNatsMessage.IsReleaseInstalled { + + if !helmInstallNatsMessage.ErrorInInstallation { installedAppVersionHistory.Status = "Failed" - } else if helmInstallNatsMessage.IsReleaseInstalled { + } else if helmInstallNatsMessage.ErrorInInstallation { installedAppVersionHistory.Status = "Succeeded" } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data From 0469bf591a15f4ac2e58cae660ea67d3502ca6cc Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 14 Sep 2023 19:02:43 +0530 Subject: [PATCH 15/35] fixing nats message --- pkg/appStore/deployment/service/AppStoreDeploymentService.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 1ac97fc1b8..97da9a6cbe 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1698,9 +1698,9 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { return } - if !helmInstallNatsMessage.ErrorInInstallation { + if helmInstallNatsMessage.ErrorInInstallation { installedAppVersionHistory.Status = "Failed" - } else if helmInstallNatsMessage.ErrorInInstallation { + } else if !helmInstallNatsMessage.ErrorInInstallation { installedAppVersionHistory.Status = "Succeeded" } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data From 973c671d5c1e528c231b303310385df7cc679cb3 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 15 Sep 2023 10:03:54 +0530 Subject: [PATCH 16/35] wip --- App.go | 2 +- .../deployment/service/InstalledAppService.go | 35 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/App.go b/App.go index bb55b4700b..ff250a25c0 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8080 //TODO: extract from environment variable + port := 8081 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 5b954a76c4..6bd0ae0f3c 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1101,12 +1101,41 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h impl.logger.Errorw("error in fetching app detail", "err", err) } + /* helmReleaseInstallStatus is nats message sent from kubelink to orchestrator and has the following details about installation :- + 1) isReleaseInstalled -> whether release object is created or not in this installation + 2) ErrorInInstallation -> if there is error in installation + 3) Message -> error message/ success message + 4) InstallAppVersionHistoryId + */ + if detail != nil && detail.ReleaseExist { + resourceTree = util3.InterfaceToMapAdapter(detail.ResourceTreeResponse) resourceTree["status"] = detail.ApplicationStatus appDetailsContainer.Notes = detail.ChartMetadata.Notes - releaseStatus := util3.InterfaceToMapAdapter(detail.ReleaseStatus) - appDetailsContainer.ReleaseStatus = releaseStatus + + helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} + releaseStatus := detail.ReleaseStatus + + if len(helmReleaseInstallStatus) > 0 { + err := json.Unmarshal([]byte(helmReleaseInstallStatus), helmInstallStatus) + if err != nil { + impl.logger.Errorw("error in unmarshalling helm release install status") + return err + } + // ReleaseExist=true in app detail container but helm install status says that isReleaseInstalled=false which means this release was created externally + if helmInstallStatus.IsReleaseInstalled == false { + /* + Handling case when :- + 1) An external release with name "foo" exist + 2) User creates an app with same name i.e "foo" + 3) In this case we use helmReleaseInstallStatus which will have status of our release and not external release + */ + releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) + } + } + releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) + appDetailsContainer.ReleaseStatus = releaseStatusMap impl.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", installedApp.App.AppName, "env", installedApp.Environment.Name) } else { // case when helm release is not created @@ -1137,7 +1166,7 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus impl.logger.Errorw("error in unmarshalling helm release install status") return releaseStatus } - if !helmInstallStatus.IsReleaseInstalled { + if helmInstallStatus.ErrorInInstallation { releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release for this app doesn't exist" From 70ab4d4d9d040dfc8584d529f6b34e6686b5dd27 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 15 Sep 2023 11:12:53 +0530 Subject: [PATCH 17/35] wip --- pkg/appStore/deployment/service/InstalledAppService.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 6bd0ae0f3c..515bac849e 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1136,7 +1136,6 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h } releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap - impl.logger.Warnw("appName and envName not found - avoiding resource tree call", "app", installedApp.App.AppName, "env", installedApp.Environment.Name) } else { // case when helm release is not created releaseStatus := impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) From b8d551a776d851d385a35b7d255d8bc329103040 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 15 Sep 2023 11:48:53 +0530 Subject: [PATCH 18/35] wip --- App.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App.go b/App.go index ff250a25c0..bb55b4700b 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8081 //TODO: extract from environment variable + port := 8080 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) From 1c81d964647d104105291463b934be39a468be83 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 15 Sep 2023 12:33:09 +0530 Subject: [PATCH 19/35] argo asset files --- .../service/AppStoreDeploymentService.go | 1 + .../argoproj/argo-cd/assets/badge.svg | 22 + .../argo-cd/assets/builtin-policy.csv | 34 + .../argoproj/argo-cd/assets/model.conf | 14 + .../argoproj/argo-cd/assets/swagger.json | 3887 +++++++++++++++++ 5 files changed, 3958 insertions(+) create mode 100644 vendor/github.com/argoproj/argo-cd/assets/badge.svg create mode 100644 vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv create mode 100644 vendor/github.com/argoproj/argo-cd/assets/model.conf create mode 100644 vendor/github.com/argoproj/argo-cd/assets/swagger.json diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 97da9a6cbe..d3ba7cd2eb 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1382,6 +1382,7 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex if err != nil { return nil, err } + installedAppVersion.Id = installedAppVersion.Id } else { installedAppVersion.ValuesYaml = installAppVersionRequest.ValuesOverrideYaml installedAppVersion.UpdatedOn = time.Now() diff --git a/vendor/github.com/argoproj/argo-cd/assets/badge.svg b/vendor/github.com/argoproj/argo-cd/assets/badge.svg new file mode 100644 index 0000000000..a3234cfdf5 --- /dev/null +++ b/vendor/github.com/argoproj/argo-cd/assets/badge.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv b/vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv new file mode 100644 index 0000000000..f74c5b8002 --- /dev/null +++ b/vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv @@ -0,0 +1,34 @@ +# Built-in policy which defines two roles: role:readonly and role:admin, +# and additionally assigns the admin user to the role:admin role. +# There are two policy formats: +# 1. Applications (which belong to a project): +# p, , , , / +# 2. All other resources: +# p, , , , + +p, role:readonly, applications, get, */*, allow +p, role:readonly, certificates, get, *, allow +p, role:readonly, clusters, get, *, allow +p, role:readonly, repositories, get, *, allow +p, role:readonly, projects, get, *, allow + +p, role:admin, applications, create, */*, allow +p, role:admin, applications, update, */*, allow +p, role:admin, applications, delete, */*, allow +p, role:admin, applications, sync, */*, allow +p, role:admin, applications, override, */*, allow +p, role:admin, certificates, create, *, allow +p, role:admin, certificates, update, *, allow +p, role:admin, certificates, delete, *, allow +p, role:admin, clusters, create, *, allow +p, role:admin, clusters, update, *, allow +p, role:admin, clusters, delete, *, allow +p, role:admin, repositories, create, *, allow +p, role:admin, repositories, update, *, allow +p, role:admin, repositories, delete, *, allow +p, role:admin, projects, create, *, allow +p, role:admin, projects, update, *, allow +p, role:admin, projects, delete, *, allow + +g, role:admin, role:readonly +g, admin, role:admin \ No newline at end of file diff --git a/vendor/github.com/argoproj/argo-cd/assets/model.conf b/vendor/github.com/argoproj/argo-cd/assets/model.conf new file mode 100644 index 0000000000..240a9180d3 --- /dev/null +++ b/vendor/github.com/argoproj/argo-cd/assets/model.conf @@ -0,0 +1,14 @@ +[request_definition] +r = sub, res, act, obj + +[policy_definition] +p = sub, res, act, obj, eft + +[role_definition] +g = _, _ + +[policy_effect] +e = some(where (p.eft == allow)) && !some(where (p.eft == deny)) + +[matchers] +m = g(r.sub, p.sub) && keyMatch(r.res, p.res) && keyMatch(r.act, p.act) && keyMatch(r.obj, p.obj) \ No newline at end of file diff --git a/vendor/github.com/argoproj/argo-cd/assets/swagger.json b/vendor/github.com/argoproj/argo-cd/assets/swagger.json new file mode 100644 index 0000000000..0ad53c18de --- /dev/null +++ b/vendor/github.com/argoproj/argo-cd/assets/swagger.json @@ -0,0 +1,3887 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "http", + "https" + ], + "swagger": "2.0", + "info": { + "description": "Description of all APIs", + "title": "Consolidate Services", + "version": "version not set" + }, + "paths": { + "/api/v1/account/password": { + "put": { + "tags": [ + "AccountService" + ], + "summary": "UpdatePassword updates an account's password to a new value", + "operationId": "UpdatePassword", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/accountUpdatePasswordRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/accountUpdatePasswordResponse" + } + } + } + } + }, + "/api/v1/applications": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "List returns list of applications", + "operationId": "ListMixin6", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "string", + "name": "refresh", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "name": "project", + "in": "query" + }, + { + "type": "string", + "name": "resourceVersion", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1ApplicationList" + } + } + } + }, + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "Create creates an application", + "operationId": "CreateMixin6", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + } + }, + "/api/v1/applications/{application.metadata.name}": { + "put": { + "tags": [ + "ApplicationService" + ], + "summary": "Update updates an application", + "operationId": "UpdateMixin6", + "parameters": [ + { + "type": "string", + "name": "application.metadata.name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + } + }, + "/api/v1/applications/{applicationName}/managed-resources": { + "get": { + "tags": [ + "ApplicationService" + ], + "operationId": "ManagedResources", + "parameters": [ + { + "type": "string", + "name": "applicationName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationManagedResourcesResponse" + } + } + } + } + }, + "/api/v1/applications/{applicationName}/resource-tree": { + "get": { + "tags": [ + "ApplicationService" + ], + "operationId": "ResourceTree", + "parameters": [ + { + "type": "string", + "name": "applicationName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1ApplicationTree" + } + } + } + } + }, + "/api/v1/applications/{name}": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "Get returns an application by name", + "operationId": "GetMixin6", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "refresh", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "name": "project", + "in": "query" + }, + { + "type": "string", + "name": "resourceVersion", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + }, + "delete": { + "tags": [ + "ApplicationService" + ], + "summary": "Delete deletes an application", + "operationId": "DeleteMixin6", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationApplicationResponse" + } + } + } + }, + "patch": { + "tags": [ + "ApplicationService" + ], + "summary": "Patch patch an application", + "operationId": "Patch", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/applicationApplicationPatchRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + } + }, + "/api/v1/applications/{name}/events": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "ListResourceEvents returns a list of event resources", + "operationId": "ListResourceEvents", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "resourceNamespace", + "in": "query" + }, + { + "type": "string", + "name": "resourceName", + "in": "query" + }, + { + "type": "string", + "name": "resourceUID", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1EventList" + } + } + } + } + }, + "/api/v1/applications/{name}/manifests": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "GetManifests returns application manifests", + "operationId": "GetManifests", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "revision", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/repositoryManifestResponse" + } + } + } + } + }, + "/api/v1/applications/{name}/operation": { + "delete": { + "tags": [ + "ApplicationService" + ], + "summary": "TerminateOperation terminates the currently running operation", + "operationId": "TerminateOperation", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationOperationTerminateResponse" + } + } + } + } + }, + "/api/v1/applications/{name}/pods/{podName}/logs": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "PodLogs returns stream of log entries for the specified pod. Pod", + "operationId": "PodLogs", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "podName", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "container", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "name": "sinceSeconds", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "Represents seconds of UTC time since Unix epoch\n1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to\n9999-12-31T23:59:59Z inclusive.", + "name": "sinceTime.seconds", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "Non-negative fractions of a second at nanosecond resolution. Negative\nsecond values with fractions must still have non-negative nanos values\nthat count forward in time. Must be from 0 to 999,999,999\ninclusive. This field may be limited in precision depending on context.", + "name": "sinceTime.nanos", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "name": "tailLines", + "in": "query" + }, + { + "type": "boolean", + "format": "boolean", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(streaming responses)", + "schema": { + "$ref": "#/definitions/applicationLogEntry" + } + } + } + } + }, + "/api/v1/applications/{name}/resource": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "GetResource returns single application resource", + "operationId": "GetResource", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "resourceName", + "in": "query" + }, + { + "type": "string", + "name": "version", + "in": "query" + }, + { + "type": "string", + "name": "group", + "in": "query" + }, + { + "type": "string", + "name": "kind", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationApplicationResourceResponse" + } + } + } + }, + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "PatchResource patch single application resource", + "operationId": "PatchResource", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationApplicationResourceResponse" + } + } + } + }, + "delete": { + "tags": [ + "ApplicationService" + ], + "summary": "DeleteResource deletes a single application resource", + "operationId": "DeleteResource", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationApplicationResponse" + } + } + } + } + }, + "/api/v1/applications/{name}/resource/actions": { + "get": { + "tags": [ + "ApplicationService" + ], + "operationId": "ListResourceActions", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "resourceName", + "in": "query" + }, + { + "type": "string", + "name": "version", + "in": "query" + }, + { + "type": "string", + "name": "group", + "in": "query" + }, + { + "type": "string", + "name": "kind", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationResourceActionsListResponse" + } + } + } + }, + "post": { + "tags": [ + "ApplicationService" + ], + "operationId": "RunResourceAction", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/applicationApplicationResponse" + } + } + } + } + }, + "/api/v1/applications/{name}/revisions/{revision}/metadata": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "Get the meta-data (author, date, tags, message) for a specific revision of the application", + "operationId": "RevisionMetadata", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "revision", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1RevisionMetadata" + } + } + } + } + }, + "/api/v1/applications/{name}/rollback": { + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "Rollback syncs an application to its target state", + "operationId": "Rollback", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/applicationApplicationRollbackRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + } + }, + "/api/v1/applications/{name}/spec": { + "put": { + "tags": [ + "ApplicationService" + ], + "summary": "UpdateSpec updates an application spec", + "operationId": "UpdateSpec", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1ApplicationSpec" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1ApplicationSpec" + } + } + } + } + }, + "/api/v1/applications/{name}/sync": { + "post": { + "tags": [ + "ApplicationService" + ], + "summary": "Sync syncs an application to its target state", + "operationId": "Sync", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/applicationApplicationSyncRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Application" + } + } + } + } + }, + "/api/v1/certificates": { + "get": { + "tags": [ + "CertificateService" + ], + "summary": "List all available repository certificates", + "operationId": "ListCertificates", + "parameters": [ + { + "type": "string", + "description": "A file-glob pattern (not regular expression) the host name has to match.", + "name": "hostNamePattern", + "in": "query" + }, + { + "type": "string", + "description": "The type of the certificate to match (ssh or https).", + "name": "certType", + "in": "query" + }, + { + "type": "string", + "description": "The sub type of the certificate to match (protocol dependent, usually only used for ssh certs).", + "name": "certSubType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryCertificateList" + } + } + } + }, + "post": { + "tags": [ + "CertificateService" + ], + "summary": "Creates repository certificates on the server", + "operationId": "CreateCertificate", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryCertificateList" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryCertificateList" + } + } + } + }, + "delete": { + "tags": [ + "CertificateService" + ], + "summary": "Delete the certificates that match the RepositoryCertificateQuery", + "operationId": "DeleteCertificate", + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryCertificateList" + } + } + } + } + }, + "/api/v1/clusters": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "List returns list of clusters", + "operationId": "List", + "parameters": [ + { + "type": "string", + "name": "server", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterList" + } + } + } + }, + "post": { + "tags": [ + "ClusterService" + ], + "summary": "Create creates a cluster", + "operationId": "Create", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + } + } + }, + "/api/v1/clusters/{cluster.server}": { + "put": { + "tags": [ + "ClusterService" + ], + "summary": "Update updates a cluster", + "operationId": "Update", + "parameters": [ + { + "type": "string", + "name": "cluster.server", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + } + } + }, + "/api/v1/clusters/{server}": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "Get returns a cluster by server address", + "operationId": "GetMixin1", + "parameters": [ + { + "type": "string", + "name": "server", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + } + }, + "delete": { + "tags": [ + "ClusterService" + ], + "summary": "Delete deletes a cluster", + "operationId": "Delete", + "parameters": [ + { + "type": "string", + "name": "server", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/clusterClusterResponse" + } + } + } + } + }, + "/api/v1/clusters/{server}/rotate-auth": { + "post": { + "tags": [ + "ClusterService" + ], + "summary": "RotateAuth returns a cluster by server address", + "operationId": "RotateAuth", + "parameters": [ + { + "type": "string", + "name": "server", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/clusterClusterResponse" + } + } + } + } + }, + "/api/v1/projects": { + "get": { + "tags": [ + "ProjectService" + ], + "summary": "List returns list of projects", + "operationId": "ListMixin4", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1AppProjectList" + } + } + } + }, + "post": { + "tags": [ + "ProjectService" + ], + "summary": "Create a new project.", + "operationId": "CreateMixin4", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/projectProjectCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1AppProject" + } + } + } + } + }, + "/api/v1/projects/{name}": { + "get": { + "tags": [ + "ProjectService" + ], + "summary": "Get returns a project by name", + "operationId": "GetMixin4", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1AppProject" + } + } + } + }, + "delete": { + "tags": [ + "ProjectService" + ], + "summary": "Delete deletes a project", + "operationId": "DeleteMixin4", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/projectEmptyResponse" + } + } + } + } + }, + "/api/v1/projects/{name}/events": { + "get": { + "tags": [ + "ProjectService" + ], + "summary": "ListEvents returns a list of project events", + "operationId": "ListEvents", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1EventList" + } + } + } + } + }, + "/api/v1/projects/{project.metadata.name}": { + "put": { + "tags": [ + "ProjectService" + ], + "summary": "Update updates a project", + "operationId": "UpdateMixin4", + "parameters": [ + { + "type": "string", + "name": "project.metadata.name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/projectProjectUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1AppProject" + } + } + } + } + }, + "/api/v1/projects/{project}/roles/{role}/token": { + "post": { + "tags": [ + "ProjectService" + ], + "summary": "Create a new project token.", + "operationId": "CreateToken", + "parameters": [ + { + "type": "string", + "name": "project", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "role", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/projectProjectTokenCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/projectProjectTokenResponse" + } + } + } + } + }, + "/api/v1/projects/{project}/roles/{role}/token/{iat}": { + "delete": { + "tags": [ + "ProjectService" + ], + "summary": "Delete a new project token.", + "operationId": "DeleteToken", + "parameters": [ + { + "type": "string", + "name": "project", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "role", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "int64", + "name": "iat", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/projectEmptyResponse" + } + } + } + } + }, + "/api/v1/repositories": { + "get": { + "tags": [ + "RepositoryService" + ], + "summary": "List returns list of repos", + "operationId": "ListMixin2", + "parameters": [ + { + "type": "string", + "name": "repo", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1RepositoryList" + } + } + } + }, + "post": { + "tags": [ + "RepositoryService" + ], + "summary": "Create creates a repo", + "operationId": "CreateMixin2", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + } + } + } + }, + "/api/v1/repositories/{repo.repo}": { + "put": { + "tags": [ + "RepositoryService" + ], + "summary": "Update updates a repo", + "operationId": "UpdateMixin2", + "parameters": [ + { + "type": "string", + "name": "repo.repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/v1alpha1Repository" + } + } + } + } + }, + "/api/v1/repositories/{repo}": { + "delete": { + "tags": [ + "RepositoryService" + ], + "summary": "Delete deletes a repo", + "operationId": "DeleteMixin2", + "parameters": [ + { + "type": "string", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/repositoryRepoResponse" + } + } + } + } + }, + "/api/v1/repositories/{repo}/apps": { + "get": { + "tags": [ + "RepositoryService" + ], + "summary": "ListApps returns list of apps in the repo", + "operationId": "ListApps", + "parameters": [ + { + "type": "string", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "revision", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/repositoryRepoAppsResponse" + } + } + } + } + }, + "/api/v1/repositories/{repo}/apps/{path}": { + "get": { + "tags": [ + "RepositoryService" + ], + "summary": "GetAppDetails returns application details by given path", + "operationId": "GetAppDetails", + "parameters": [ + { + "type": "string", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "path", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "revision", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "name": "helm.valueFiles", + "in": "query" + }, + { + "type": "string", + "name": "ksonnet.environment", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/repositoryRepoAppDetailsResponse" + } + } + } + } + }, + "/api/v1/repositories/{repo}/validate": { + "post": { + "tags": [ + "RepositoryService" + ], + "summary": "ValidateAccess validates access to a repository with given parameters", + "operationId": "ValidateAccess", + "parameters": [ + { + "type": "string", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/repositoryRepoResponse" + } + } + } + } + }, + "/api/v1/session": { + "post": { + "tags": [ + "SessionService" + ], + "summary": "Create a new JWT for authentication and set a cookie if using HTTP.", + "operationId": "CreateMixin8", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/sessionSessionCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/sessionSessionResponse" + } + } + } + }, + "delete": { + "tags": [ + "SessionService" + ], + "summary": "Delete an existing JWT cookie if using HTTP.", + "operationId": "DeleteMixin8", + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/sessionSessionResponse" + } + } + } + } + }, + "/api/v1/settings": { + "get": { + "tags": [ + "SettingsService" + ], + "summary": "Get returns Argo CD settings", + "operationId": "Get", + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/clusterSettings" + } + } + } + } + }, + "/api/v1/stream/applications": { + "get": { + "tags": [ + "ApplicationService" + ], + "summary": "Watch returns stream of application change events.", + "operationId": "Watch", + "parameters": [ + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "string", + "name": "refresh", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "name": "project", + "in": "query" + }, + { + "type": "string", + "name": "resourceVersion", + "in": "query" + } + ], + "responses": { + "200": { + "description": "(streaming responses)", + "schema": { + "$ref": "#/definitions/v1alpha1ApplicationWatchEvent" + } + } + } + } + }, + "/api/version": { + "get": { + "tags": [ + "VersionService" + ], + "summary": "Version returns version information of the API server", + "operationId": "Version", + "responses": { + "200": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/versionVersionMessage" + } + } + } + } + } + }, + "definitions": { + "accountUpdatePasswordRequest": { + "type": "object", + "properties": { + "currentPassword": { + "type": "string" + }, + "newPassword": { + "type": "string" + } + } + }, + "accountUpdatePasswordResponse": { + "type": "object" + }, + "applicationApplicationPatchRequest": { + "type": "object", + "title": "ApplicationPatchRequest is a request to patch an application", + "properties": { + "name": { + "type": "string" + }, + "patch": { + "type": "string" + }, + "patchType": { + "type": "string" + } + } + }, + "applicationApplicationResourceResponse": { + "type": "object", + "properties": { + "manifest": { + "type": "string" + } + } + }, + "applicationApplicationResponse": { + "type": "object" + }, + "applicationApplicationRollbackRequest": { + "type": "object", + "properties": { + "dryRun": { + "type": "boolean", + "format": "boolean" + }, + "id": { + "type": "string", + "format": "int64" + }, + "name": { + "type": "string" + }, + "prune": { + "type": "boolean", + "format": "boolean" + } + } + }, + "applicationApplicationSyncRequest": { + "type": "object", + "title": "ApplicationSyncRequest is a request to apply the config state to live state", + "properties": { + "dryRun": { + "type": "boolean", + "format": "boolean" + }, + "manifests": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "prune": { + "type": "boolean", + "format": "boolean" + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1SyncOperationResource" + } + }, + "revision": { + "type": "string" + }, + "strategy": { + "$ref": "#/definitions/v1alpha1SyncStrategy" + } + } + }, + "applicationLogEntry": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "timeStamp": { + "$ref": "#/definitions/v1Time" + } + } + }, + "applicationManagedResourcesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceDiff" + } + } + } + }, + "applicationOperationTerminateResponse": { + "type": "object" + }, + "applicationResourceActionsListResponse": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceAction" + } + } + } + }, + "clusterClusterResponse": { + "type": "object" + }, + "clusterConnector": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "clusterDexConfig": { + "type": "object", + "properties": { + "connectors": { + "type": "array", + "items": { + "$ref": "#/definitions/clusterConnector" + } + } + } + }, + "clusterGoogleAnalyticsConfig": { + "type": "object", + "properties": { + "anonymizeUsers": { + "type": "boolean", + "format": "boolean" + }, + "trackingID": { + "type": "string" + } + } + }, + "clusterHelp": { + "type": "object", + "title": "Help settings", + "properties": { + "chatText": { + "type": "string", + "title": "the text for getting chat help, defaults to \"Chat now!\"" + }, + "chatUrl": { + "type": "string", + "title": "the URL for getting chat help, this will typically be your Slack channel for support" + } + } + }, + "clusterOIDCConfig": { + "type": "object", + "properties": { + "cliClientID": { + "type": "string" + }, + "clientID": { + "type": "string" + }, + "issuer": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "clusterSettings": { + "type": "object", + "properties": { + "appLabelKey": { + "type": "string" + }, + "dexConfig": { + "$ref": "#/definitions/clusterDexConfig" + }, + "googleAnalytics": { + "$ref": "#/definitions/clusterGoogleAnalyticsConfig" + }, + "help": { + "$ref": "#/definitions/clusterHelp" + }, + "kustomizeOptions": { + "$ref": "#/definitions/v1alpha1KustomizeOptions" + }, + "oidcConfig": { + "$ref": "#/definitions/clusterOIDCConfig" + }, + "resourceOverrides": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1ResourceOverride" + } + }, + "statusBadgeEnabled": { + "type": "boolean", + "format": "boolean" + }, + "url": { + "type": "string" + } + } + }, + "projectEmptyResponse": { + "type": "object" + }, + "projectProjectCreateRequest": { + "description": "ProjectCreateRequest defines project creation parameters.", + "type": "object", + "properties": { + "project": { + "$ref": "#/definitions/v1alpha1AppProject" + } + } + }, + "projectProjectTokenCreateRequest": { + "description": "ProjectTokenCreateRequest defines project token creation parameters.", + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "expiresIn": { + "type": "string", + "format": "int64", + "title": "expiresIn represents a duration in seconds" + }, + "project": { + "type": "string" + }, + "role": { + "type": "string" + } + } + }, + "projectProjectTokenResponse": { + "description": "ProjectTokenResponse wraps the created token or returns an empty string if deleted.", + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "projectProjectUpdateRequest": { + "type": "object", + "properties": { + "project": { + "$ref": "#/definitions/v1alpha1AppProject" + } + } + }, + "repositoryAppInfo": { + "type": "object", + "title": "AppInfo contains application type and app file path", + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "repositoryDirectoryAppSpec": { + "type": "object", + "title": "DirectoryAppSpec contains directory" + }, + "repositoryHelmAppDetailsQuery": { + "type": "object", + "properties": { + "valueFiles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "repositoryHelmAppSpec": { + "type": "object", + "title": "HelmAppSpec contains helm app name and path in source repo", + "properties": { + "name": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmParameter" + } + }, + "path": { + "type": "string" + }, + "valueFiles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "repositoryKsonnetAppDetailsQuery": { + "type": "object", + "properties": { + "environment": { + "type": "string" + } + } + }, + "repositoryKsonnetAppSpec": { + "type": "object", + "title": "KsonnetAppSpec contains Ksonnet app response\nThis roughly reflects: ksonnet/ksonnet/metadata/app/schema.go", + "properties": { + "environments": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/repositoryKsonnetEnvironment" + } + }, + "name": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1KsonnetParameter" + } + }, + "path": { + "type": "string" + } + } + }, + "repositoryKsonnetEnvironment": { + "type": "object", + "properties": { + "destination": { + "$ref": "#/definitions/repositoryKsonnetEnvironmentDestination" + }, + "k8sVersion": { + "description": "KubernetesVersion is the kubernetes version the targetted cluster is running on.", + "type": "string" + }, + "name": { + "type": "string", + "title": "Name is the user defined name of an environment" + }, + "path": { + "description": "Path is the relative project path containing metadata for this environment.", + "type": "string" + } + } + }, + "repositoryKsonnetEnvironmentDestination": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "title": "Namespace is the namespace of the Kubernetes server that targets should be deployed to" + }, + "server": { + "description": "Server is the Kubernetes server that the cluster is running on.", + "type": "string" + } + } + }, + "repositoryKustomizeAppSpec": { + "type": "object", + "title": "KustomizeAppSpec contains kustomize app name and path in source repo", + "properties": { + "images": { + "description": "images is a list of available images.", + "type": "array", + "items": { + "type": "string" + } + }, + "path": { + "type": "string" + } + } + }, + "repositoryManifestResponse": { + "type": "object", + "properties": { + "manifests": { + "type": "array", + "items": { + "type": "string" + } + }, + "namespace": { + "type": "string" + }, + "revision": { + "type": "string" + }, + "server": { + "type": "string" + }, + "sourceType": { + "type": "string" + } + } + }, + "repositoryRepoAppDetailsResponse": { + "type": "object", + "title": "RepoAppDetailsResponse application details", + "properties": { + "directory": { + "$ref": "#/definitions/repositoryDirectoryAppSpec" + }, + "helm": { + "$ref": "#/definitions/repositoryHelmAppSpec" + }, + "ksonnet": { + "$ref": "#/definitions/repositoryKsonnetAppSpec" + }, + "kustomize": { + "$ref": "#/definitions/repositoryKustomizeAppSpec" + }, + "type": { + "type": "string" + } + } + }, + "repositoryRepoAppsResponse": { + "type": "object", + "title": "RepoAppsResponse contains applications of specified repository", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/repositoryAppInfo" + } + } + } + }, + "repositoryRepoResponse": { + "type": "object" + }, + "sessionSessionCreateRequest": { + "description": "SessionCreateRequest is for logging in.", + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "token": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "sessionSessionResponse": { + "description": "SessionResponse wraps the created token or returns an empty string if deleted.", + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "v1Event": { + "description": "Event is a report of an event somewhere in the cluster.", + "type": "object", + "properties": { + "action": { + "type": "string", + "title": "What action was taken/failed regarding to the Regarding object.\n+optional" + }, + "count": { + "type": "integer", + "format": "int32", + "title": "The number of times this event has occurred.\n+optional" + }, + "eventTime": { + "$ref": "#/definitions/v1MicroTime" + }, + "firstTimestamp": { + "$ref": "#/definitions/v1Time" + }, + "involvedObject": { + "$ref": "#/definitions/v1ObjectReference" + }, + "lastTimestamp": { + "$ref": "#/definitions/v1Time" + }, + "message": { + "type": "string", + "title": "A human-readable description of the status of this operation.\nTODO: decide on maximum length.\n+optional" + }, + "metadata": { + "$ref": "#/definitions/v1ObjectMeta" + }, + "reason": { + "type": "string", + "title": "This should be a short, machine understandable string that gives the reason\nfor the transition into the object's current status.\nTODO: provide exact specification for format.\n+optional" + }, + "related": { + "$ref": "#/definitions/v1ObjectReference" + }, + "reportingComponent": { + "type": "string", + "title": "Name of the controller that emitted this Event, e.g. `kubernetes.io/kubelet`.\n+optional" + }, + "reportingInstance": { + "type": "string", + "title": "ID of the controller instance, e.g. `kubelet-xyzf`.\n+optional" + }, + "series": { + "$ref": "#/definitions/v1EventSeries" + }, + "source": { + "$ref": "#/definitions/v1EventSource" + }, + "type": { + "type": "string", + "title": "Type of this event (Normal, Warning), new types could be added in the future\n+optional" + } + } + }, + "v1EventList": { + "description": "EventList is a list of events.", + "type": "object", + "properties": { + "items": { + "type": "array", + "title": "List of events", + "items": { + "$ref": "#/definitions/v1Event" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1EventSeries": { + "description": "EventSeries contain information on series of events, i.e. thing that was/is happening\ncontinuously for some time.", + "type": "object", + "properties": { + "count": { + "type": "integer", + "format": "int32", + "title": "Number of occurrences in this series up to the last heartbeat time" + }, + "lastObservedTime": { + "$ref": "#/definitions/v1MicroTime" + }, + "state": { + "type": "string", + "title": "State of this Series: Ongoing or Finished" + } + } + }, + "v1EventSource": { + "description": "EventSource contains information for an event.", + "type": "object", + "properties": { + "component": { + "type": "string", + "title": "Component from which the event is generated.\n+optional" + }, + "host": { + "type": "string", + "title": "Node name on which the event is generated.\n+optional" + } + } + }, + "v1Fields": { + "type": "object", + "title": "Fields stores a set of fields in a data structure like a Trie.\nTo understand how this is used, see: https://github.com/kubernetes-sigs/structured-merge-diff", + "properties": { + "map": { + "description": "Map stores a set of fields in a data structure like a Trie.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set,\nor a string representing a sub-field or item. The string will follow one of these four formats:\n'f:', where is the name of a field in a struct, or key in a map\n'v:', where is the exact json formatted value of a list item\n'i:', where is position of a item in a list\n'k:', where is a map of a list item's key fields to their unique values\nIf a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1Fields" + } + } + } + }, + "v1GroupKind": { + "description": "+protobuf.options.(gogoproto.goproto_stringer)=false", + "type": "object", + "title": "GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying\nconcepts during lookup stages without having partially valid types", + "properties": { + "group": { + "type": "string" + }, + "kind": { + "type": "string" + } + } + }, + "v1Initializer": { + "description": "Initializer is information about an initializer that has not yet completed.", + "type": "object", + "properties": { + "name": { + "description": "name of the process that is responsible for initializing this object.", + "type": "string" + } + } + }, + "v1Initializers": { + "description": "Initializers tracks the progress of initialization.", + "type": "object", + "properties": { + "pending": { + "type": "array", + "title": "Pending is a list of initializers that must execute in order before this object is visible.\nWhen the last pending initializer is removed, and no failing result is set, the initializers\nstruct will be set to nil and the object is considered as initialized and visible to all\nclients.\n+patchMergeKey=name\n+patchStrategy=merge", + "items": { + "$ref": "#/definitions/v1Initializer" + } + }, + "result": { + "$ref": "#/definitions/v1Status" + } + } + }, + "v1ListMeta": { + "description": "ListMeta describes metadata that synthetic resources must have, including lists and\nvarious status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "type": "object", + "properties": { + "continue": { + "description": "continue may be set if the user set a limit on the number of items returned, and indicates that\nthe server has more data available. The value is opaque and may be used to issue another request\nto the endpoint that served this list to retrieve the next set of available objects. Continuing a\nconsistent list may not be possible if the server configuration has changed or more than a few\nminutes have passed. The resourceVersion field returned when using this continue value will be\nidentical to the value in the first response, unless you have received this token from an error\nmessage.", + "type": "string" + }, + "resourceVersion": { + "type": "string", + "title": "String that identifies the server's internal version of this object that\ncan be used by clients to determine when objects have changed.\nValue must be treated as opaque by clients and passed unmodified back to the server.\nPopulated by the system.\nRead-only.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency\n+optional" + }, + "selfLink": { + "type": "string", + "title": "selfLink is a URL representing this object.\nPopulated by the system.\nRead-only.\n+optional" + } + } + }, + "v1LoadBalancerIngress": { + "description": "LoadBalancerIngress represents the status of a load-balancer ingress point:\ntraffic intended for the service should be sent to an ingress point.", + "type": "object", + "properties": { + "hostname": { + "type": "string", + "title": "Hostname is set for load-balancer ingress points that are DNS based\n(typically AWS load-balancers)\n+optional" + }, + "ip": { + "type": "string", + "title": "IP is set for load-balancer ingress points that are IP based\n(typically GCE or OpenStack load-balancers)\n+optional" + } + } + }, + "v1ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource\nthat the fieldset applies to.", + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set\napplies to. The format is \"group/version\" just like the top-level\nAPIVersion field. It is necessary to track the version of a field\nset because it cannot be automatically converted.", + "type": "string" + }, + "fields": { + "$ref": "#/definitions/v1Fields" + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created.\nThe only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "time": { + "$ref": "#/definitions/v1Time" + } + } + }, + "v1MicroTime": { + "description": "MicroTime is version of Time with microsecond level precision.\n\n+protobuf.options.marshal=false\n+protobuf.as=Timestamp\n+protobuf.options.(gogoproto.goproto_stringer)=false", + "type": "object", + "properties": { + "nanos": { + "description": "Non-negative fractions of a second at nanosecond resolution. Negative\nsecond values with fractions must still have non-negative nanos values\nthat count forward in time. Must be from 0 to 999,999,999\ninclusive. This field may be limited in precision depending on context.", + "type": "integer", + "format": "int32" + }, + "seconds": { + "description": "Represents seconds of UTC time since Unix epoch\n1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to\n9999-12-31T23:59:59Z inclusive.", + "type": "string", + "format": "int64" + } + } + }, + "v1ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects\nusers must create.", + "type": "object", + "properties": { + "annotations": { + "type": "object", + "title": "Annotations is an unstructured key value map stored with a resource that may be\nset by external tools to store and retrieve arbitrary metadata. They are not\nqueryable and should be preserved when modifying objects.\nMore info: http://kubernetes.io/docs/user-guide/annotations\n+optional", + "additionalProperties": { + "type": "string" + } + }, + "clusterName": { + "type": "string", + "title": "The name of the cluster which the object belongs to.\nThis is used to distinguish resources with same name and namespace in different clusters.\nThis field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.\n+optional" + }, + "creationTimestamp": { + "$ref": "#/definitions/v1Time" + }, + "deletionGracePeriodSeconds": { + "type": "string", + "format": "int64", + "title": "Number of seconds allowed for this object to gracefully terminate before\nit will be removed from the system. Only set when deletionTimestamp is also set.\nMay only be shortened.\nRead-only.\n+optional" + }, + "deletionTimestamp": { + "$ref": "#/definitions/v1Time" + }, + "finalizers": { + "type": "array", + "title": "Must be empty before the object is deleted from the registry. Each entry\nis an identifier for the responsible component that will remove the entry\nfrom the list. If the deletionTimestamp of the object is non-nil, entries\nin this list can only be removed.\n+optional\n+patchStrategy=merge", + "items": { + "type": "string" + } + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique\nname ONLY IF the Name field has not been provided.\nIf this field is used, the name returned to the client will be different\nthan the name passed. This value will also be combined with a unique suffix.\nThe provided value has the same validation rules as the Name field,\nand may be truncated by the length of the suffix required to make the value\nunique on the server.\n\nIf this field is specified and the generated name exists, the server will\nNOT return a 409 - instead, it will either return 201 Created or 500 with Reason\nServerTimeout indicating a unique name could not be found in the time allotted, and the client\nshould retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency\n+optional", + "type": "string" + }, + "generation": { + "type": "string", + "format": "int64", + "title": "A sequence number representing a specific generation of the desired state.\nPopulated by the system. Read-only.\n+optional" + }, + "initializers": { + "$ref": "#/definitions/v1Initializers" + }, + "labels": { + "type": "object", + "title": "Map of string keys and values that can be used to organize and categorize\n(scope and select) objects. May match selectors of replication controllers\nand services.\nMore info: http://kubernetes.io/docs/user-guide/labels\n+optional", + "additionalProperties": { + "type": "string" + } + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields\nthat are managed by that workflow. This is mostly for internal\nhousekeeping, and users typically shouldn't need to set or\nunderstand this field. A workflow can be the user's name, a\ncontroller's name, or the name of a specific apply path like\n\"ci-cd\". The set of fields is always in the version that the\nworkflow used when modifying the object.\n\nThis field is alpha and can be changed or removed without notice.\n\n+optional", + "type": "array", + "items": { + "$ref": "#/definitions/v1ManagedFieldsEntry" + } + }, + "name": { + "type": "string", + "title": "Name must be unique within a namespace. Is required when creating resources, although\nsome resources may allow a client to request the generation of an appropriate name\nautomatically. Name is primarily intended for creation idempotence and configuration\ndefinition.\nCannot be updated.\nMore info: http://kubernetes.io/docs/user-guide/identifiers#names\n+optional" + }, + "namespace": { + "description": "Namespace defines the space within each name must be unique. An empty namespace is\nequivalent to the \"default\" namespace, but \"default\" is the canonical representation.\nNot all objects are required to be scoped to a namespace - the value of this field for\nthose objects will be empty.\n\nMust be a DNS_LABEL.\nCannot be updated.\nMore info: http://kubernetes.io/docs/user-guide/namespaces\n+optional", + "type": "string" + }, + "ownerReferences": { + "type": "array", + "title": "List of objects depended by this object. If ALL objects in the list have\nbeen deleted, this object will be garbage collected. If this object is managed by a controller,\nthen an entry in this list will point to this controller, with the controller field set to true.\nThere cannot be more than one managing controller.\n+optional\n+patchMergeKey=uid\n+patchStrategy=merge", + "items": { + "$ref": "#/definitions/v1OwnerReference" + } + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can\nbe used by clients to determine when objects have changed. May be used for optimistic\nconcurrency, change detection, and the watch operation on a resource or set of resources.\nClients must treat these values as opaque and passed unmodified back to the server.\nThey may only be valid for a particular resource or set of resources.\n\nPopulated by the system.\nRead-only.\nValue must be treated as opaque by clients and .\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency\n+optional", + "type": "string" + }, + "selfLink": { + "type": "string", + "title": "SelfLink is a URL representing this object.\nPopulated by the system.\nRead-only.\n+optional" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by\nthe server on successful creation of a resource and is not allowed to change on PUT\noperations.\n\nPopulated by the system.\nRead-only.\nMore info: http://kubernetes.io/docs/user-guide/identifiers#uids\n+optional", + "type": "string" + } + } + }, + "v1ObjectReference": { + "type": "object", + "title": "ObjectReference contains enough information to let you inspect or modify the referred object.\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object", + "properties": { + "apiVersion": { + "type": "string", + "title": "API version of the referent.\n+optional" + }, + "fieldPath": { + "type": "string", + "title": "If referring to a piece of an object instead of an entire object, this string\nshould contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].\nFor example, if the object reference is to a container within a pod, this would take on a value like:\n\"spec.containers{name}\" (where \"name\" refers to the name of the container that triggered\nthe event) or if no container name is specified \"spec.containers[2]\" (container with\nindex 2 in this pod). This syntax is chosen only to have some well-defined way of\nreferencing a part of an object.\nTODO: this design is not final and this field is subject to change in the future.\n+optional" + }, + "kind": { + "type": "string", + "title": "Kind of the referent.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds\n+optional" + }, + "name": { + "type": "string", + "title": "Name of the referent.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n+optional" + }, + "namespace": { + "type": "string", + "title": "Namespace of the referent.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\n+optional" + }, + "resourceVersion": { + "type": "string", + "title": "Specific resourceVersion to which this reference is made, if any.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency\n+optional" + }, + "uid": { + "type": "string", + "title": "UID of the referent.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids\n+optional" + } + } + }, + "v1OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning\nobject. An owning object must be in the same namespace as the dependent, or\nbe cluster-scoped, so there is no namespace field.", + "type": "object", + "properties": { + "apiVersion": { + "description": "API version of the referent.", + "type": "string" + }, + "blockOwnerDeletion": { + "type": "boolean", + "format": "boolean", + "title": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then\nthe owner cannot be deleted from the key-value store until this\nreference is removed.\nDefaults to false.\nTo set this field, a user needs \"delete\" permission of the owner,\notherwise 422 (Unprocessable Entity) will be returned.\n+optional" + }, + "controller": { + "type": "boolean", + "format": "boolean", + "title": "If true, this reference points to the managing controller.\n+optional" + }, + "kind": { + "type": "string", + "title": "Kind of the referent.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds" + }, + "name": { + "type": "string", + "title": "Name of the referent.\nMore info: http://kubernetes.io/docs/user-guide/identifiers#names" + }, + "uid": { + "type": "string", + "title": "UID of the referent.\nMore info: http://kubernetes.io/docs/user-guide/identifiers#uids" + } + } + }, + "v1Status": { + "description": "Status is a return value for calls that don't return other objects.", + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32", + "title": "Suggested HTTP return code for this status, 0 if not set.\n+optional" + }, + "details": { + "$ref": "#/definitions/v1StatusDetails" + }, + "message": { + "type": "string", + "title": "A human-readable description of the status of this operation.\n+optional" + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + }, + "reason": { + "type": "string", + "title": "A machine-readable description of why this operation is in the\n\"Failure\" status. If this value is empty there\nis no information available. A Reason clarifies an HTTP status\ncode but does not override it.\n+optional" + }, + "status": { + "type": "string", + "title": "Status of the operation.\nOne of: \"Success\" or \"Failure\".\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status\n+optional" + } + } + }, + "v1StatusCause": { + "description": "StatusCause provides more information about an api.Status failure, including\ncases when multiple errors are encountered.", + "type": "object", + "properties": { + "field": { + "description": "The field of the resource that has caused this error, as named by its JSON\nserialization. May include dot and postfix notation for nested attributes.\nArrays are zero-indexed. Fields may appear more than once in an array of\ncauses due to fields having multiple errors.\nOptional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"\n+optional", + "type": "string" + }, + "message": { + "type": "string", + "title": "A human-readable description of the cause of the error. This field may be\npresented as-is to a reader.\n+optional" + }, + "reason": { + "type": "string", + "title": "A machine-readable description of the cause of the error. If this value is\nempty there is no information available.\n+optional" + } + } + }, + "v1StatusDetails": { + "description": "StatusDetails is a set of additional properties that MAY be set by the\nserver to provide additional information about a response. The Reason\nfield of a Status object defines what attributes will be set. Clients\nmust ignore fields that do not match the defined type of each attribute,\nand should assume that any attribute may be empty, invalid, or under\ndefined.", + "type": "object", + "properties": { + "causes": { + "type": "array", + "title": "The Causes array includes more details associated with the StatusReason\nfailure. Not all StatusReasons may provide detailed causes.\n+optional", + "items": { + "$ref": "#/definitions/v1StatusCause" + } + }, + "group": { + "type": "string", + "title": "The group attribute of the resource associated with the status StatusReason.\n+optional" + }, + "kind": { + "type": "string", + "title": "The kind attribute of the resource associated with the status StatusReason.\nOn some operations may differ from the requested resource Kind.\nMore info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds\n+optional" + }, + "name": { + "type": "string", + "title": "The name attribute of the resource associated with the status StatusReason\n(when there is a single name which can be described).\n+optional" + }, + "retryAfterSeconds": { + "type": "integer", + "format": "int32", + "title": "If specified, the time in seconds before the operation should be retried. Some errors may indicate\nthe client must take an alternate action - for those errors this field may indicate how long to wait\nbefore taking the alternate action.\n+optional" + }, + "uid": { + "type": "string", + "title": "UID of the resource.\n(when there is a single resource which can be described).\nMore info: http://kubernetes.io/docs/user-guide/identifiers#uids\n+optional" + } + } + }, + "v1Time": { + "description": "Time is a wrapper around time.Time which supports correct\nmarshaling to YAML and JSON. Wrappers are provided for many\nof the factory methods that the time package offers.\n\n+protobuf.options.marshal=false\n+protobuf.as=Timestamp\n+protobuf.options.(gogoproto.goproto_stringer)=false", + "type": "object", + "properties": { + "nanos": { + "description": "Non-negative fractions of a second at nanosecond resolution. Negative\nsecond values with fractions must still have non-negative nanos values\nthat count forward in time. Must be from 0 to 999,999,999\ninclusive. This field may be limited in precision depending on context.", + "type": "integer", + "format": "int32" + }, + "seconds": { + "description": "Represents seconds of UTC time since Unix epoch\n1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to\n9999-12-31T23:59:59Z inclusive.", + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1AWSAuthConfig": { + "type": "object", + "title": "AWSAuthConfig is an AWS IAM authentication configuration", + "properties": { + "clusterName": { + "type": "string", + "title": "ClusterName contains AWS cluster name" + }, + "roleARN": { + "description": "RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain.", + "type": "string" + } + } + }, + "v1alpha1AppProject": { + "type": "object", + "title": "AppProject provides a logical grouping of applications, providing controls for:\n* where the apps may deploy to (cluster whitelist)\n* what may be deployed (repository whitelist, resource whitelist/blacklist)\n* who can access these applications (roles, OIDC group claims bindings)\n* and what they can do (RBAC policies)\n* automation access to these roles (JWT tokens)\n+genclient\n+genclient:noStatus\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+kubebuilder:resource:path=appprojects,shortName=appproj;appprojs", + "properties": { + "metadata": { + "$ref": "#/definitions/v1ObjectMeta" + }, + "spec": { + "$ref": "#/definitions/v1alpha1AppProjectSpec" + } + } + }, + "v1alpha1AppProjectList": { + "type": "object", + "title": "AppProjectList is list of AppProject resources\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1AppProject" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1alpha1AppProjectSpec": { + "type": "object", + "title": "AppProjectSpec is the specification of an AppProject", + "properties": { + "clusterResourceWhitelist": { + "type": "array", + "title": "ClusterResourceWhitelist contains list of whitelisted cluster level resources", + "items": { + "$ref": "#/definitions/v1GroupKind" + } + }, + "description": { + "type": "string", + "title": "Description contains optional project description" + }, + "destinations": { + "type": "array", + "title": "Destinations contains list of destinations available for deployment", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationDestination" + } + }, + "namespaceResourceBlacklist": { + "type": "array", + "title": "NamespaceResourceBlacklist contains list of blacklisted namespace level resources", + "items": { + "$ref": "#/definitions/v1GroupKind" + } + }, + "roles": { + "type": "array", + "title": "Roles are user defined RBAC roles associated with this project", + "items": { + "$ref": "#/definitions/v1alpha1ProjectRole" + } + }, + "sourceRepos": { + "type": "array", + "title": "SourceRepos contains list of git repository URLs which can be used for deployment", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1Application": { + "type": "object", + "title": "Application is a definition of Application resource.\n+genclient\n+genclient:noStatus\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+kubebuilder:resource:path=applications,shortName=app;apps", + "properties": { + "metadata": { + "$ref": "#/definitions/v1ObjectMeta" + }, + "operation": { + "$ref": "#/definitions/v1alpha1Operation" + }, + "spec": { + "$ref": "#/definitions/v1alpha1ApplicationSpec" + }, + "status": { + "$ref": "#/definitions/v1alpha1ApplicationStatus" + } + } + }, + "v1alpha1ApplicationCondition": { + "type": "object", + "title": "ApplicationCondition contains details about current application condition", + "properties": { + "message": { + "type": "string", + "title": "Message contains human-readable message indicating details about condition" + }, + "type": { + "type": "string", + "title": "Type is an application condition type" + } + } + }, + "v1alpha1ApplicationDestination": { + "type": "object", + "title": "ApplicationDestination contains deployment destination information", + "properties": { + "namespace": { + "type": "string", + "title": "Namespace overrides the environment namespace value in the ksonnet app.yaml" + }, + "server": { + "type": "string", + "title": "Server overrides the environment server value in the ksonnet app.yaml" + } + } + }, + "v1alpha1ApplicationList": { + "type": "object", + "title": "ApplicationList is list of Application resources\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Application" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1alpha1ApplicationSource": { + "description": "ApplicationSource contains information about github repository, path within repository and target application environment.", + "type": "object", + "properties": { + "directory": { + "$ref": "#/definitions/v1alpha1ApplicationSourceDirectory" + }, + "helm": { + "$ref": "#/definitions/v1alpha1ApplicationSourceHelm" + }, + "ksonnet": { + "$ref": "#/definitions/v1alpha1ApplicationSourceKsonnet" + }, + "kustomize": { + "$ref": "#/definitions/v1alpha1ApplicationSourceKustomize" + }, + "path": { + "type": "string", + "title": "Path is a directory path within the repository containing a" + }, + "plugin": { + "$ref": "#/definitions/v1alpha1ApplicationSourcePlugin" + }, + "repoURL": { + "type": "string", + "title": "RepoURL is the git repository URL of the application manifests" + }, + "targetRevision": { + "type": "string", + "title": "TargetRevision defines the commit, tag, or branch in which to sync the application to.\nIf omitted, will sync to HEAD" + } + } + }, + "v1alpha1ApplicationSourceDirectory": { + "type": "object", + "properties": { + "jsonnet": { + "$ref": "#/definitions/v1alpha1ApplicationSourceJsonnet" + }, + "recurse": { + "type": "boolean", + "format": "boolean" + } + } + }, + "v1alpha1ApplicationSourceHelm": { + "type": "object", + "title": "ApplicationSourceHelm holds helm specific options", + "properties": { + "parameters": { + "type": "array", + "title": "Parameters are parameters to the helm template", + "items": { + "$ref": "#/definitions/v1alpha1HelmParameter" + } + }, + "releaseName": { + "type": "string", + "title": "The Helm release name. If omitted it will use the application name" + }, + "valueFiles": { + "type": "array", + "title": "ValuesFiles is a list of Helm value files to use when generating a template", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1ApplicationSourceJsonnet": { + "type": "object", + "title": "ApplicationSourceJsonnet holds jsonnet specific options", + "properties": { + "extVars": { + "type": "array", + "title": "ExtVars is a list of Jsonnet External Variables", + "items": { + "$ref": "#/definitions/v1alpha1JsonnetVar" + } + }, + "tlas": { + "type": "array", + "title": "TLAS is a list of Jsonnet Top-level Arguments", + "items": { + "$ref": "#/definitions/v1alpha1JsonnetVar" + } + } + } + }, + "v1alpha1ApplicationSourceKsonnet": { + "type": "object", + "title": "ApplicationSourceKsonnet holds ksonnet specific options", + "properties": { + "environment": { + "type": "string", + "title": "Environment is a ksonnet application environment name" + }, + "parameters": { + "type": "array", + "title": "Parameters are a list of ksonnet component parameter override values", + "items": { + "$ref": "#/definitions/v1alpha1KsonnetParameter" + } + } + } + }, + "v1alpha1ApplicationSourceKustomize": { + "type": "object", + "title": "ApplicationSourceKustomize holds kustomize specific options", + "properties": { + "commonLabels": { + "type": "object", + "title": "CommonLabels adds additional kustomize commonLabels", + "additionalProperties": { + "type": "string" + } + }, + "images": { + "type": "array", + "title": "Images are kustomize image overrides", + "items": { + "type": "string" + } + }, + "namePrefix": { + "type": "string", + "title": "NamePrefix is a prefix appended to resources for kustomize apps" + } + } + }, + "v1alpha1ApplicationSourcePlugin": { + "type": "object", + "title": "ApplicationSourcePlugin holds config management plugin specific options", + "properties": { + "env": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1EnvEntry" + } + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1ApplicationSpec": { + "description": "ApplicationSpec represents desired application state. Contains link to repository with application definition and additional parameters link definition revision.", + "type": "object", + "properties": { + "destination": { + "$ref": "#/definitions/v1alpha1ApplicationDestination" + }, + "ignoreDifferences": { + "type": "array", + "title": "IgnoreDifferences controls resources fields which should be ignored during comparison", + "items": { + "$ref": "#/definitions/v1alpha1ResourceIgnoreDifferences" + } + }, + "info": { + "type": "array", + "title": "Infos contains a list of useful information (URLs, email addresses, and plain text) that relates to the application", + "items": { + "$ref": "#/definitions/v1alpha1Info" + } + }, + "project": { + "description": "Project is a application project name. Empty name means that application belongs to 'default' project.", + "type": "string" + }, + "source": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + }, + "syncPolicy": { + "$ref": "#/definitions/v1alpha1SyncPolicy" + } + } + }, + "v1alpha1ApplicationStatus": { + "type": "object", + "title": "ApplicationStatus contains information about application sync, health status", + "properties": { + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ApplicationCondition" + } + }, + "health": { + "$ref": "#/definitions/v1alpha1HealthStatus" + }, + "history": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1RevisionHistory" + } + }, + "observedAt": { + "$ref": "#/definitions/v1Time" + }, + "operationState": { + "$ref": "#/definitions/v1alpha1OperationState" + }, + "reconciledAt": { + "$ref": "#/definitions/v1Time" + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceStatus" + } + }, + "sourceType": { + "type": "string" + }, + "summary": { + "$ref": "#/definitions/v1alpha1ApplicationSummary" + }, + "sync": { + "$ref": "#/definitions/v1alpha1SyncStatus" + } + } + }, + "v1alpha1ApplicationSummary": { + "type": "object", + "properties": { + "externalURLs": { + "description": "ExternalURLs holds all external URLs of application child resources.", + "type": "array", + "items": { + "type": "string" + } + }, + "images": { + "description": "Images holds all images of application child resources.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1ApplicationTree": { + "type": "object", + "title": "ApplicationTree holds nodes which belongs to the application", + "properties": { + "nodes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceNode" + } + } + } + }, + "v1alpha1ApplicationWatchEvent": { + "description": "ApplicationWatchEvent contains information about application change.", + "type": "object", + "properties": { + "application": { + "$ref": "#/definitions/v1alpha1Application" + }, + "type": { + "type": "string" + } + } + }, + "v1alpha1Cluster": { + "type": "object", + "title": "Cluster is the definition of a cluster resource", + "properties": { + "config": { + "$ref": "#/definitions/v1alpha1ClusterConfig" + }, + "connectionState": { + "$ref": "#/definitions/v1alpha1ConnectionState" + }, + "name": { + "type": "string", + "title": "Name of the cluster. If omitted, will use the server address" + }, + "server": { + "type": "string", + "title": "Server is the API server URL of the Kubernetes cluster" + } + } + }, + "v1alpha1ClusterConfig": { + "description": "ClusterConfig is the configuration attributes. This structure is subset of the go-client\nrest.Config with annotations added for marshalling.", + "type": "object", + "properties": { + "awsAuthConfig": { + "$ref": "#/definitions/v1alpha1AWSAuthConfig" + }, + "bearerToken": { + "description": "Server requires Bearer authentication. This client will not attempt to use\nrefresh tokens for an OAuth2 flow.\nTODO: demonstrate an OAuth2 compatible client.", + "type": "string" + }, + "password": { + "type": "string" + }, + "tlsClientConfig": { + "$ref": "#/definitions/v1alpha1TLSClientConfig" + }, + "username": { + "type": "string", + "title": "Server requires Basic authentication" + } + } + }, + "v1alpha1ClusterList": { + "description": "ClusterList is a collection of Clusters.", + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Cluster" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1alpha1ComparedTo": { + "type": "object", + "title": "ComparedTo contains application source and target which was used for resources comparison", + "properties": { + "destination": { + "$ref": "#/definitions/v1alpha1ApplicationDestination" + }, + "source": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } + } + }, + "v1alpha1ConnectionState": { + "type": "object", + "title": "ConnectionState contains information about remote resource connection state", + "properties": { + "attemptedAt": { + "$ref": "#/definitions/v1Time" + }, + "message": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "v1alpha1EnvEntry": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "the name, usually uppercase" + }, + "value": { + "type": "string", + "title": "the value" + } + } + }, + "v1alpha1HealthStatus": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "v1alpha1HelmParameter": { + "type": "object", + "title": "HelmParameter is a parameter to a helm template", + "properties": { + "forceString": { + "type": "boolean", + "format": "boolean", + "title": "ForceString determines whether to tell Helm to interpret booleans and numbers as strings" + }, + "name": { + "type": "string", + "title": "Name is the name of the helm parameter" + }, + "value": { + "type": "string", + "title": "Value is the value for the helm parameter" + } + } + }, + "v1alpha1Info": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1InfoItem": { + "type": "object", + "title": "InfoItem contains human readable information about object", + "properties": { + "name": { + "description": "Name is a human readable title for this piece of information.", + "type": "string" + }, + "value": { + "description": "Value is human readable content.", + "type": "string" + } + } + }, + "v1alpha1JWTToken": { + "type": "object", + "title": "JWTToken holds the issuedAt and expiresAt values of a token", + "properties": { + "exp": { + "type": "string", + "format": "int64" + }, + "iat": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1JsonnetVar": { + "type": "object", + "title": "JsonnetVar is a jsonnet variable", + "properties": { + "code": { + "type": "boolean", + "format": "boolean" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1KsonnetParameter": { + "type": "object", + "title": "KsonnetParameter is a ksonnet component parameter", + "properties": { + "component": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1KustomizeOptions": { + "type": "object", + "title": "KustomizeOptions are options for kustomize to use when building manifests", + "properties": { + "buildOptions": { + "type": "string", + "title": "BuildOptions is a string of build parameters to use when calling `kustomize build`" + } + } + }, + "v1alpha1Operation": { + "description": "Operation contains requested operation parameters.", + "type": "object", + "properties": { + "sync": { + "$ref": "#/definitions/v1alpha1SyncOperation" + } + } + }, + "v1alpha1OperationState": { + "description": "OperationState contains information about state of currently performing operation on application.", + "type": "object", + "properties": { + "finishedAt": { + "$ref": "#/definitions/v1Time" + }, + "message": { + "description": "Message hold any pertinent messages when attempting to perform operation (typically errors).", + "type": "string" + }, + "operation": { + "$ref": "#/definitions/v1alpha1Operation" + }, + "phase": { + "type": "string", + "title": "Phase is the current phase of the operation" + }, + "startedAt": { + "$ref": "#/definitions/v1Time" + }, + "syncResult": { + "$ref": "#/definitions/v1alpha1SyncOperationResult" + } + } + }, + "v1alpha1ProjectRole": { + "type": "object", + "title": "ProjectRole represents a role that has access to a project", + "properties": { + "description": { + "type": "string", + "title": "Description is a description of the role" + }, + "groups": { + "type": "array", + "title": "Groups are a list of OIDC group claims bound to this role", + "items": { + "type": "string" + } + }, + "jwtTokens": { + "type": "array", + "title": "JWTTokens are a list of generated JWT tokens bound to this role", + "items": { + "$ref": "#/definitions/v1alpha1JWTToken" + } + }, + "name": { + "type": "string", + "title": "Name is a name for this role" + }, + "policies": { + "type": "array", + "title": "Policies Stores a list of casbin formated strings that define access policies for the role in the project", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1Repository": { + "type": "object", + "title": "Repository is a Git repository holding application configurations", + "properties": { + "connectionState": { + "$ref": "#/definitions/v1alpha1ConnectionState" + }, + "enableLfs": { + "type": "boolean", + "format": "boolean", + "title": "Whether git-lfs support should be enabled for this repo" + }, + "insecure": { + "type": "boolean", + "format": "boolean", + "title": "Whether the repo is insecure" + }, + "insecureIgnoreHostKey": { + "type": "boolean", + "format": "boolean", + "title": "InsecureIgnoreHostKey should not be used anymore, Insecure is favoured" + }, + "password": { + "type": "string", + "title": "Password for authenticating at the repo server" + }, + "repo": { + "type": "string", + "title": "URL of the repo" + }, + "sshPrivateKey": { + "type": "string", + "title": "SSH private key data for authenticating at the repo server" + }, + "tlsClientCertData": { + "type": "string", + "title": "TLS client cert data for authenticating at the repo server" + }, + "tlsClientCertKey": { + "type": "string", + "title": "TLS client cert key for authenticating at the repo server" + }, + "username": { + "type": "string", + "title": "Username for authenticating at the repo server" + } + } + }, + "v1alpha1RepositoryCertificate": { + "type": "object", + "title": "A RepositoryCertificate is either SSH known hosts entry or TLS certificate", + "properties": { + "certData": { + "type": "string", + "format": "byte", + "title": "Actual certificate data, protocol dependent" + }, + "certInfo": { + "type": "string", + "title": "Additional certificate info (e.g. SSH fingerprint, X509 CommonName)" + }, + "certSubType": { + "type": "string", + "title": "The sub type of the cert, i.e. \"ssh-rsa\"" + }, + "certType": { + "type": "string", + "title": "Type of certificate - currently \"https\" or \"ssh\"" + }, + "serverName": { + "type": "string", + "title": "Name of the server the certificate is intended for" + } + } + }, + "v1alpha1RepositoryCertificateList": { + "type": "object", + "title": "RepositoryCertificateList is a collection of RepositoryCertificates", + "properties": { + "items": { + "type": "array", + "title": "List of certificates to be processed", + "items": { + "$ref": "#/definitions/v1alpha1RepositoryCertificate" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1alpha1RepositoryList": { + "description": "RepositoryList is a collection of Repositories.", + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Repository" + } + }, + "metadata": { + "$ref": "#/definitions/v1ListMeta" + } + } + }, + "v1alpha1ResourceAction": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "params": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceActionParam" + } + } + } + }, + "v1alpha1ResourceActionParam": { + "type": "object", + "properties": { + "default": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1ResourceDiff": { + "type": "object", + "title": "ResourceDiff holds the diff of a live and target resource object", + "properties": { + "diff": { + "type": "string" + }, + "group": { + "type": "string" + }, + "hook": { + "type": "boolean", + "format": "boolean" + }, + "kind": { + "type": "string" + }, + "liveState": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetState": { + "type": "string" + } + } + }, + "v1alpha1ResourceIgnoreDifferences": { + "description": "ResourceIgnoreDifferences contains resource filter and list of json paths which should be ignored during comparison with live state.", + "type": "object", + "properties": { + "group": { + "type": "string" + }, + "jsonPointers": { + "type": "array", + "items": { + "type": "string" + } + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "v1alpha1ResourceNetworkingInfo": { + "type": "object", + "title": "ResourceNetworkingInfo holds networking resource related information", + "properties": { + "externalURLs": { + "description": "ExternalURLs holds list of URLs which should be available externally. List is populated for ingress resources using rules hostnames.", + "type": "array", + "items": { + "type": "string" + } + }, + "ingress": { + "type": "array", + "items": { + "$ref": "#/definitions/v1LoadBalancerIngress" + } + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "targetLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "targetRefs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceRef" + } + } + } + }, + "v1alpha1ResourceNode": { + "type": "object", + "title": "ResourceNode contains information about live resource and its children", + "properties": { + "health": { + "$ref": "#/definitions/v1alpha1HealthStatus" + }, + "images": { + "type": "array", + "items": { + "type": "string" + } + }, + "info": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1InfoItem" + } + }, + "networkingInfo": { + "$ref": "#/definitions/v1alpha1ResourceNetworkingInfo" + }, + "parentRefs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceRef" + } + }, + "resourceRef": { + "$ref": "#/definitions/v1alpha1ResourceRef" + }, + "resourceVersion": { + "type": "string" + } + } + }, + "v1alpha1ResourceOverride": { + "type": "object", + "title": "ResourceOverride holds configuration to customize resource diffing and health assessment", + "properties": { + "actions": { + "type": "string" + }, + "healthLua": { + "type": "string" + }, + "ignoreDifferences": { + "type": "string" + } + } + }, + "v1alpha1ResourceRef": { + "type": "object", + "title": "ResourceRef includes fields which unique identify resource", + "properties": { + "group": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "v1alpha1ResourceResult": { + "type": "object", + "title": "ResourceResult holds the operation result details of a specific resource", + "properties": { + "group": { + "type": "string" + }, + "hookPhase": { + "type": "string", + "title": "the state of any operation associated with this resource OR hook\nnote: can contain values for non-hook resources" + }, + "hookType": { + "type": "string", + "title": "the type of the hook, empty for non-hook resources" + }, + "kind": { + "type": "string" + }, + "message": { + "type": "string", + "title": "message for the last sync OR operation" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "status": { + "type": "string", + "title": "the final result of the sync, this is be empty if the resources is yet to be applied/pruned and is always zero-value for hooks" + }, + "syncPhase": { + "type": "string", + "title": "indicates the particular phase of the sync that this is for" + }, + "version": { + "type": "string" + } + } + }, + "v1alpha1ResourceStatus": { + "type": "object", + "title": "ResourceStatus holds the current sync and health status of a resource", + "properties": { + "group": { + "type": "string" + }, + "health": { + "$ref": "#/definitions/v1alpha1HealthStatus" + }, + "hook": { + "type": "boolean", + "format": "boolean" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "requiresPruning": { + "type": "boolean", + "format": "boolean" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "v1alpha1RevisionHistory": { + "type": "object", + "title": "RevisionHistory contains information relevant to an application deployment", + "properties": { + "deployedAt": { + "$ref": "#/definitions/v1Time" + }, + "id": { + "type": "string", + "format": "int64" + }, + "revision": { + "type": "string" + }, + "source": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } + } + }, + "v1alpha1RevisionMetadata": { + "type": "object", + "title": "data about a specific revision within a repo", + "properties": { + "author": { + "type": "string", + "title": "who authored this revision,\ntypically their name and email, e.g. \"John Doe \",\nbut might not match this example" + }, + "date": { + "$ref": "#/definitions/v1Time" + }, + "message": { + "type": "string", + "title": "the message associated with the revision,\nprobably the commit message,\nthis is truncated to the first newline or 64 characters (which ever comes first)" + }, + "tags": { + "type": "array", + "title": "tags on the revision,\nnote - tags can move from one revision to another", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1SyncOperation": { + "description": "SyncOperation contains sync operation details.", + "type": "object", + "properties": { + "dryRun": { + "type": "boolean", + "format": "boolean", + "title": "DryRun will perform a `kubectl apply --dry-run` without actually performing the sync" + }, + "manifests": { + "type": "array", + "title": "Manifests is an optional field that overrides sync source with a local directory for development", + "items": { + "type": "string" + } + }, + "prune": { + "type": "boolean", + "format": "boolean", + "title": "Prune deletes resources that are no longer tracked in git" + }, + "resources": { + "type": "array", + "title": "Resources describes which resources to sync", + "items": { + "$ref": "#/definitions/v1alpha1SyncOperationResource" + } + }, + "revision": { + "description": "Revision is the git revision in which to sync the application to.\nIf omitted, will use the revision specified in app spec.", + "type": "string" + }, + "source": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + }, + "syncStrategy": { + "$ref": "#/definitions/v1alpha1SyncStrategy" + } + } + }, + "v1alpha1SyncOperationResource": { + "description": "SyncOperationResource contains resources to sync.", + "type": "object", + "properties": { + "group": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1SyncOperationResult": { + "type": "object", + "title": "SyncOperationResult represent result of sync operation", + "properties": { + "resources": { + "type": "array", + "title": "Resources holds the sync result of each individual resource", + "items": { + "$ref": "#/definitions/v1alpha1ResourceResult" + } + }, + "revision": { + "type": "string", + "title": "Revision holds the git commit SHA of the sync" + }, + "source": { + "$ref": "#/definitions/v1alpha1ApplicationSource" + } + } + }, + "v1alpha1SyncPolicy": { + "type": "object", + "title": "SyncPolicy controls when a sync will be performed in response to updates in git", + "properties": { + "automated": { + "$ref": "#/definitions/v1alpha1SyncPolicyAutomated" + } + } + }, + "v1alpha1SyncPolicyAutomated": { + "type": "object", + "title": "SyncPolicyAutomated controls the behavior of an automated sync", + "properties": { + "prune": { + "type": "boolean", + "format": "boolean", + "title": "Prune will prune resources automatically as part of automated sync (default: false)" + }, + "selfHeal": { + "type": "boolean", + "format": "boolean", + "title": "SelfHeal enables auto-syncing if (default: false)" + } + } + }, + "v1alpha1SyncStatus": { + "description": "SyncStatus is a comparison result of application spec and deployed application.", + "type": "object", + "properties": { + "comparedTo": { + "$ref": "#/definitions/v1alpha1ComparedTo" + }, + "revision": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "v1alpha1SyncStrategy": { + "type": "object", + "title": "SyncStrategy controls the manner in which a sync is performed", + "properties": { + "apply": { + "$ref": "#/definitions/v1alpha1SyncStrategyApply" + }, + "hook": { + "$ref": "#/definitions/v1alpha1SyncStrategyHook" + } + } + }, + "v1alpha1SyncStrategyApply": { + "type": "object", + "title": "SyncStrategyApply uses `kubectl apply` to perform the apply", + "properties": { + "force": { + "description": "Force indicates whether or not to supply the --force flag to `kubectl apply`.\nThe --force flag deletes and re-create the resource, when PATCH encounters conflict and has\nretried for 5 times.", + "type": "boolean", + "format": "boolean" + } + } + }, + "v1alpha1SyncStrategyHook": { + "description": "SyncStrategyHook will perform a sync using hooks annotations.\nIf no hook annotation is specified falls back to `kubectl apply`.", + "type": "object", + "properties": { + "syncStrategyApply": { + "$ref": "#/definitions/v1alpha1SyncStrategyApply" + } + } + }, + "v1alpha1TLSClientConfig": { + "type": "object", + "title": "TLSClientConfig contains settings to enable transport layer security", + "properties": { + "caData": { + "type": "string", + "format": "byte", + "title": "CAData holds PEM-encoded bytes (typically read from a root certificates bundle).\nCAData takes precedence over CAFile" + }, + "certData": { + "type": "string", + "format": "byte", + "title": "CertData holds PEM-encoded bytes (typically read from a client certificate file).\nCertData takes precedence over CertFile" + }, + "insecure": { + "description": "Server should be accessed without verifying the TLS certificate. For testing only.", + "type": "boolean", + "format": "boolean" + }, + "keyData": { + "type": "string", + "format": "byte", + "title": "KeyData holds PEM-encoded bytes (typically read from a client certificate key file).\nKeyData takes precedence over KeyFile" + }, + "serverName": { + "description": "ServerName is passed to the server for SNI and is used in the client to check server\ncertificates against. If ServerName is empty, the hostname used to contact the\nserver is used.", + "type": "string" + } + } + }, + "versionVersionMessage": { + "type": "object", + "title": "VersionMessage represents version of the Argo CD API server", + "properties": { + "BuildDate": { + "type": "string" + }, + "Compiler": { + "type": "string" + }, + "GitCommit": { + "type": "string" + }, + "GitTag": { + "type": "string" + }, + "GitTreeState": { + "type": "string" + }, + "GoVersion": { + "type": "string" + }, + "KsonnetVersion": { + "type": "string" + }, + "Platform": { + "type": "string" + }, + "Version": { + "type": "string" + } + } + } + } +} \ No newline at end of file From 78b1d109648ae780efde2b594cd719fb4334edbc Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Fri, 15 Sep 2023 15:51:13 +0530 Subject: [PATCH 20/35] wip --- pkg/appStore/deployment/service/InstalledAppService.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 515bac849e..a613f293d6 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1168,7 +1168,11 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus if helmInstallStatus.ErrorInInstallation { releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message - releaseStatus.Message = "Release for this app doesn't exist" + if !helmInstallStatus.IsReleaseInstalled { + releaseStatus.Message = "Release for this app doesn't exist" + } else { + releaseStatus.Message = "Release install/upgrade failed" + } } else { // there can be a case when helm release is created but we are not able to fetch it releaseStatus.Status = "Unknown" From e029a640d74773f607f63a86757b921372e4162b Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Wed, 20 Sep 2023 19:10:21 +0530 Subject: [PATCH 21/35] wip --- pkg/appStore/deployment/service/InstalledAppService.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index a613f293d6..df35a735ef 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1168,11 +1168,7 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus if helmInstallStatus.ErrorInInstallation { releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message - if !helmInstallStatus.IsReleaseInstalled { - releaseStatus.Message = "Release for this app doesn't exist" - } else { - releaseStatus.Message = "Release install/upgrade failed" - } + releaseStatus.Message = "Release install/upgrade failed" } else { // there can be a case when helm release is created but we are not able to fetch it releaseStatus.Status = "Unknown" From 6e6cd8560c874b00b80867392ae685a912747408 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 01:48:41 +0530 Subject: [PATCH 22/35] wip --- .../deployment/service/AppStoreDeploymentService.go | 13 ------------- .../deployment/service/InstalledAppService.go | 12 ++++-------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index d3ba7cd2eb..3686fae7c6 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -227,19 +227,6 @@ func (impl AppStoreDeploymentServiceImpl) AppStoreDeployOperationDB(installAppVe Status: appStoreBean.DEPLOY_INIT, } - //if isGitOpsConfigured && appInstallationMode == util2.SERVER_MODE_FULL && (installAppVersionRequest.DeploymentAppType == util.PIPELINE_DEPLOYMENT_TYPE_ACD || !isInternalUse) { - // installedAppModel.DeploymentAppType = util.PIPELINE_DEPLOYMENT_TYPE_ACD - //} else { - // installedAppModel.DeploymentAppType = util.PIPELINE_DEPLOYMENT_TYPE_HELM - //} - // - //if isInternalUse && installedAppModel.DeploymentAppType == "" { - // if isGitOpsConfigured { - // installedAppModel.DeploymentAppType = util.PIPELINE_DEPLOYMENT_TYPE_ACD - // } else { - // installedAppModel.DeploymentAppType = util.PIPELINE_DEPLOYMENT_TYPE_HELM - // } - //} if !isInternalUse { if isGitOpsConfigured && appInstallationMode == util2.SERVER_MODE_FULL && !isOCIRepo { installAppVersionRequest.DeploymentAppType = util.PIPELINE_DEPLOYMENT_TYPE_ACD diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index df35a735ef..2e6512d316 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1131,6 +1131,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h 2) User creates an app with same name i.e "foo" 3) In this case we use helmReleaseInstallStatus which will have status of our release and not external release */ + resourceTree = make(map[string]interface{}) releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) } } @@ -1169,16 +1170,11 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus releaseStatus.Status = "Failed" releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release install/upgrade failed" - } else { - // there can be a case when helm release is created but we are not able to fetch it - releaseStatus.Status = "Unknown" - releaseStatus.Description = "Unable to fetch release for app" - releaseStatus.Message = "Unable to fetch release for app" } } else { - releaseStatus.Status = "Unknown" - releaseStatus.Description = "Release not found" - releaseStatus.Message = "Release not found " + releaseStatus.Status = "Progressing" + releaseStatus.Description = "Release install/upgrade pending" + releaseStatus.Message = "Release install/upgrade pending" } return releaseStatus } From aecf655827202782c6dc5064a89c0813a48abcd3 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 02:41:15 +0530 Subject: [PATCH 23/35] wip --- pkg/appStore/bean/bean.go | 1 + .../deployment/service/InstalledAppService.go | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/appStore/bean/bean.go b/pkg/appStore/bean/bean.go index 8abf92f487..18a20a8115 100644 --- a/pkg/appStore/bean/bean.go +++ b/pkg/appStore/bean/bean.go @@ -379,4 +379,5 @@ type HelmInstallNatsMessage struct { Message string IsReleaseInstalled bool ErrorInInstallation bool + Status string } diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 2e6512d316..312aedbffb 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1106,6 +1106,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h 2) ErrorInInstallation -> if there is error in installation 3) Message -> error message/ success message 4) InstallAppVersionHistoryId + 5) Status -> Progressing, Failed, Succeeded */ if detail != nil && detail.ReleaseExist { @@ -1166,15 +1167,24 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus impl.logger.Errorw("error in unmarshalling helm release install status") return releaseStatus } - if helmInstallStatus.ErrorInInstallation { - releaseStatus.Status = "Failed" + if helmInstallStatus.Status == "Failed" { + releaseStatus.Status = helmInstallStatus.Status releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release install/upgrade failed" + } else if helmInstallStatus.Status == "Progressing" { + releaseStatus.Status = helmInstallStatus.Status + releaseStatus.Description = helmInstallStatus.Message + releaseStatus.Message = helmInstallStatus.Message + } else { + // there can be a case when helm release is created but we are not able to fetch it + releaseStatus.Status = "Unknown" + releaseStatus.Description = "Unable to fetch release for app" + releaseStatus.Message = "Unable to fetch release for app" } } else { - releaseStatus.Status = "Progressing" - releaseStatus.Description = "Release install/upgrade pending" - releaseStatus.Message = "Release install/upgrade pending" + releaseStatus.Status = "Unknown" + releaseStatus.Description = "Release not found" + releaseStatus.Message = "Release not found " } return releaseStatus } From b9c76bb50d52543b4c92b7993a9c60d3b770b604 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 03:48:23 +0530 Subject: [PATCH 24/35] wip --- .../deployment/service/AppStoreDeploymentService.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 3686fae7c6..986944a57c 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -1685,12 +1685,7 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) return } - - if helmInstallNatsMessage.ErrorInInstallation { - installedAppVersionHistory.Status = "Failed" - } else if !helmInstallNatsMessage.ErrorInInstallation { - installedAppVersionHistory.Status = "Succeeded" - } + installedAppVersionHistory.Status = helmInstallNatsMessage.Status installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(installedAppVersionHistory, nil) if err != nil { From 3c5c67c9be2a17c2b358925df254cb46a48f75e3 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 13:17:30 +0530 Subject: [PATCH 25/35] progressing state --- api/appStore/InstalledAppRestHandler.go | 8 +++---- api/restHandler/AppListingRestHandler.go | 2 +- pkg/appStore/bean/bean.go | 3 +-- .../repository/InstalledAppRepository.go | 17 ++++++++------ .../repository/InstalledAppVersionHistory.go | 2 +- .../service/AppStoreDeploymentService.go | 12 ++++++---- .../deployment/service/InstalledAppService.go | 23 +++++++++---------- 7 files changed, 35 insertions(+), 32 deletions(-) diff --git a/api/appStore/InstalledAppRestHandler.go b/api/appStore/InstalledAppRestHandler.go index 2909ef047c..d253bec64a 100644 --- a/api/appStore/InstalledAppRestHandler.go +++ b/api/appStore/InstalledAppRestHandler.go @@ -580,7 +580,7 @@ func (handler *InstalledAppRestHandlerImpl) FetchAppDetailsForInstalledApp(w htt resourceTreeAndNotesContainer.ResourceTree = map[string]interface{}{} if len(installedApp.App.AppName) > 0 && len(installedApp.Environment.Name) > 0 { - err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, "") + err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, "", "") if installedApp.DeploymentAppType == util2.PIPELINE_DEPLOYMENT_TYPE_ACD { apiError, ok := err.(*util2.ApiError) if ok && apiError != nil { @@ -695,7 +695,7 @@ func (handler *InstalledAppRestHandlerImpl) FetchResourceTree(w http.ResponseWri resourceTreeAndNotesContainer.ResourceTree = map[string]interface{}{} if len(installedApp.App.AppName) > 0 && len(installedApp.Environment.Name) > 0 { - err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, appDetail.HelmReleaseInstallStatus) + err = handler.fetchResourceTree(w, r, &resourceTreeAndNotesContainer, *installedApp, appDetail.HelmReleaseInstallStatus, appDetail.Status) if installedApp.DeploymentAppType == util2.PIPELINE_DEPLOYMENT_TYPE_ACD { //resource tree has been fetched now prepare to sync application deployment status with this resource tree call handler.syncDeploymentStatusWithResourceTreeCall(appDetail) @@ -786,10 +786,10 @@ func (handler *InstalledAppRestHandlerImpl) FetchResourceTreeForACDApp(w http.Re common.WriteJsonResp(w, err, appDetail, http.StatusOK) } -func (handler *InstalledAppRestHandlerImpl) fetchResourceTree(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer *bean2.AppDetailsContainer, installedApp repository.InstalledApps, helmReleaseInstallStatus string) error { +func (handler *InstalledAppRestHandlerImpl) fetchResourceTree(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer *bean2.AppDetailsContainer, installedApp repository.InstalledApps, helmReleaseInstallStatus string, status string) error { ctx := r.Context() cn, _ := w.(http.CloseNotifier) - err := handler.installedAppService.FetchResourceTree(ctx, cn, resourceTreeAndNotesContainer, installedApp, helmReleaseInstallStatus) + err := handler.installedAppService.FetchResourceTree(ctx, cn, resourceTreeAndNotesContainer, installedApp, helmReleaseInstallStatus, status) return err } diff --git a/api/restHandler/AppListingRestHandler.go b/api/restHandler/AppListingRestHandler.go index 737539a6e2..590fde38f0 100644 --- a/api/restHandler/AppListingRestHandler.go +++ b/api/restHandler/AppListingRestHandler.go @@ -1348,7 +1348,7 @@ func (handler AppListingRestHandlerImpl) RedirectToLinkouts(w http.ResponseWrite func (handler AppListingRestHandlerImpl) fetchResourceTreeFromInstallAppService(w http.ResponseWriter, r *http.Request, resourceTreeAndNotesContainer bean.AppDetailsContainer, installedApps repository.InstalledApps) (bean.AppDetailsContainer, error) { rctx := r.Context() cn, _ := w.(http.CloseNotifier) - err := handler.installedAppService.FetchResourceTree(rctx, cn, &resourceTreeAndNotesContainer, installedApps, "") + err := handler.installedAppService.FetchResourceTree(rctx, cn, &resourceTreeAndNotesContainer, installedApps, "", "") return resourceTreeAndNotesContainer, err } func (handler AppListingRestHandlerImpl) GetHostUrlsByBatch(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/appStore/bean/bean.go b/pkg/appStore/bean/bean.go index 18a20a8115..19dde14013 100644 --- a/pkg/appStore/bean/bean.go +++ b/pkg/appStore/bean/bean.go @@ -374,10 +374,9 @@ type PushChartToGitRequestDTO struct { UserId int32 } -type HelmInstallNatsMessage struct { +type HelmReleaseStatusConfig struct { InstallAppVersionHistoryId int Message string IsReleaseInstalled bool ErrorInInstallation bool - Status string } diff --git a/pkg/appStore/deployment/repository/InstalledAppRepository.go b/pkg/appStore/deployment/repository/InstalledAppRepository.go index 65230b66cb..f9ca885294 100644 --- a/pkg/appStore/deployment/repository/InstalledAppRepository.go +++ b/pkg/appStore/deployment/repository/InstalledAppRepository.go @@ -72,7 +72,7 @@ type InstalledAppRepository interface { GetArgoPipelinesHavingLatestTriggerStuckInNonTerminalStatusesForAppStore(getPipelineDeployedBeforeMinutes int, getPipelineDeployedWithinHours int) ([]*InstalledAppVersions, error) GetArgoPipelinesHavingTriggersStuckInLastPossibleNonTerminalTimelinesForAppStore(pendingSinceSeconds int, timeForDegradation int) ([]*InstalledAppVersions, error) - GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, error) + GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, string, error) } type InstalledAppRepositoryImpl struct { @@ -828,13 +828,16 @@ func (impl InstalledAppRepositoryImpl) GetArgoPipelinesHavingTriggersStuckInLast return installedAppVersions, nil } -func (impl InstalledAppRepositoryImpl) GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, error) { - var helmReleaseStatusConfig string - queryString := `select helm_release_status_config from installed_app_version_history inner join installed_app_versions on installed_app_version_history.installed_app_version_id=installed_app_versions.id inner join installed_apps on installed_apps.id=installed_app_versions.installed_app_id where installed_apps.id = ? order by installed_app_version_history.created_on desc limit 1;` - _, err := impl.dbConnection.Query(&helmReleaseStatusConfig, queryString, installedAppVersionHistoryId) +func (impl InstalledAppRepositoryImpl) GetHelmReleaseStatusConfigByInstalledAppId(installedAppVersionHistoryId int) (string, string, error) { + installStatus := struct { + HelmReleaseStatusConfig string + Status string + }{} + queryString := `select helm_release_status_config, installed_app_version_history.status from installed_app_version_history inner join installed_app_versions on installed_app_version_history.installed_app_version_id=installed_app_versions.id inner join installed_apps on installed_apps.id=installed_app_versions.installed_app_id where installed_apps.id = ? order by installed_app_version_history.created_on desc limit 1;` + _, err := impl.dbConnection.Query(&installStatus, queryString, installedAppVersionHistoryId) if err != nil { impl.Logger.Errorw("error in GetAllGitOpsDeploymentAppName", "err", err) - return helmReleaseStatusConfig, err + return installStatus.HelmReleaseStatusConfig, "", err } - return helmReleaseStatusConfig, nil + return installStatus.HelmReleaseStatusConfig, installStatus.Status, nil } diff --git a/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go b/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go index d9cca40180..52ece2aae0 100644 --- a/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go +++ b/pkg/appStore/deployment/repository/InstalledAppVersionHistory.go @@ -42,7 +42,7 @@ type InstalledAppVersionHistory struct { GitHash string `sql:"git_hash"` StartedOn time.Time `sql:"started_on,type:timestamptz"` FinishedOn time.Time `sql:"finished_on,type:timestamptz"` - HelmReleaseStatusConfig string `sql: "helm_release_status"` + HelmReleaseStatusConfig string `sql:"helm_release_status_config"` sql.AuditLog } diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 986944a57c..213ea577e5 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -295,7 +295,6 @@ func (impl AppStoreDeploymentServiceImpl) AppStoreDeployOperationDB(installAppVe return nil, err } installAppVersionRequest.InstalledAppVersionHistoryId = installedAppVersionHistory.Id - if installAppVersionRequest.DefaultClusterComponent { clusterInstalledAppsModel := &repository.ClusterInstalledApps{ ClusterId: environment.ClusterId, @@ -1393,8 +1392,7 @@ func (impl *AppStoreDeploymentServiceImpl) UpdateInstalledApp(ctx context.Contex installAppVersionRequest.EnvironmentName = installedApp.Environment.Name installAppVersionRequest.Environment = &installedApp.Environment - installAppVersionHistoryStatus := "Unknown" - installAppVersionHistoryStatus = pipelineConfig.WorkflowInProgress + installAppVersionHistoryStatus := pipelineConfig.WorkflowInProgress installedAppVersionHistory := &repository.InstalledAppVersionHistory{ InstalledAppVersionId: installedAppVersion.Id, ValuesYamlRaw: installAppVersionRequest.ValuesOverrideYaml, @@ -1673,7 +1671,7 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { callback := func(msg *pubsub.PubSubMsg) { impl.logger.Debug("received helm install status event - HELM_INSTALL_STATUS", "data", msg.Data) - helmInstallNatsMessage := &appStoreBean.HelmInstallNatsMessage{} + helmInstallNatsMessage := &appStoreBean.HelmReleaseStatusConfig{} err := json.Unmarshal([]byte(msg.Data), helmInstallNatsMessage) if err != nil { impl.logger.Errorw("error in unmarshalling helm install status nats message", "err", err) @@ -1685,7 +1683,11 @@ func (impl AppStoreDeploymentServiceImpl) SubscribeHelmInstallStatus() error { impl.logger.Errorw("error in fetching installed app by installed app id in subscribe helm status callback", "err", err) return } - installedAppVersionHistory.Status = helmInstallNatsMessage.Status + if helmInstallNatsMessage.ErrorInInstallation { + installedAppVersionHistory.Status = pipelineConfig.WorkflowFailed + } else { + installedAppVersionHistory.Status = pipelineConfig.WorkflowSucceeded + } installedAppVersionHistory.HelmReleaseStatusConfig = msg.Data _, err = impl.installedAppRepositoryHistory.UpdateInstalledAppVersionHistory(installedAppVersionHistory, nil) if err != nil { diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 312aedbffb..582436f0ea 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -91,7 +91,7 @@ type InstalledAppService interface { DeployDefaultChartOnCluster(bean *cluster2.ClusterBean, userId int32) (bool, error) FindAppDetailsForAppstoreApplication(installedAppId, envId int) (bean2.AppDetailContainer, error) UpdateInstalledAppVersionStatus(application *v1alpha1.Application) (bool, error) - FetchResourceTree(rctx context.Context, cn http.CloseNotifier, resourceTreeAndNotesContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string) error + FetchResourceTree(rctx context.Context, cn http.CloseNotifier, appDetailsContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string, status string) error MarkGitOpsInstalledAppsDeletedIfArgoAppIsDeleted(installedAppId int, envId int) error CheckAppExistsByInstalledAppId(installedAppId int) (*repository2.InstalledApps, error) FindNotesForArgoApplication(installedAppId, envId int) (string, string, error) @@ -833,7 +833,7 @@ func (impl *InstalledAppServiceImpl) FindAppDetailsForAppstoreApplication(instal impl.logger.Error(err) return bean2.AppDetailContainer{}, err } - helmReleaseInstallStatus, err := impl.installedAppRepository.GetHelmReleaseStatusConfigByInstalledAppId(installedAppVerison.InstalledAppId) + helmReleaseInstallStatus, status, err := impl.installedAppRepository.GetHelmReleaseStatusConfigByInstalledAppId(installedAppVerison.InstalledAppId) if err != nil { impl.logger.Errorw("error in getting helm release status from db", "err", err) return bean2.AppDetailContainer{}, err @@ -863,6 +863,7 @@ func (impl *InstalledAppServiceImpl) FindAppDetailsForAppstoreApplication(instal DeploymentAppDeleteRequest: installedAppVerison.InstalledApp.DeploymentAppDeleteRequest, IsVirtualEnvironment: installedAppVerison.InstalledApp.Environment.IsVirtualEnvironment, HelmReleaseInstallStatus: helmReleaseInstallStatus, + Status: status, } userInfo, err := impl.userService.GetByIdIncludeDeleted(installedAppVerison.AuditLog.UpdatedBy) if err != nil { @@ -1080,7 +1081,7 @@ func (impl InstalledAppServiceImpl) GetInstalledAppVersionHistoryValues(installe values.ValuesYaml = versionHistory.ValuesYamlRaw return values, err } -func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn http.CloseNotifier, appDetailsContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string) error { +func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn http.CloseNotifier, appDetailsContainer *bean2.AppDetailsContainer, installedApp repository2.InstalledApps, helmReleaseInstallStatus string, status string) error { var err error var resourceTree map[string]interface{} deploymentAppName := fmt.Sprintf("%s-%s", installedApp.App.AppName, installedApp.Environment.Name) @@ -1115,7 +1116,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h resourceTree["status"] = detail.ApplicationStatus appDetailsContainer.Notes = detail.ChartMetadata.Notes - helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} + helmInstallStatus := &appStoreBean.HelmReleaseStatusConfig{} releaseStatus := detail.ReleaseStatus if len(helmReleaseInstallStatus) > 0 { @@ -1133,14 +1134,14 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h 3) In this case we use helmReleaseInstallStatus which will have status of our release and not external release */ resourceTree = make(map[string]interface{}) - releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) + releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) } } releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap } else { // case when helm release is not created - releaseStatus := impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus) + releaseStatus := impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap } @@ -1157,22 +1158,20 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h return err } -func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus string) *client.ReleaseStatus { +func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus string, status string) *client.ReleaseStatus { //release status is sent in resource tree call and is shown on UI as helm config apply status releaseStatus := &client.ReleaseStatus{} if len(helmReleaseInstallStatus) > 0 { - helmInstallStatus := &appStoreBean.HelmInstallNatsMessage{} + helmInstallStatus := &appStoreBean.HelmReleaseStatusConfig{} err := json.Unmarshal([]byte(helmReleaseInstallStatus), helmInstallStatus) if err != nil { impl.logger.Errorw("error in unmarshalling helm release install status") return releaseStatus } - if helmInstallStatus.Status == "Failed" { - releaseStatus.Status = helmInstallStatus.Status + if status == "Failed" { releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release install/upgrade failed" - } else if helmInstallStatus.Status == "Progressing" { - releaseStatus.Status = helmInstallStatus.Status + } else if status == "Progressing" { releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = helmInstallStatus.Message } else { From 8577a8be8f17f5fa6516801b11f5bc57f6c8b2ba Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 13:28:47 +0530 Subject: [PATCH 26/35] progressing state --- .../deployment/service/AppStoreDeploymentService.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 213ea577e5..33ff4ab0e8 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -289,6 +289,17 @@ func (impl AppStoreDeploymentServiceImpl) AppStoreDeployOperationDB(installAppVe installedAppVersionHistory.UpdatedOn = time.Now() installedAppVersionHistory.StartedOn = time.Now() installedAppVersionHistory.Status = pipelineConfig.WorkflowInProgress + helmInstallConfigDTO := appStoreBean.HelmReleaseStatusConfig{ + InstallAppVersionHistoryId: 0, + Message: "Install initiated", + IsReleaseInstalled: false, + ErrorInInstallation: false, + } + helmInstallConfig, err := json.Marshal(helmInstallConfigDTO) + if err != nil { + impl.logger.Errorw("error in helm install config marshal", "err") + } + installedAppVersionHistory.HelmReleaseStatusConfig = string(helmInstallConfig) _, err = impl.installedAppRepositoryHistory.CreateInstalledAppVersionHistory(installedAppVersionHistory, tx) if err != nil { impl.logger.Errorw("error while fetching from db", "error", err) From fe3891048d6591868116ed6d1239ea82e63654b9 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 15:14:09 +0530 Subject: [PATCH 27/35] wip --- pkg/appStore/deployment/service/InstalledAppService.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 582436f0ea..a750d785e0 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1169,9 +1169,11 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus return releaseStatus } if status == "Failed" { + releaseStatus.Status = status releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release install/upgrade failed" } else if status == "Progressing" { + releaseStatus.Status = status releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = helmInstallStatus.Message } else { From 065015b858f6be7050c381f7b078548692ab3d56 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 16:36:24 +0530 Subject: [PATCH 28/35] wip --- App.go | 2 +- .../service/AppStoreDeploymentService.go | 41 ------------------- .../deployment/service/InstalledAppService.go | 2 +- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/App.go b/App.go index bb55b4700b..ff250a25c0 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8080 //TODO: extract from environment variable + port := 8081 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go index 33ff4ab0e8..138c26604c 100644 --- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go +++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go @@ -460,47 +460,6 @@ func (impl AppStoreDeploymentServiceImpl) InstallApp(installAppVersionRequest *a return installAppVersionRequest, nil } -//func (impl AppStoreDeploymentServiceImpl) InstallApp(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ctx context.Context) (*appStoreBean.InstallAppVersionDTO, error) { -// -// dbConnection := impl.installedAppRepository.GetConnection() -// tx, err := dbConnection.Begin() -// if err != nil { -// return nil, err -// } -// // Rollback tx on error. -// defer tx.Rollback() -// -// //step 1 db operation initiated -// installAppVersionRequest, err = impl.AppStoreDeployOperationDB(installAppVersionRequest, tx, false) -// if err != nil { -// impl.logger.Errorw(" error", "err", err) -// return nil, err -// } -// -// if util2.IsBaseStack() || util2.IsHelmApp(installAppVersionRequest.AppOfferingMode) || util.IsHelmApp(installAppVersionRequest.DeploymentAppType) { -// installAppVersionRequest, err = impl.appStoreDeploymentHelmService.InstallApp(installAppVersionRequest, ctx) -// } else { -// installAppVersionRequest, err = impl.appStoreDeploymentArgoCdService.InstallApp(installAppVersionRequest, ctx) -// } -// -// if err != nil { -// return nil, err -// } -// -// // tx commit here because next operation will be process after this commit. -// err = tx.Commit() -// if err != nil { -// return nil, err -// } -// -// err = impl.installAppPostDbOperation(installAppVersionRequest) -// if err != nil { -// return nil, err -// } -// -// return installAppVersionRequest, nil -//} - func (impl AppStoreDeploymentServiceImpl) UpdateInstalledAppVersionHistoryStatus(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, status string) error { dbConnection := impl.installedAppRepository.GetConnection() tx, err := dbConnection.Begin() diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index a750d785e0..c699c5e587 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1126,7 +1126,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h return err } // ReleaseExist=true in app detail container but helm install status says that isReleaseInstalled=false which means this release was created externally - if helmInstallStatus.IsReleaseInstalled == false { + if helmInstallStatus.IsReleaseInstalled == false && status != "Progressing" { /* Handling case when :- 1) An external release with name "foo" exist From 7bff00f2aae22fd5f3e7a775d51f76e1a38d6615 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 17:05:01 +0530 Subject: [PATCH 29/35] port fix --- App.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App.go b/App.go index ff250a25c0..bb55b4700b 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8081 //TODO: extract from environment variable + port := 8080 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) From f16e2c37cf0e57b2b5169808c615c5c92e39bf81 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 17:47:18 +0530 Subject: [PATCH 30/35] pr review --- .../tool/AppStoreDeploymentHelmService.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go index 28779315ea..f5a99a1ec7 100644 --- a/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go +++ b/pkg/appStore/deployment/tool/AppStoreDeploymentHelmService.go @@ -126,8 +126,8 @@ func (impl AppStoreDeploymentHelmServiceImpl) InstallApp(installAppVersionReques ReleaseNamespace: installAppVersionRequest.Namespace, ReleaseName: installAppVersionRequest.AppName, }, - IsOCIRepo: IsOCIRepo, - RegistryCredential: registryCredential, + IsOCIRepo: IsOCIRepo, + RegistryCredential: registryCredential, InstallAppVersionHistoryId: int32(installAppVersionRequest.InstalledAppVersionHistoryId), } @@ -304,7 +304,7 @@ func (impl *AppStoreDeploymentHelmServiceImpl) OnUpdateRepoInInstalledApp(ctx co } } - err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml, 0) + err := impl.updateApplicationWithChartInfo(ctx, installAppVersionRequest.InstalledAppId, installAppVersionRequest.AppStoreVersion, installAppVersionRequest.ValuesOverrideYaml, installAppVersionRequest.InstalledAppVersionHistoryId) if err != nil { return installAppVersionRequest, err } @@ -443,11 +443,11 @@ func (impl *AppStoreDeploymentHelmServiceImpl) updateApplicationWithChartInfo(ct ReleaseNamespace: installedApp.Environment.Namespace, ReleaseName: installedApp.App.AppName, }, - ChartName: appStoreApplicationVersion.Name, - ChartVersion: appStoreApplicationVersion.Version, - ChartRepository: chartRepository, - RegistryCredential: registryCredential, - IsOCIRepo: IsOCIRepo, + ChartName: appStoreApplicationVersion.Name, + ChartVersion: appStoreApplicationVersion.Version, + ChartRepository: chartRepository, + RegistryCredential: registryCredential, + IsOCIRepo: IsOCIRepo, InstallAppVersionHistoryId: int32(installAppVersionHistoryId), }, SourceAppType: client.SOURCE_HELM_APP, From 4fa8977dbcdf45ab85316bae3e4ca5eb4b8a8495 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 17:51:14 +0530 Subject: [PATCH 31/35] pr review --- .../deployment/service/InstalledAppService.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index c699c5e587..5cfe882548 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -81,6 +81,9 @@ import ( const ( DEFAULT_ENVIRONMENT_OR_NAMESPACE_OR_PROJECT = "devtron" CLUSTER_COMPONENT_DIR_PATH = "/cluster/component" + HELM_RELEASE_STATUS_FAILED = "Failed" + HELM_RELEASE_STATUS_PROGRESSING = "Progressing" + HELM_RELEASE_STATUS_UNKNOWN = "Unknown" ) type InstalledAppService interface { @@ -1168,22 +1171,22 @@ func (impl InstalledAppServiceImpl) getReleaseStatusFromHelmReleaseInstallStatus impl.logger.Errorw("error in unmarshalling helm release install status") return releaseStatus } - if status == "Failed" { + if status == HELM_RELEASE_STATUS_FAILED { releaseStatus.Status = status releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = "Release install/upgrade failed" - } else if status == "Progressing" { + } else if status == HELM_RELEASE_STATUS_PROGRESSING { releaseStatus.Status = status releaseStatus.Description = helmInstallStatus.Message releaseStatus.Message = helmInstallStatus.Message } else { // there can be a case when helm release is created but we are not able to fetch it - releaseStatus.Status = "Unknown" + releaseStatus.Status = HELM_RELEASE_STATUS_UNKNOWN releaseStatus.Description = "Unable to fetch release for app" releaseStatus.Message = "Unable to fetch release for app" } } else { - releaseStatus.Status = "Unknown" + releaseStatus.Status = HELM_RELEASE_STATUS_UNKNOWN releaseStatus.Description = "Release not found" releaseStatus.Message = "Release not found " } From d69010c3def54c11b1846d38f14dc36711fe4a81 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 18:37:17 +0530 Subject: [PATCH 32/35] common-lib update --- App.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- pkg/appStore/deployment/service/InstalledAppService.go | 3 +++ vendor/modules.txt | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/App.go b/App.go index bb55b4700b..ff250a25c0 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8080 //TODO: extract from environment variable + port := 8081 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port) diff --git a/go.mod b/go.mod index ed535534e7..3e92e5f474 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53 - github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 + github.com/devtron-labs/common-lib v0.0.2 github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2 github.com/evanphx/json-patch v5.6.0+incompatible github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 diff --git a/go.sum b/go.sum index 779f206ce6..68c1ae115d 100644 --- a/go.sum +++ b/go.sum @@ -292,8 +292,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADG github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53 h1:oHDpsCsuYiL+u5TEhilKNLGhH9lwRNkIqrzhHQA6d3c= github.com/devtron-labs/authenticator v0.4.31-0.20221213131053-6e4668309f53/go.mod h1:ozNfT8WcruiSgnUbyp48WVfc41++W6xYXhKFp67lNTU= -github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 h1:BNyGu3HBIiHDNo2rbk/tv75O3rt9dSY/9OkGPhwD/8s= -github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327/go.mod h1:R24nOqgk4buk9zv+BXzORfObZsOe3NE9P55KrZXGX9k= +github.com/devtron-labs/common-lib v0.0.2 h1:YiCS6+e/KhKF/oW2Amn56N6/onxe0kE9g9b9KKn/HYI= +github.com/devtron-labs/common-lib v0.0.2/go.mod h1:R24nOqgk4buk9zv+BXzORfObZsOe3NE9P55KrZXGX9k= github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2 h1:/IEIsJTxDZ3hv8uOoCaqdWCXqcv7nCAgX9AP/v84dUY= github.com/devtron-labs/protos v0.0.0-20230503113602-282404f70fd2/go.mod h1:l85jxWHlcSo910hdUfRycL40yGzC6glE93V1sVxVPto= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 5cfe882548..408c7c1d3a 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1139,6 +1139,9 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h resourceTree = make(map[string]interface{}) releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) } + if helmInstallStatus.IsReleaseInstalled && helmInstallStatus.ErrorInInstallation { + releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) + } } releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap diff --git a/vendor/modules.txt b/vendor/modules.txt index 6cccabdaa5..a2146129dd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -339,7 +339,7 @@ github.com/devtron-labs/authenticator/jwt github.com/devtron-labs/authenticator/middleware github.com/devtron-labs/authenticator/oidc github.com/devtron-labs/authenticator/password -# github.com/devtron-labs/common-lib v0.0.0-20230821120530-56d8ed4bc327 +# github.com/devtron-labs/common-lib v0.0.2 ## explicit; go 1.18 github.com/devtron-labs/common-lib/blob-storage github.com/devtron-labs/common-lib/pubsub-lib From 8cba7bc798fe960c0778345b5e5ee7d8741c7f3a Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 18:52:19 +0530 Subject: [PATCH 33/35] failed on update handling --- pkg/appStore/deployment/service/InstalledAppService.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 408c7c1d3a..93f4a693f3 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1139,7 +1139,7 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h resourceTree = make(map[string]interface{}) releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) } - if helmInstallStatus.IsReleaseInstalled && helmInstallStatus.ErrorInInstallation { + if status == "Failed" { releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) } } From 67c3afe567a9187bb5135f25105b7f1a12d2e253 Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 18:56:02 +0530 Subject: [PATCH 34/35] reverting --- pkg/appStore/deployment/service/InstalledAppService.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/appStore/deployment/service/InstalledAppService.go b/pkg/appStore/deployment/service/InstalledAppService.go index 93f4a693f3..5cfe882548 100644 --- a/pkg/appStore/deployment/service/InstalledAppService.go +++ b/pkg/appStore/deployment/service/InstalledAppService.go @@ -1139,9 +1139,6 @@ func (impl InstalledAppServiceImpl) FetchResourceTree(rctx context.Context, cn h resourceTree = make(map[string]interface{}) releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) } - if status == "Failed" { - releaseStatus = impl.getReleaseStatusFromHelmReleaseInstallStatus(helmReleaseInstallStatus, status) - } } releaseStatusMap := util3.InterfaceToMapAdapter(releaseStatus) appDetailsContainer.ReleaseStatus = releaseStatusMap From 99a61bc76161a1b31d081df3cb75e6640a8418ed Mon Sep 17 00:00:00 2001 From: ayushmaheshwari Date: Thu, 21 Sep 2023 19:06:26 +0530 Subject: [PATCH 35/35] port revert --- App.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App.go b/App.go index ff250a25c0..bb55b4700b 100644 --- a/App.go +++ b/App.go @@ -87,7 +87,7 @@ func NewApp(router *router.MuxRouter, } func (app *App) Start() { - port := 8081 //TODO: extract from environment variable + port := 8080 //TODO: extract from environment variable app.Logger.Debugw("starting server") app.Logger.Infow("starting server on ", "port", port)