From 47895e6b1ac24f07c377eb92fc756e11b78f2485 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Wed, 19 Jul 2023 09:22:28 -0400 Subject: [PATCH] fix(api): return 404 when the app is not found if a project is specified (#13393) (#13394) * fix(api): return 404 when the app is not found if a project is specified (#13393) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> simplify, respond 404 on project specified but doesn't match, always fetch app Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> handle project updates Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * handle new endpoint, fix bad merge Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- assets/swagger.json | 117 ++ docs/developer-guide/api-docs.md | 17 +- pkg/apiclient/application/application.pb.go | 1371 ++++++++++++++++--- server/application/application.go | 130 +- server/application/application.proto | 25 +- server/application/application_test.go | 59 +- 6 files changed, 1491 insertions(+), 228 deletions(-) diff --git a/assets/swagger.json b/assets/swagger.json index f8a7b3208793d..38d98c3460b35 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -401,6 +401,11 @@ "type": "boolean", "name": "validate", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -462,6 +467,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -523,6 +533,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -649,6 +664,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -737,6 +757,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -773,6 +798,11 @@ "type": "string", "name": "namespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -885,6 +915,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -935,6 +970,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -971,6 +1011,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1084,6 +1129,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1154,6 +1204,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1226,6 +1281,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1295,6 +1355,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1356,6 +1421,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1423,6 +1493,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1484,6 +1559,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1529,6 +1609,11 @@ "description": "the application's namespace.", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1574,6 +1659,11 @@ "description": "the application's namespace.", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1662,6 +1752,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -1737,6 +1832,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -3833,6 +3933,11 @@ "type": "string", "name": "appNamespace", "in": "query" + }, + { + "type": "string", + "name": "project", + "in": "query" } ], "responses": { @@ -3998,6 +4103,9 @@ }, "name": { "type": "string" + }, + "project": { + "type": "string" } } }, @@ -4027,6 +4135,9 @@ }, "patchType": { "type": "string" + }, + "project": { + "type": "string" } } }, @@ -4057,6 +4168,9 @@ "name": { "type": "string" }, + "project": { + "type": "string" + }, "prune": { "type": "boolean" } @@ -4087,6 +4201,9 @@ "name": { "type": "string" }, + "project": { + "type": "string" + }, "prune": { "type": "boolean" }, diff --git a/docs/developer-guide/api-docs.md b/docs/developer-guide/api-docs.md index 7b4b44bf9269e..289e4d466652e 100644 --- a/docs/developer-guide/api-docs.md +++ b/docs/developer-guide/api-docs.md @@ -1,6 +1,6 @@ # API Docs -You can find the Swagger docs by setting the path to `/swagger-ui` in your Argo CD UI's. E.g. [http://localhost:8080/swagger-ui](http://localhost:8080/swagger-ui). +You can find the Swagger docs by setting the path to `/swagger-ui` in your Argo CD UI. E.g. [http://localhost:8080/swagger-ui](http://localhost:8080/swagger-ui). ## Authorization @@ -17,4 +17,17 @@ Then pass using the HTTP `Authorization` header, prefixing with `Bearer `: $ curl $ARGOCD_SERVER/api/v1/applications -H "Authorization: Bearer $ARGOCD_TOKEN" {"metadata":{"selfLink":"/apis/argoproj.io/v1alpha1/namespaces/argocd/applications","resourceVersion":"37755"},"items":...} ``` - + +## Services + +### Applications API + +#### How to Avoid 403 Errors for Missing Applications + +All endpoints of the Applications API accept an optional `project` query string parameter. If the parameter is +specified, and the specified Application does not exist, or if the Application does exist but is not in the given +project, the API will return a `404` error. + +If the `project` query string parameter is specified, and the Application does not exist, the API will return a `403` +error. This is to prevent leaking information about the existence of Applications to users who do not have access to +them. diff --git a/pkg/apiclient/application/application.pb.go b/pkg/apiclient/application/application.pb.go index 0035796551791..8fd016ee36f68 100644 --- a/pkg/apiclient/application/application.pb.go +++ b/pkg/apiclient/application/application.pb.go @@ -36,7 +36,11 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// ApplicationQuery is a query for application resources +// ApplicationQuery is a query for application resources. When getting multiple applications, the "projects" field acts +// as a filter. When getting a single application, you may specify either zero or one project. If you specify zero +// projects, the application will be returned regardless of which project it belongs to (assuming you have access). If +// you specify one project, the application will only be returned if it exists and belongs to the specified project. +// Otherwise you will receive a 404. type ApplicationQuery struct { // the application's name Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` @@ -211,6 +215,7 @@ type RevisionMetadataQuery struct { Revision *string `protobuf:"bytes,2,req,name=revision" json:"revision,omitempty"` // the application's namespace AppNamespace *string `protobuf:"bytes,3,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -270,6 +275,13 @@ func (m *RevisionMetadataQuery) GetAppNamespace() string { return "" } +func (m *RevisionMetadataQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + // ApplicationEventsQuery is a query for application resource events type ApplicationResourceEventsQuery struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` @@ -277,6 +289,7 @@ type ApplicationResourceEventsQuery struct { ResourceName *string `protobuf:"bytes,3,opt,name=resourceName" json:"resourceName,omitempty"` ResourceUID *string `protobuf:"bytes,4,opt,name=resourceUID" json:"resourceUID,omitempty"` AppNamespace *string `protobuf:"bytes,5,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,6,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -350,11 +363,19 @@ func (m *ApplicationResourceEventsQuery) GetAppNamespace() string { return "" } +func (m *ApplicationResourceEventsQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + // ManifestQuery is a query for manifest resources type ApplicationManifestQuery struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Revision *string `protobuf:"bytes,2,opt,name=revision" json:"revision,omitempty"` AppNamespace *string `protobuf:"bytes,3,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -414,6 +435,13 @@ func (m *ApplicationManifestQuery) GetAppNamespace() string { return "" } +func (m *ApplicationManifestQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type FileChunk struct { Chunk []byte `protobuf:"bytes,1,req,name=chunk" json:"chunk,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -465,6 +493,7 @@ type ApplicationManifestQueryWithFiles struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Checksum *string `protobuf:"bytes,2,req,name=checksum" json:"checksum,omitempty"` AppNamespace *string `protobuf:"bytes,3,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -524,6 +553,13 @@ func (m *ApplicationManifestQueryWithFiles) GetAppNamespace() string { return "" } +func (m *ApplicationManifestQueryWithFiles) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationManifestQueryWithFilesWrapper struct { // Types that are valid to be assigned to Part: // *ApplicationManifestQueryWithFilesWrapper_Query @@ -721,6 +757,7 @@ func (m *ApplicationCreateRequest) GetValidate() bool { type ApplicationUpdateRequest struct { Application *v1alpha1.Application `protobuf:"bytes,1,req,name=application" json:"application,omitempty"` Validate *bool `protobuf:"varint,2,opt,name=validate" json:"validate,omitempty"` + Project *string `protobuf:"bytes,3,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -773,11 +810,19 @@ func (m *ApplicationUpdateRequest) GetValidate() bool { return false } +func (m *ApplicationUpdateRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationDeleteRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Cascade *bool `protobuf:"varint,2,opt,name=cascade" json:"cascade,omitempty"` PropagationPolicy *string `protobuf:"bytes,3,opt,name=propagationPolicy" json:"propagationPolicy,omitempty"` AppNamespace *string `protobuf:"bytes,4,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,5,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -844,6 +889,13 @@ func (m *ApplicationDeleteRequest) GetAppNamespace() string { return "" } +func (m *ApplicationDeleteRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type SyncOptions struct { Items []string `protobuf:"bytes,1,rep,name=items" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -904,6 +956,7 @@ type ApplicationSyncRequest struct { RetryStrategy *v1alpha1.RetryStrategy `protobuf:"bytes,10,opt,name=retryStrategy" json:"retryStrategy,omitempty"` SyncOptions *SyncOptions `protobuf:"bytes,11,opt,name=syncOptions" json:"syncOptions,omitempty"` AppNamespace *string `protobuf:"bytes,12,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,13,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1019,12 +1072,20 @@ func (m *ApplicationSyncRequest) GetAppNamespace() string { return "" } +func (m *ApplicationSyncRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + // ApplicationUpdateSpecRequest is a request to update application spec type ApplicationUpdateSpecRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Spec *v1alpha1.ApplicationSpec `protobuf:"bytes,2,req,name=spec" json:"spec,omitempty"` Validate *bool `protobuf:"varint,3,opt,name=validate" json:"validate,omitempty"` AppNamespace *string `protobuf:"bytes,4,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,5,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1091,12 +1152,20 @@ func (m *ApplicationUpdateSpecRequest) GetAppNamespace() string { return "" } +func (m *ApplicationUpdateSpecRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + // ApplicationPatchRequest is a request to patch an application type ApplicationPatchRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Patch *string `protobuf:"bytes,2,req,name=patch" json:"patch,omitempty"` PatchType *string `protobuf:"bytes,3,req,name=patchType" json:"patchType,omitempty"` AppNamespace *string `protobuf:"bytes,5,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,6,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1163,12 +1232,20 @@ func (m *ApplicationPatchRequest) GetAppNamespace() string { return "" } +func (m *ApplicationPatchRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationRollbackRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Id *int64 `protobuf:"varint,2,req,name=id" json:"id,omitempty"` DryRun *bool `protobuf:"varint,3,opt,name=dryRun" json:"dryRun,omitempty"` Prune *bool `protobuf:"varint,4,opt,name=prune" json:"prune,omitempty"` AppNamespace *string `protobuf:"bytes,6,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,7,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1242,6 +1319,13 @@ func (m *ApplicationRollbackRequest) GetAppNamespace() string { return "" } +func (m *ApplicationRollbackRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationResourceRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` @@ -1250,6 +1334,7 @@ type ApplicationResourceRequest struct { Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"` Kind *string `protobuf:"bytes,6,req,name=kind" json:"kind,omitempty"` AppNamespace *string `protobuf:"bytes,7,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,8,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1337,6 +1422,13 @@ func (m *ApplicationResourceRequest) GetAppNamespace() string { return "" } +func (m *ApplicationResourceRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationResourcePatchRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` @@ -1347,6 +1439,7 @@ type ApplicationResourcePatchRequest struct { Patch *string `protobuf:"bytes,7,req,name=patch" json:"patch,omitempty"` PatchType *string `protobuf:"bytes,8,req,name=patchType" json:"patchType,omitempty"` AppNamespace *string `protobuf:"bytes,9,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,10,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1448,6 +1541,13 @@ func (m *ApplicationResourcePatchRequest) GetAppNamespace() string { return "" } +func (m *ApplicationResourcePatchRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationResourceDeleteRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` @@ -1458,6 +1558,7 @@ type ApplicationResourceDeleteRequest struct { Force *bool `protobuf:"varint,7,opt,name=force" json:"force,omitempty"` Orphan *bool `protobuf:"varint,8,opt,name=orphan" json:"orphan,omitempty"` AppNamespace *string `protobuf:"bytes,9,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,10,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1559,6 +1660,13 @@ func (m *ApplicationResourceDeleteRequest) GetAppNamespace() string { return "" } +func (m *ApplicationResourceDeleteRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ResourceActionRunRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` @@ -1568,6 +1676,7 @@ type ResourceActionRunRequest struct { Kind *string `protobuf:"bytes,6,req,name=kind" json:"kind,omitempty"` Action *string `protobuf:"bytes,7,req,name=action" json:"action,omitempty"` AppNamespace *string `protobuf:"bytes,8,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,9,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1662,6 +1771,13 @@ func (m *ResourceActionRunRequest) GetAppNamespace() string { return "" } +func (m *ResourceActionRunRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ResourceActionsListResponse struct { Actions []*v1alpha1.ResourceAction `protobuf:"bytes,1,rep,name=actions" json:"actions,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -1772,6 +1888,7 @@ type ApplicationPodLogsQuery struct { ResourceName *string `protobuf:"bytes,13,opt,name=resourceName" json:"resourceName,omitempty"` Previous *bool `protobuf:"varint,14,opt,name=previous" json:"previous,omitempty"` AppNamespace *string `protobuf:"bytes,15,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,16,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1915,6 +2032,13 @@ func (m *ApplicationPodLogsQuery) GetAppNamespace() string { return "" } +func (m *ApplicationPodLogsQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type LogEntry struct { Content *string `protobuf:"bytes,1,req,name=content" json:"content,omitempty"` // deprecated in favor of timeStampStr since meta.v1.Time don't support nano time @@ -1998,6 +2122,7 @@ func (m *LogEntry) GetPodName() string { type OperationTerminateRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` AppNamespace *string `protobuf:"bytes,2,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,3,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2050,9 +2175,17 @@ func (m *OperationTerminateRequest) GetAppNamespace() string { return "" } +func (m *OperationTerminateRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationSyncWindowsQuery struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` AppNamespace *string `protobuf:"bytes,2,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,3,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2105,6 +2238,13 @@ func (m *ApplicationSyncWindowsQuery) GetAppNamespace() string { return "" } +func (m *ApplicationSyncWindowsQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ApplicationSyncWindowsResponse struct { ActiveWindows []*ApplicationSyncWindow `protobuf:"bytes,1,rep,name=activeWindows" json:"activeWindows,omitempty"` AssignedWindows []*ApplicationSyncWindow `protobuf:"bytes,2,rep,name=assignedWindows" json:"assignedWindows,omitempty"` @@ -2286,6 +2426,7 @@ type ResourcesQuery struct { Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"` Kind *string `protobuf:"bytes,6,opt,name=kind" json:"kind,omitempty"` AppNamespace *string `protobuf:"bytes,7,opt,name=appNamespace" json:"appNamespace,omitempty"` + Project *string `protobuf:"bytes,8,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2373,6 +2514,13 @@ func (m *ResourcesQuery) GetAppNamespace() string { return "" } +func (m *ResourcesQuery) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + type ManagedResourcesResponse struct { Items []*v1alpha1.ResourceDiff `protobuf:"bytes,1,rep,name=items" json:"items,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -2541,6 +2689,7 @@ func (m *LinksResponse) GetItems() []*LinkInfo { type ListAppLinksRequest struct { Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` Namespace *string `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` + Project *string `protobuf:"bytes,4,opt,name=project" json:"project,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2593,6 +2742,13 @@ func (m *ListAppLinksRequest) GetNamespace() string { return "" } +func (m *ListAppLinksRequest) GetProject() string { + if m != nil && m.Project != nil { + return *m.Project + } + return "" +} + func init() { proto.RegisterType((*ApplicationQuery)(nil), "application.ApplicationQuery") proto.RegisterType((*NodeQuery)(nil), "application.NodeQuery") @@ -2636,172 +2792,175 @@ func init() { } var fileDescriptor_df6e82b174b5eaec = []byte{ - // 2630 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcb, 0x8f, 0x1c, 0x49, - 0xd1, 0xff, 0xb2, 0xe7, 0xd5, 0x1d, 0x3d, 0x7e, 0xe5, 0xda, 0xf3, 0xd5, 0xb6, 0xc7, 0x66, 0x5c, - 0x7e, 0x8d, 0xc7, 0x9e, 0x6e, 0xbb, 0x31, 0xc8, 0x3b, 0xbb, 0x2b, 0xb0, 0xc7, 0x4f, 0x18, 0x7b, - 0x4d, 0x8d, 0x8d, 0xd1, 0x72, 0x80, 0xdc, 0xaa, 0x9c, 0x9e, 0x62, 0xaa, 0xab, 0xca, 0x55, 0xd5, - 0x6d, 0x8d, 0x8c, 0x2f, 0x8b, 0xb8, 0xad, 0x16, 0x69, 0x77, 0x0f, 0x68, 0xb5, 0x42, 0x68, 0x57, - 0x7b, 0xe1, 0xc2, 0x0d, 0x21, 0x71, 0x81, 0x0b, 0x02, 0x09, 0x24, 0xc4, 0xe3, 0x02, 0x17, 0x64, - 0x71, 0xe3, 0xc2, 0x81, 0x3f, 0x00, 0x65, 0x56, 0x66, 0x55, 0x56, 0x77, 0x75, 0x75, 0x0d, 0x33, - 0x68, 0x7d, 0xab, 0xc8, 0xce, 0x8c, 0xf8, 0x45, 0x64, 0x64, 0x44, 0x64, 0x64, 0xc3, 0xa9, 0x90, - 0x06, 0x7d, 0x1a, 0xb4, 0x88, 0xef, 0x3b, 0xb6, 0x49, 0x22, 0xdb, 0x73, 0xd5, 0xef, 0xa6, 0x1f, - 0x78, 0x91, 0x87, 0xeb, 0xca, 0x50, 0x63, 0xbe, 0xe3, 0x79, 0x1d, 0x87, 0xb6, 0x88, 0x6f, 0xb7, - 0x88, 0xeb, 0x7a, 0x11, 0x1f, 0x0e, 0xe3, 0xa9, 0x0d, 0x7d, 0xeb, 0x4a, 0xd8, 0xb4, 0x3d, 0xfe, - 0xab, 0xe9, 0x05, 0xb4, 0xd5, 0xbf, 0xd4, 0xea, 0x50, 0x97, 0x06, 0x24, 0xa2, 0x96, 0x98, 0x73, - 0x39, 0x9d, 0xd3, 0x25, 0xe6, 0xa6, 0xed, 0xd2, 0x60, 0xbb, 0xe5, 0x6f, 0x75, 0xd8, 0x40, 0xd8, - 0xea, 0xd2, 0x88, 0xe4, 0xad, 0x5a, 0xeb, 0xd8, 0xd1, 0x66, 0xef, 0xad, 0xa6, 0xe9, 0x75, 0x5b, - 0x24, 0xe8, 0x78, 0x7e, 0xe0, 0x7d, 0x87, 0x7f, 0x2c, 0x9b, 0x56, 0xab, 0xdf, 0x4e, 0x19, 0xa8, - 0xba, 0xf4, 0x2f, 0x11, 0xc7, 0xdf, 0x24, 0xc3, 0xdc, 0x6e, 0x8c, 0xe1, 0x16, 0x50, 0xdf, 0x13, - 0xb6, 0xe1, 0x9f, 0x76, 0xe4, 0x05, 0xdb, 0xca, 0x67, 0xcc, 0x46, 0xff, 0x37, 0x82, 0x83, 0x57, - 0x53, 0x79, 0x5f, 0xeb, 0xd1, 0x60, 0x1b, 0x63, 0x98, 0x74, 0x49, 0x97, 0x6a, 0x68, 0x01, 0x2d, - 0xd6, 0x0c, 0xfe, 0x8d, 0x35, 0x98, 0x09, 0xe8, 0x46, 0x40, 0xc3, 0x4d, 0xad, 0xc2, 0x87, 0x25, - 0x89, 0x1b, 0x50, 0x65, 0xc2, 0xa9, 0x19, 0x85, 0xda, 0xc4, 0xc2, 0xc4, 0x62, 0xcd, 0x48, 0x68, - 0xbc, 0x08, 0x07, 0x02, 0x1a, 0x7a, 0xbd, 0xc0, 0xa4, 0x5f, 0xa7, 0x41, 0x68, 0x7b, 0xae, 0x36, - 0xc9, 0x57, 0x0f, 0x0e, 0x33, 0x2e, 0x21, 0x75, 0xa8, 0x19, 0x79, 0x81, 0x36, 0xc5, 0xa7, 0x24, - 0x34, 0xc3, 0xc3, 0x80, 0x6b, 0xd3, 0x31, 0x1e, 0xf6, 0x8d, 0x75, 0x98, 0x25, 0xbe, 0x7f, 0x8f, - 0x74, 0x69, 0xe8, 0x13, 0x93, 0x6a, 0x33, 0xfc, 0xb7, 0xcc, 0x18, 0xc3, 0x2c, 0x90, 0x68, 0x55, - 0x0e, 0x4c, 0x92, 0xfa, 0x2a, 0xd4, 0xee, 0x79, 0x16, 0x1d, 0xad, 0xee, 0x20, 0xfb, 0xca, 0x30, - 0x7b, 0x7d, 0x0b, 0x8e, 0x18, 0xb4, 0x6f, 0x33, 0xf8, 0x77, 0x69, 0x44, 0x2c, 0x12, 0x91, 0x41, - 0x86, 0x95, 0x84, 0x61, 0x03, 0xaa, 0x81, 0x98, 0xac, 0x55, 0xf8, 0x78, 0x42, 0x0f, 0x09, 0x9b, - 0xc8, 0x11, 0xf6, 0x3b, 0x04, 0xc7, 0x95, 0x8d, 0x32, 0x84, 0xf9, 0x6e, 0xf4, 0xa9, 0x1b, 0x85, - 0xa3, 0xc5, 0x5e, 0x80, 0x43, 0xd2, 0xd2, 0x83, 0xca, 0x0c, 0xff, 0xc0, 0x80, 0xa8, 0x83, 0x12, - 0x88, 0x3a, 0x86, 0x17, 0xa0, 0x2e, 0xe9, 0x87, 0x77, 0xae, 0x8b, 0xed, 0x54, 0x87, 0x86, 0xd4, - 0x99, 0xca, 0x51, 0xc7, 0x05, 0x4d, 0xd1, 0xe6, 0x2e, 0x71, 0xed, 0x0d, 0x1a, 0x46, 0x65, 0xcd, - 0x87, 0x76, 0x6c, 0xbe, 0x13, 0x50, 0xbb, 0x69, 0x3b, 0x74, 0x75, 0xb3, 0xe7, 0x6e, 0xe1, 0xc3, - 0x30, 0x65, 0xb2, 0x0f, 0x2e, 0x61, 0xd6, 0x88, 0x09, 0xfd, 0x09, 0x9c, 0x18, 0x05, 0xe9, 0x91, - 0x1d, 0x6d, 0xb2, 0xe5, 0xe1, 0x28, 0x6c, 0xe6, 0x26, 0x35, 0xb7, 0xc2, 0x5e, 0x57, 0x6e, 0xad, - 0xa4, 0x4b, 0x61, 0xfb, 0x09, 0x82, 0xc5, 0xb1, 0x92, 0x1f, 0x05, 0xc4, 0xf7, 0x69, 0x80, 0x6f, - 0xc2, 0xd4, 0x63, 0xf6, 0x03, 0xf7, 0xd6, 0x7a, 0xbb, 0xd9, 0x54, 0xa3, 0xdd, 0x58, 0x2e, 0xb7, - 0xff, 0xcf, 0x88, 0x97, 0xe3, 0xa6, 0xb4, 0x41, 0x85, 0xf3, 0x99, 0xcb, 0xf0, 0x49, 0x4c, 0xc5, - 0xe6, 0xf3, 0x69, 0xd7, 0xa6, 0x61, 0xd2, 0x27, 0x41, 0xa4, 0x1f, 0x81, 0x97, 0xb2, 0x6e, 0xe8, - 0x7b, 0x6e, 0x48, 0xf5, 0x5f, 0xa0, 0xcc, 0x86, 0xae, 0x06, 0x94, 0x44, 0xd4, 0xa0, 0x8f, 0x7b, - 0x34, 0x8c, 0xf0, 0x16, 0xa8, 0x01, 0x98, 0xdb, 0xae, 0xde, 0xbe, 0xd3, 0x4c, 0x23, 0x58, 0x53, - 0x46, 0x30, 0xfe, 0xf1, 0x2d, 0xd3, 0x6a, 0xf6, 0xdb, 0x4d, 0x7f, 0xab, 0xd3, 0x64, 0xf1, 0x30, - 0x83, 0x4c, 0xc6, 0x43, 0x55, 0x55, 0x43, 0xe5, 0x8e, 0xe7, 0x60, 0xba, 0xe7, 0x87, 0x34, 0x88, - 0xb8, 0x66, 0x55, 0x43, 0x50, 0x6c, 0x97, 0xfa, 0xc4, 0xb1, 0x2d, 0x12, 0xc5, 0xbb, 0x50, 0x35, - 0x12, 0x5a, 0xff, 0x24, 0x8b, 0xfe, 0xa1, 0x6f, 0x7d, 0x56, 0xe8, 0x55, 0x94, 0x95, 0x01, 0x94, - 0x1f, 0x66, 0x51, 0x5e, 0xa7, 0x0e, 0x4d, 0x51, 0xe6, 0x39, 0xa6, 0x06, 0x33, 0x26, 0x09, 0x4d, - 0x62, 0x49, 0x5e, 0x92, 0x64, 0x61, 0xc1, 0x0f, 0x3c, 0x9f, 0x74, 0x38, 0xa7, 0xfb, 0x9e, 0x63, - 0x9b, 0xdb, 0xc2, 0x37, 0x87, 0x7f, 0x18, 0x72, 0xe2, 0xc9, 0x1c, 0x27, 0x3e, 0x09, 0xf5, 0xf5, - 0x6d, 0xd7, 0x7c, 0xc3, 0xe7, 0xc9, 0x94, 0x1d, 0x31, 0x3b, 0xa2, 0xdd, 0x50, 0x43, 0x3c, 0xf0, - 0xc6, 0x84, 0xfe, 0xd1, 0x14, 0xcc, 0x29, 0x1a, 0xb0, 0x05, 0x45, 0xf8, 0x8b, 0x0e, 0xfd, 0x1c, - 0x4c, 0x5b, 0xc1, 0xb6, 0xd1, 0x73, 0xc5, 0x66, 0x0a, 0x8a, 0x09, 0xf6, 0x83, 0x9e, 0x1b, 0x83, - 0xac, 0x1a, 0x31, 0x81, 0x37, 0xa0, 0x1a, 0x46, 0x2c, 0x7d, 0x76, 0xb6, 0x79, 0x38, 0xaa, 0xb7, - 0xbf, 0xb2, 0xbb, 0x0d, 0x64, 0xd0, 0xd7, 0x05, 0x47, 0x23, 0xe1, 0x8d, 0x1f, 0x43, 0x4d, 0x46, - 0xc2, 0x50, 0x9b, 0x59, 0x98, 0x58, 0xac, 0xb7, 0xd7, 0x77, 0x2f, 0xe8, 0x0d, 0x9f, 0xa5, 0x7e, - 0x25, 0xea, 0x1b, 0xa9, 0x14, 0x3c, 0x0f, 0xb5, 0xae, 0x38, 0xeb, 0xa1, 0x48, 0x73, 0xe9, 0x00, - 0xfe, 0x06, 0x4c, 0xd9, 0xee, 0x86, 0x17, 0x6a, 0x35, 0x0e, 0xe6, 0xda, 0xee, 0xc0, 0xdc, 0x71, - 0x37, 0x3c, 0x23, 0x66, 0x88, 0x1f, 0xc3, 0xbe, 0x80, 0x46, 0xc1, 0xb6, 0xb4, 0x82, 0x06, 0xdc, - 0xae, 0x5f, 0xdd, 0x9d, 0x04, 0x43, 0x65, 0x69, 0x64, 0x25, 0xe0, 0x15, 0xa8, 0x87, 0xa9, 0x8f, - 0x69, 0x75, 0x2e, 0x50, 0xcb, 0x30, 0x52, 0x7c, 0xd0, 0x50, 0x27, 0x0f, 0xf9, 0xf0, 0x6c, 0x8e, - 0x0f, 0xff, 0x05, 0xc1, 0xfc, 0x50, 0x18, 0x58, 0xf7, 0x69, 0xa1, 0x93, 0x12, 0x98, 0x0c, 0x7d, - 0x6a, 0xf2, 0xc8, 0x5f, 0x6f, 0xdf, 0xdd, 0xb3, 0xb8, 0xc0, 0xe5, 0x72, 0xd6, 0x45, 0xa1, 0xab, - 0xd4, 0xd9, 0xfc, 0x3e, 0x82, 0xff, 0x57, 0x38, 0xdf, 0x27, 0x91, 0xb9, 0x59, 0xa4, 0x12, 0x3b, - 0x43, 0x6c, 0x8e, 0xc8, 0x66, 0x31, 0xc1, 0x1c, 0x8d, 0x7f, 0x3c, 0xd8, 0xf6, 0x19, 0x0c, 0xf6, - 0x4b, 0x3a, 0x50, 0x2a, 0xe9, 0xbf, 0x87, 0xa0, 0xa1, 0x46, 0x3e, 0xcf, 0x71, 0xde, 0x22, 0xe6, - 0x56, 0x11, 0x94, 0xfd, 0x50, 0xb1, 0x2d, 0x8e, 0x63, 0xc2, 0xa8, 0xd8, 0xd6, 0x0e, 0x8f, 0xfd, - 0x20, 0xa8, 0xe9, 0x1c, 0x50, 0x7f, 0x1d, 0x00, 0x25, 0x8f, 0x58, 0x01, 0xa8, 0x79, 0xa8, 0xb9, - 0x03, 0xc5, 0x54, 0x3a, 0x90, 0x53, 0x44, 0x55, 0x86, 0x8a, 0x28, 0x0d, 0x66, 0xfa, 0x49, 0x3d, - 0xcc, 0x7e, 0x96, 0x24, 0x53, 0xa4, 0x13, 0x78, 0x3d, 0x5f, 0x18, 0x30, 0x26, 0x18, 0x8a, 0x2d, - 0xdb, 0xb5, 0xb4, 0xe9, 0x18, 0x05, 0xfb, 0x2e, 0x53, 0x01, 0xeb, 0xef, 0x57, 0xe0, 0x73, 0x39, - 0xca, 0x8d, 0xf5, 0x80, 0x17, 0x43, 0xc3, 0xc4, 0x0f, 0x67, 0x46, 0xfa, 0x61, 0x75, 0x9c, 0x1f, - 0xd6, 0x72, 0xac, 0xf2, 0x6e, 0x05, 0x16, 0x72, 0xac, 0x32, 0x3e, 0xa1, 0xbe, 0x30, 0x66, 0xd9, - 0xf0, 0x02, 0xb1, 0xe3, 0x55, 0x23, 0x26, 0xd8, 0xc9, 0xf0, 0x02, 0x7f, 0x93, 0xb8, 0x5a, 0x35, - 0x3e, 0x19, 0x31, 0x55, 0xca, 0x20, 0xff, 0x42, 0xa0, 0x49, 0x2b, 0x5c, 0x35, 0xb9, 0x4d, 0x7a, - 0xee, 0x8b, 0x6f, 0x88, 0x39, 0x98, 0x26, 0x1c, 0xad, 0x70, 0x10, 0x41, 0x0d, 0xa9, 0x5c, 0xcd, - 0x8f, 0x89, 0x47, 0xb3, 0x2a, 0x87, 0x6b, 0x76, 0x18, 0xc9, 0x82, 0x16, 0x6f, 0xc0, 0x4c, 0xcc, - 0x2d, 0x2e, 0x61, 0xea, 0xed, 0xb5, 0xdd, 0x26, 0xb6, 0x8c, 0x79, 0x25, 0x73, 0xfd, 0x15, 0x38, - 0x9a, 0x1b, 0x7d, 0x04, 0x8c, 0x06, 0x54, 0x65, 0x32, 0x17, 0x1b, 0x90, 0xd0, 0xfa, 0x3f, 0x27, - 0xb2, 0x61, 0xdd, 0xb3, 0xd6, 0xbc, 0x4e, 0xc1, 0x5d, 0xb0, 0x78, 0xd3, 0xd8, 0x65, 0xd9, 0xb3, - 0x94, 0x6b, 0x9f, 0x24, 0xd9, 0x3a, 0xd3, 0x73, 0x23, 0x62, 0xbb, 0x34, 0x10, 0xf9, 0x25, 0x1d, - 0x60, 0xc6, 0x0e, 0x6d, 0xd7, 0xa4, 0xeb, 0xd4, 0xf4, 0x5c, 0x2b, 0xe4, 0xbb, 0x36, 0x61, 0x64, - 0xc6, 0xf0, 0x6d, 0xa8, 0x71, 0xfa, 0x81, 0xdd, 0x8d, 0x83, 0x70, 0xbd, 0xbd, 0xd4, 0x8c, 0x9b, - 0x28, 0x4d, 0xb5, 0x89, 0x92, 0xda, 0xb0, 0x4b, 0x23, 0xd2, 0xec, 0x5f, 0x6a, 0xb2, 0x15, 0x46, - 0xba, 0x98, 0x61, 0x89, 0x88, 0xed, 0xac, 0xd9, 0x2e, 0x2f, 0xb0, 0x98, 0xa8, 0x74, 0x80, 0x39, - 0xc4, 0x86, 0xe7, 0x38, 0xde, 0x13, 0x79, 0x06, 0x62, 0x8a, 0xad, 0xea, 0xb9, 0x91, 0xed, 0x70, - 0xf9, 0xf1, 0x01, 0x48, 0x07, 0xf8, 0x2a, 0xdb, 0x89, 0x68, 0xc0, 0x4b, 0x98, 0x9a, 0x21, 0xa8, - 0xc4, 0xe5, 0xea, 0x71, 0x5f, 0x40, 0x9e, 0xbd, 0xd8, 0x39, 0x67, 0x55, 0xe7, 0x1c, 0x74, 0xf8, - 0x7d, 0x39, 0xf7, 0x66, 0xde, 0x26, 0xa1, 0x7d, 0xdb, 0xeb, 0x85, 0xda, 0xfe, 0x38, 0x89, 0x4b, - 0x7a, 0xc8, 0x61, 0x0f, 0xe4, 0x38, 0xec, 0x2f, 0x11, 0x54, 0xd7, 0xbc, 0xce, 0x0d, 0x37, 0x0a, - 0xb6, 0x79, 0x65, 0xef, 0xb9, 0x11, 0x75, 0xa5, 0x57, 0x48, 0x92, 0x99, 0x3a, 0xb2, 0xbb, 0x74, - 0x3d, 0x22, 0x5d, 0x5f, 0xd4, 0x24, 0x3b, 0x32, 0x75, 0xb2, 0x98, 0xa9, 0xef, 0x90, 0x30, 0xe2, - 0xa7, 0xb7, 0x6a, 0xf0, 0x6f, 0x06, 0x34, 0x99, 0xb0, 0x1e, 0x05, 0xe2, 0xe8, 0x66, 0xc6, 0x54, - 0x47, 0x9a, 0x8a, 0xb1, 0x09, 0x52, 0x5f, 0x87, 0x97, 0x93, 0x52, 0xf6, 0x01, 0x0d, 0xba, 0xb6, - 0x4b, 0x8a, 0xe3, 0x6d, 0x99, 0x2e, 0xcc, 0xc3, 0xcc, 0x01, 0x62, 0xf5, 0xdf, 0x23, 0xdb, 0xb5, - 0xbc, 0x27, 0x05, 0x07, 0xa1, 0x0c, 0xdb, 0x3f, 0x66, 0xfb, 0x2d, 0x0a, 0xdf, 0xe4, 0x6c, 0xde, - 0x86, 0x7d, 0xec, 0x14, 0xf7, 0xa9, 0xf8, 0x41, 0x04, 0x0a, 0x7d, 0xd4, 0x95, 0x3c, 0xe5, 0x61, - 0x64, 0x17, 0xe2, 0x35, 0x38, 0x40, 0xc2, 0xd0, 0xee, 0xb8, 0xd4, 0x92, 0xbc, 0x2a, 0xa5, 0x79, - 0x0d, 0x2e, 0x8d, 0xaf, 0x7d, 0x7c, 0x86, 0xd8, 0x3b, 0x49, 0xea, 0xdf, 0x43, 0x70, 0x24, 0x97, - 0x49, 0xe2, 0xeb, 0x48, 0x09, 0xaf, 0x0d, 0xa8, 0x86, 0xe6, 0x26, 0xb5, 0x7a, 0x0e, 0x95, 0x7d, - 0x0d, 0x49, 0xb3, 0xdf, 0xac, 0x5e, 0xbc, 0x93, 0x22, 0xbc, 0x27, 0x34, 0x3e, 0x0e, 0xd0, 0x25, - 0x6e, 0x8f, 0x38, 0x1c, 0xc2, 0x24, 0x87, 0xa0, 0x8c, 0xe8, 0xf3, 0xd0, 0xc8, 0x73, 0x03, 0xd1, - 0x49, 0xf8, 0x33, 0x82, 0xfd, 0x32, 0x0c, 0x8a, 0x3d, 0x5c, 0x84, 0x03, 0x8a, 0x19, 0xee, 0xa5, - 0xdb, 0x39, 0x38, 0x3c, 0x26, 0xc4, 0x49, 0x5f, 0x98, 0xc8, 0xf6, 0x35, 0xfb, 0x99, 0xce, 0x64, - 0xe9, 0x3c, 0x84, 0x76, 0x54, 0x89, 0x7d, 0x17, 0xb4, 0xbb, 0xc4, 0x25, 0x1d, 0x6a, 0x25, 0xca, - 0x25, 0x8e, 0xf4, 0x6d, 0xf5, 0xb2, 0xbc, 0xeb, 0xab, 0x69, 0x52, 0xce, 0xd8, 0x1b, 0x1b, 0xf2, - 0xe2, 0x1d, 0x40, 0x75, 0xcd, 0x76, 0xb7, 0xd8, 0xfd, 0x8d, 0xe9, 0x15, 0xd9, 0x91, 0x23, 0x6d, - 0x18, 0x13, 0xf8, 0x20, 0x4c, 0xf4, 0x02, 0x47, 0xec, 0x33, 0xfb, 0xc4, 0x0b, 0x50, 0xb7, 0x68, - 0x68, 0x06, 0xb6, 0x2f, 0x76, 0x99, 0x37, 0xfa, 0x94, 0x21, 0x66, 0x6d, 0xdb, 0xf4, 0xdc, 0x55, - 0x87, 0x84, 0xa1, 0x4c, 0x0c, 0xc9, 0x80, 0xfe, 0x1a, 0xec, 0x63, 0x32, 0x53, 0x35, 0xcf, 0x67, - 0xd5, 0x3c, 0x92, 0x81, 0x2f, 0xe1, 0x49, 0xc4, 0xb7, 0xe0, 0x25, 0x96, 0x8f, 0xaf, 0xfa, 0xbe, - 0x60, 0x52, 0xb2, 0x18, 0x99, 0x18, 0xd8, 0xf4, 0xf6, 0xdf, 0x4e, 0x02, 0x56, 0x7d, 0x9e, 0x06, - 0x7d, 0xdb, 0xa4, 0xf8, 0x3d, 0x04, 0x93, 0x4c, 0x00, 0x3e, 0x36, 0xea, 0x88, 0x71, 0xdf, 0x6b, - 0xec, 0xdd, 0x85, 0x8e, 0x49, 0xd3, 0xe7, 0xdf, 0xfe, 0xd3, 0x3f, 0xde, 0xaf, 0xcc, 0xe1, 0xc3, - 0xfc, 0x81, 0xa1, 0x7f, 0x49, 0x6d, 0xf6, 0x87, 0xf8, 0x1d, 0x04, 0x58, 0x54, 0x21, 0x4a, 0x77, - 0x17, 0x9f, 0x1f, 0x05, 0x31, 0xa7, 0x0b, 0xdc, 0x38, 0xa6, 0x44, 0xfb, 0xa6, 0xe9, 0x05, 0x94, - 0xc5, 0x76, 0x3e, 0x81, 0x03, 0x58, 0xe2, 0x00, 0x4e, 0x61, 0x3d, 0x0f, 0x40, 0xeb, 0x29, 0xb3, - 0xdb, 0xb3, 0x16, 0x8d, 0xe5, 0x7e, 0x8c, 0x60, 0xea, 0x11, 0xaf, 0xb9, 0xc7, 0x18, 0x69, 0x7d, - 0xcf, 0x8c, 0xc4, 0xc5, 0x71, 0xb4, 0xfa, 0x49, 0x8e, 0xf4, 0x18, 0x3e, 0x2a, 0x91, 0x86, 0x51, - 0x40, 0x49, 0x37, 0x03, 0xf8, 0x22, 0xc2, 0x9f, 0x22, 0x98, 0x8e, 0xdb, 0x8d, 0xf8, 0xf4, 0x28, - 0x94, 0x99, 0x76, 0x64, 0x63, 0xef, 0x7a, 0x77, 0xfa, 0x39, 0x8e, 0xf1, 0xa4, 0x9e, 0xbb, 0x9d, - 0x2b, 0x99, 0xce, 0xde, 0x07, 0x08, 0x26, 0x6e, 0xd1, 0xb1, 0xfe, 0xb6, 0x87, 0xe0, 0x86, 0x0c, - 0x98, 0xb3, 0xd5, 0xf8, 0x13, 0x04, 0x2f, 0xdf, 0xa2, 0x51, 0x7e, 0xaa, 0xc3, 0x8b, 0xe3, 0xf3, - 0x8f, 0x70, 0xbb, 0xf3, 0x25, 0x66, 0x26, 0x31, 0xbe, 0xc5, 0x91, 0x9d, 0xc3, 0x67, 0x8b, 0x9c, - 0x30, 0xdc, 0x76, 0xcd, 0x27, 0x02, 0xc7, 0x6f, 0x11, 0x1c, 0x1c, 0x7c, 0x6b, 0xc1, 0xd9, 0xe4, - 0x98, 0xfb, 0x14, 0xd3, 0xb8, 0xb7, 0xdb, 0x58, 0x9a, 0x65, 0xaa, 0x5f, 0xe5, 0xc8, 0x5f, 0xc5, - 0xaf, 0x14, 0x21, 0x97, 0x4d, 0xca, 0xb0, 0xf5, 0x54, 0x7e, 0x3e, 0xe3, 0xcf, 0x82, 0x1c, 0xf6, - 0xef, 0x11, 0x1c, 0x96, 0x7c, 0x57, 0x37, 0x49, 0x10, 0x5d, 0xa7, 0xac, 0x82, 0x0d, 0x4b, 0xe9, - 0xb3, 0xcb, 0xdc, 0xa0, 0xca, 0xd3, 0x6f, 0x70, 0x5d, 0xbe, 0x84, 0x5f, 0xdf, 0xb1, 0x2e, 0x26, - 0x63, 0x63, 0x09, 0xd8, 0x6f, 0x23, 0x98, 0xbd, 0x45, 0xa3, 0xbb, 0x49, 0xcf, 0xf1, 0x74, 0xa9, - 0x37, 0x89, 0xc6, 0x7c, 0x53, 0x79, 0x8d, 0x94, 0x3f, 0x25, 0x2e, 0xb2, 0xcc, 0xc1, 0x9d, 0xc5, - 0xa7, 0x8b, 0xc0, 0xa5, 0x7d, 0xce, 0x8f, 0x11, 0x1c, 0x51, 0x41, 0xa4, 0x2f, 0x36, 0x5f, 0xd8, - 0xd9, 0x0b, 0x89, 0x78, 0x67, 0x19, 0x83, 0xae, 0xcd, 0xd1, 0x5d, 0xd0, 0xf3, 0x1d, 0xb8, 0x3b, - 0x84, 0x62, 0x05, 0x2d, 0x2d, 0x22, 0xfc, 0x2b, 0x04, 0xd3, 0x71, 0x53, 0x71, 0xb4, 0x8d, 0x32, - 0x6f, 0x0f, 0x7b, 0x19, 0x0d, 0xc4, 0x6e, 0x37, 0x2e, 0xe6, 0x1b, 0x54, 0x5d, 0x2f, 0x5d, 0xb5, - 0xc9, 0xad, 0x9c, 0x0d, 0x63, 0x3f, 0x43, 0x00, 0x69, 0x63, 0x14, 0x9f, 0x2b, 0xd6, 0x43, 0x69, - 0x9e, 0x36, 0xf6, 0xb6, 0x35, 0xaa, 0x37, 0xb9, 0x3e, 0x8b, 0x8d, 0x85, 0xc2, 0x18, 0xe2, 0x53, - 0x73, 0x25, 0x6e, 0xa2, 0xfe, 0x18, 0xc1, 0x14, 0xef, 0x7b, 0xe1, 0x53, 0xa3, 0x30, 0xab, 0x6d, - 0xb1, 0xbd, 0x34, 0xfd, 0x19, 0x0e, 0x75, 0xa1, 0x5d, 0x14, 0x88, 0x57, 0xd0, 0x12, 0xee, 0xc3, - 0x74, 0xdc, 0x83, 0x1a, 0xed, 0x1e, 0x99, 0x1e, 0x55, 0x63, 0xa1, 0xa0, 0x30, 0x88, 0x1d, 0x55, - 0xe4, 0x80, 0xa5, 0x71, 0x39, 0x60, 0x92, 0x85, 0x69, 0x7c, 0xb2, 0x28, 0x88, 0xff, 0x0f, 0x0c, - 0x73, 0x9e, 0xa3, 0x3b, 0xad, 0x2f, 0x8c, 0xcb, 0x03, 0xcc, 0x3a, 0x3f, 0x44, 0x70, 0x70, 0xb0, - 0x84, 0xc6, 0x47, 0x07, 0x62, 0xa6, 0x7a, 0x6f, 0x68, 0x64, 0xad, 0x38, 0xaa, 0xfc, 0xd6, 0xbf, - 0xcc, 0x51, 0xac, 0xe0, 0x2b, 0x63, 0x4f, 0xc6, 0x3d, 0x19, 0x75, 0x18, 0xa3, 0xe5, 0xf4, 0x0d, - 0xe6, 0xe7, 0x08, 0x66, 0x25, 0xdf, 0x07, 0x01, 0xa5, 0xc5, 0xb0, 0xf6, 0xee, 0x20, 0x30, 0x59, - 0xfa, 0x6b, 0x1c, 0xfe, 0x17, 0xf1, 0xe5, 0x92, 0xf0, 0x25, 0xec, 0xe5, 0x88, 0x21, 0xfd, 0x35, - 0x82, 0x43, 0x8f, 0x62, 0xbf, 0xff, 0x8c, 0xf0, 0xaf, 0x72, 0xfc, 0xaf, 0xe3, 0x57, 0x0b, 0xea, - 0xbc, 0x71, 0x6a, 0x5c, 0x44, 0xf8, 0xa7, 0x08, 0xaa, 0xf2, 0x45, 0x01, 0x9f, 0x1d, 0x79, 0x30, - 0xb2, 0x6f, 0x0e, 0x7b, 0xe9, 0xcc, 0xa2, 0xa8, 0xd1, 0x4f, 0x15, 0xa6, 0x53, 0x21, 0x9f, 0x39, - 0xf4, 0x07, 0x08, 0x70, 0x72, 0xff, 0x4d, 0x6e, 0xc4, 0xf8, 0x4c, 0x46, 0xd4, 0xc8, 0x86, 0x49, - 0xe3, 0xec, 0xd8, 0x79, 0xd9, 0x54, 0xba, 0x54, 0x98, 0x4a, 0xbd, 0x44, 0xfe, 0xbb, 0x08, 0xea, - 0xb7, 0x68, 0x72, 0x07, 0x29, 0xb0, 0x65, 0xf6, 0xa9, 0xa4, 0xb1, 0x38, 0x7e, 0xa2, 0x40, 0x74, - 0x81, 0x23, 0x3a, 0x83, 0x8b, 0x4d, 0x25, 0x01, 0x7c, 0x84, 0x60, 0xdf, 0x7d, 0xd5, 0x45, 0xf1, - 0x85, 0x71, 0x92, 0x32, 0x91, 0xbc, 0x3c, 0xae, 0xcf, 0x73, 0x5c, 0xcb, 0x7a, 0x29, 0x5c, 0x2b, - 0xe2, 0x3d, 0xe2, 0x47, 0x28, 0xbe, 0xaa, 0x0e, 0x74, 0x93, 0xff, 0x5b, 0xbb, 0x15, 0x34, 0xa5, - 0xf5, 0xcb, 0x1c, 0x5f, 0x13, 0x5f, 0x28, 0x83, 0xaf, 0x25, 0x5a, 0xcc, 0xf8, 0x43, 0x04, 0x87, - 0x78, 0x3f, 0x5f, 0x65, 0x3c, 0x90, 0x62, 0x46, 0x75, 0xff, 0x4b, 0xa4, 0x18, 0x11, 0x7f, 0xf4, - 0x1d, 0x81, 0x5a, 0x91, 0xbd, 0xfa, 0x1f, 0x20, 0xd8, 0x2f, 0x93, 0x9a, 0xd8, 0xdd, 0xe5, 0x71, - 0x86, 0xdb, 0x69, 0x12, 0x14, 0xee, 0xb6, 0x54, 0xce, 0xdd, 0x3e, 0x45, 0x30, 0x23, 0x7a, 0xe9, - 0x05, 0xa5, 0x82, 0xd2, 0x6c, 0x6f, 0x0c, 0x74, 0x32, 0x44, 0x93, 0x56, 0xff, 0x26, 0x17, 0xfb, - 0x10, 0xb7, 0x8a, 0xc4, 0xfa, 0x9e, 0x15, 0xb6, 0x9e, 0x8a, 0x0e, 0xe9, 0xb3, 0x96, 0xe3, 0x75, - 0xc2, 0x37, 0x75, 0x5c, 0x98, 0x10, 0xd9, 0x9c, 0x8b, 0x08, 0x47, 0x50, 0x63, 0xce, 0xc1, 0xdb, - 0x23, 0x78, 0x61, 0xa0, 0x99, 0x32, 0xd4, 0x39, 0x69, 0x34, 0x86, 0xda, 0x2d, 0x69, 0x06, 0x14, - 0xd7, 0x58, 0x7c, 0xa2, 0x50, 0x2c, 0x17, 0xf4, 0x0e, 0x82, 0x43, 0xaa, 0xb7, 0xc7, 0xe2, 0x4b, - 0xfb, 0x7a, 0x11, 0x0a, 0x51, 0x54, 0xe3, 0xa5, 0x52, 0x8e, 0xc4, 0xe1, 0x5c, 0xbb, 0xf9, 0x9b, - 0xe7, 0xc7, 0xd1, 0x1f, 0x9e, 0x1f, 0x47, 0x7f, 0x7f, 0x7e, 0x1c, 0xbd, 0x79, 0xa5, 0xdc, 0x5f, - 0x2c, 0x4d, 0xc7, 0xa6, 0x6e, 0xa4, 0xb2, 0xff, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x47, 0x97, - 0xe3, 0x09, 0x48, 0x2a, 0x00, 0x00, + // 2673 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x8f, 0x1c, 0x47, + 0x15, 0xa7, 0x66, 0xbf, 0x66, 0xde, 0xec, 0xfa, 0xa3, 0x12, 0x2f, 0x9d, 0xf6, 0xc6, 0x6c, 0xda, + 0x76, 0xbc, 0x59, 0x7b, 0x67, 0xec, 0xc1, 0x20, 0x67, 0x93, 0x08, 0xec, 0xf5, 0x27, 0xac, 0x1d, + 0xd3, 0x6b, 0x63, 0x14, 0x0e, 0x50, 0xe9, 0xae, 0x9d, 0x6d, 0xb6, 0xa7, 0xbb, 0xdd, 0xdd, 0x33, + 0xd6, 0xca, 0xf8, 0x12, 0x64, 0x09, 0xa1, 0x08, 0x04, 0xe4, 0x80, 0x10, 0x02, 0x14, 0x14, 0x09, + 0x21, 0x10, 0x17, 0x14, 0x21, 0x21, 0x24, 0xb8, 0x20, 0x38, 0x20, 0x21, 0x38, 0x72, 0x41, 0x16, + 0xe2, 0x08, 0x97, 0xfc, 0x01, 0xa8, 0xaa, 0xab, 0xba, 0xab, 0xe7, 0xa3, 0x67, 0x96, 0x19, 0x14, + 0xdf, 0xfa, 0xd5, 0x54, 0xbd, 0xf7, 0xab, 0x57, 0xbf, 0x7a, 0xaf, 0xea, 0xd5, 0xc0, 0x89, 0x88, + 0x86, 0x1d, 0x1a, 0xd6, 0x49, 0x10, 0xb8, 0x8e, 0x45, 0x62, 0xc7, 0xf7, 0xd4, 0xef, 0x5a, 0x10, + 0xfa, 0xb1, 0x8f, 0xab, 0x4a, 0x93, 0xbe, 0xd4, 0xf4, 0xfd, 0xa6, 0x4b, 0xeb, 0x24, 0x70, 0xea, + 0xc4, 0xf3, 0xfc, 0x98, 0x37, 0x47, 0x49, 0x57, 0xdd, 0xd8, 0xbd, 0x10, 0xd5, 0x1c, 0x9f, 0xff, + 0x6a, 0xf9, 0x21, 0xad, 0x77, 0xce, 0xd5, 0x9b, 0xd4, 0xa3, 0x21, 0x89, 0xa9, 0x2d, 0xfa, 0x9c, + 0xcf, 0xfa, 0xb4, 0x88, 0xb5, 0xe3, 0x78, 0x34, 0xdc, 0xab, 0x07, 0xbb, 0x4d, 0xd6, 0x10, 0xd5, + 0x5b, 0x34, 0x26, 0xfd, 0x46, 0x6d, 0x36, 0x9d, 0x78, 0xa7, 0xfd, 0x66, 0xcd, 0xf2, 0x5b, 0x75, + 0x12, 0x36, 0xfd, 0x20, 0xf4, 0xbf, 0xc2, 0x3f, 0xd6, 0x2c, 0xbb, 0xde, 0x69, 0x64, 0x0a, 0xd4, + 0xb9, 0x74, 0xce, 0x11, 0x37, 0xd8, 0x21, 0xbd, 0xda, 0xae, 0x0c, 0xd1, 0x16, 0xd2, 0xc0, 0x17, + 0xbe, 0xe1, 0x9f, 0x4e, 0xec, 0x87, 0x7b, 0xca, 0x67, 0xa2, 0xc6, 0xf8, 0x00, 0xc1, 0xa1, 0x8b, + 0x99, 0xbd, 0xcf, 0xb5, 0x69, 0xb8, 0x87, 0x31, 0x4c, 0x7b, 0xa4, 0x45, 0x35, 0xb4, 0x8c, 0x56, + 0x2a, 0x26, 0xff, 0xc6, 0x1a, 0xcc, 0x85, 0x74, 0x3b, 0xa4, 0xd1, 0x8e, 0x56, 0xe2, 0xcd, 0x52, + 0xc4, 0x3a, 0x94, 0x99, 0x71, 0x6a, 0xc5, 0x91, 0x36, 0xb5, 0x3c, 0xb5, 0x52, 0x31, 0x53, 0x19, + 0xaf, 0xc0, 0xc1, 0x90, 0x46, 0x7e, 0x3b, 0xb4, 0xe8, 0xe7, 0x69, 0x18, 0x39, 0xbe, 0xa7, 0x4d, + 0xf3, 0xd1, 0xdd, 0xcd, 0x4c, 0x4b, 0x44, 0x5d, 0x6a, 0xc5, 0x7e, 0xa8, 0xcd, 0xf0, 0x2e, 0xa9, + 0xcc, 0xf0, 0x30, 0xe0, 0xda, 0x6c, 0x82, 0x87, 0x7d, 0x63, 0x03, 0xe6, 0x49, 0x10, 0xdc, 0x22, + 0x2d, 0x1a, 0x05, 0xc4, 0xa2, 0xda, 0x1c, 0xff, 0x2d, 0xd7, 0xc6, 0x30, 0x0b, 0x24, 0x5a, 0x99, + 0x03, 0x93, 0xa2, 0xb1, 0x01, 0x95, 0x5b, 0xbe, 0x4d, 0x07, 0x4f, 0xb7, 0x5b, 0x7d, 0xa9, 0x57, + 0xbd, 0xf1, 0x18, 0xc1, 0x11, 0x93, 0x76, 0x1c, 0x86, 0xff, 0x26, 0x8d, 0x89, 0x4d, 0x62, 0xd2, + 0xad, 0xb1, 0x94, 0x6a, 0xd4, 0xa1, 0x1c, 0x8a, 0xce, 0x5a, 0x89, 0xb7, 0xa7, 0x72, 0x8f, 0xb5, + 0xa9, 0xe2, 0xc9, 0x24, 0x2e, 0x4c, 0x27, 0xf3, 0x2f, 0x04, 0xc7, 0x94, 0x35, 0x34, 0x85, 0x67, + 0xaf, 0x74, 0xa8, 0x17, 0x47, 0x83, 0x01, 0x9d, 0x81, 0xc3, 0x72, 0x11, 0xba, 0xe7, 0xd9, 0xfb, + 0x03, 0x83, 0xa8, 0x36, 0x4a, 0x88, 0x6a, 0x1b, 0x5e, 0x86, 0xaa, 0x94, 0xef, 0xde, 0xb8, 0x2c, + 0x60, 0xaa, 0x4d, 0x3d, 0x13, 0x9d, 0x29, 0x9e, 0xe8, 0x6c, 0x7e, 0xa2, 0x5f, 0x47, 0xa0, 0x29, + 0x13, 0xbd, 0x49, 0x3c, 0x67, 0x9b, 0x46, 0xf1, 0xa8, 0x3e, 0x47, 0x13, 0xf4, 0xf9, 0x0b, 0x50, + 0xb9, 0xea, 0xb8, 0x74, 0x63, 0xa7, 0xed, 0xed, 0xe2, 0x67, 0x61, 0xc6, 0x62, 0x1f, 0xdc, 0xf6, + 0xbc, 0x99, 0x08, 0xc6, 0xb7, 0x11, 0xbc, 0x30, 0x08, 0xed, 0x3d, 0x27, 0xde, 0x61, 0xe3, 0xa3, + 0x41, 0xb0, 0xad, 0x1d, 0x6a, 0xed, 0x46, 0xed, 0x96, 0xa4, 0x8a, 0x94, 0xc7, 0x84, 0xfd, 0x33, + 0x04, 0x2b, 0x43, 0x31, 0xdd, 0x0b, 0x49, 0x10, 0xd0, 0x10, 0x5f, 0x85, 0x99, 0xfb, 0xec, 0x07, + 0xbe, 0x31, 0xaa, 0x8d, 0x5a, 0x4d, 0x0d, 0xac, 0x43, 0xb5, 0x5c, 0xff, 0x88, 0x99, 0x0c, 0xc7, + 0x35, 0xe9, 0x9e, 0x12, 0xd7, 0xb3, 0x98, 0xd3, 0x93, 0x7a, 0x91, 0xf5, 0xe7, 0xdd, 0x2e, 0xcd, + 0xc2, 0x74, 0x40, 0xc2, 0xd8, 0x38, 0x02, 0xcf, 0xe4, 0x69, 0x1d, 0xf8, 0x5e, 0x44, 0x8d, 0xdf, + 0xe4, 0x59, 0xb0, 0x11, 0x52, 0x12, 0x53, 0x93, 0xde, 0x6f, 0xd3, 0x28, 0xc6, 0xbb, 0xa0, 0xc6, + 0x7a, 0xee, 0xd5, 0x6a, 0xe3, 0x46, 0x2d, 0x0b, 0x96, 0x35, 0x19, 0x2c, 0xf9, 0xc7, 0x97, 0x2c, + 0xbb, 0xd6, 0x69, 0xd4, 0x82, 0xdd, 0x66, 0x8d, 0x85, 0xde, 0x1c, 0x32, 0x19, 0x7a, 0xd5, 0xa9, + 0x9a, 0xaa, 0x76, 0xbc, 0x08, 0xb3, 0xed, 0x20, 0xa2, 0x61, 0xcc, 0x67, 0x56, 0x36, 0x85, 0xc4, + 0xd6, 0xaf, 0x43, 0x5c, 0xc7, 0x26, 0x71, 0xb2, 0x3e, 0x65, 0x33, 0x95, 0x8d, 0xdf, 0xe6, 0xd1, + 0xdf, 0x0d, 0xec, 0x0f, 0x0b, 0xbd, 0x8a, 0xb2, 0x94, 0x47, 0xa9, 0x32, 0x68, 0x2a, 0xcf, 0xa0, + 0x5f, 0xe5, 0xf1, 0x5f, 0xa6, 0x2e, 0xcd, 0xf0, 0xf7, 0x23, 0xb3, 0x06, 0x73, 0x16, 0x89, 0x2c, + 0x62, 0x4b, 0x2b, 0x52, 0x64, 0x01, 0x28, 0x08, 0xfd, 0x80, 0x34, 0xb9, 0xa6, 0xdb, 0xbe, 0xeb, + 0x58, 0x7b, 0xc2, 0x5c, 0xef, 0x0f, 0x3d, 0xc4, 0x9f, 0x2e, 0x26, 0xfe, 0x4c, 0x1e, 0xf6, 0x71, + 0xa8, 0x6e, 0xed, 0x79, 0xd6, 0xeb, 0x01, 0xcf, 0xf5, 0x6c, 0xc7, 0x3a, 0x31, 0x6d, 0x45, 0x1a, + 0xe2, 0x79, 0x21, 0x11, 0x8c, 0xf7, 0x67, 0x60, 0x51, 0x99, 0x1b, 0x1b, 0x50, 0x34, 0xb3, 0xa2, + 0xe8, 0xb2, 0x08, 0xb3, 0x76, 0xb8, 0x67, 0xb6, 0x3d, 0x41, 0x00, 0x21, 0x31, 0xc3, 0x41, 0xd8, + 0xf6, 0x12, 0xf8, 0x65, 0x33, 0x11, 0xf0, 0x36, 0x94, 0xa3, 0x98, 0x65, 0xf7, 0xe6, 0x1e, 0x07, + 0x5e, 0x6d, 0x7c, 0x66, 0xbc, 0x45, 0x67, 0xd0, 0xb7, 0x84, 0x46, 0x33, 0xd5, 0x8d, 0xef, 0x43, + 0x45, 0x46, 0xe3, 0x48, 0x9b, 0x5b, 0x9e, 0x5a, 0xa9, 0x36, 0xb6, 0xc6, 0x37, 0xf4, 0x7a, 0xc0, + 0x4e, 0x26, 0x4a, 0xe6, 0x31, 0x33, 0x2b, 0x78, 0x09, 0x2a, 0x2d, 0x11, 0x1f, 0x22, 0x91, 0x85, + 0xb3, 0x06, 0xfc, 0x05, 0x98, 0x71, 0xbc, 0x6d, 0x3f, 0xd2, 0x2a, 0x1c, 0xcc, 0xa5, 0xf1, 0xc0, + 0xdc, 0xf0, 0xb6, 0x7d, 0x33, 0x51, 0x88, 0xef, 0xc3, 0x42, 0x48, 0xe3, 0x70, 0x4f, 0x7a, 0x41, + 0x03, 0xee, 0xd7, 0xcf, 0x8e, 0x67, 0xc1, 0x54, 0x55, 0x9a, 0x79, 0x0b, 0x78, 0x1d, 0xaa, 0x51, + 0xc6, 0x31, 0xad, 0xca, 0x0d, 0x6a, 0x39, 0x45, 0x0a, 0x07, 0x4d, 0xb5, 0x73, 0x0f, 0xbb, 0xe7, + 0x8b, 0xd9, 0xbd, 0x90, 0x67, 0xf7, 0x7f, 0x10, 0x2c, 0xf5, 0x04, 0x95, 0xad, 0x80, 0x16, 0xd2, + 0x97, 0xc0, 0x74, 0x14, 0x50, 0x8b, 0x67, 0x98, 0x6a, 0xe3, 0xe6, 0xc4, 0xa2, 0x0c, 0xb7, 0xcb, + 0x55, 0x17, 0x05, 0xc2, 0x31, 0xf7, 0xf3, 0x8f, 0x10, 0x7c, 0x54, 0xb1, 0x79, 0x9b, 0xc4, 0xd6, + 0x4e, 0xd1, 0x64, 0xd9, 0xbe, 0x63, 0x7d, 0x44, 0x3e, 0x4d, 0x04, 0x46, 0x4e, 0xfe, 0x71, 0x67, + 0x2f, 0x60, 0x00, 0xd9, 0x2f, 0x59, 0xc3, 0x98, 0x87, 0x95, 0x9f, 0x23, 0xd0, 0xd5, 0xd8, 0xeb, + 0xbb, 0xee, 0x9b, 0xc4, 0xda, 0x2d, 0x02, 0x79, 0x00, 0x4a, 0x8e, 0xcd, 0x11, 0x4e, 0x99, 0x25, + 0xc7, 0xde, 0x67, 0x10, 0xe9, 0x86, 0x3b, 0x5b, 0x0c, 0x77, 0x2e, 0x0f, 0xf7, 0x83, 0x2e, 0xb8, + 0x72, 0x2b, 0x17, 0xc0, 0x5d, 0x82, 0x8a, 0xd7, 0x75, 0x70, 0xcc, 0x1a, 0xfa, 0x1c, 0x18, 0x4b, + 0x3d, 0x07, 0x46, 0x0d, 0xe6, 0x3a, 0xe9, 0xb5, 0x80, 0xfd, 0x2c, 0x45, 0x36, 0xc5, 0x66, 0xe8, + 0xb7, 0x03, 0xe1, 0xf4, 0x44, 0x60, 0x28, 0x76, 0x1d, 0xcf, 0xd6, 0x66, 0x13, 0x14, 0xec, 0x7b, + 0xff, 0x17, 0x81, 0xdc, 0xb4, 0x7f, 0x51, 0x82, 0x8f, 0xf5, 0x99, 0xf6, 0x50, 0x3e, 0x3d, 0x1d, + 0x73, 0x4f, 0x59, 0x3d, 0x37, 0x90, 0xd5, 0xe5, 0x61, 0xac, 0xae, 0x14, 0xfb, 0x0b, 0xf2, 0xfe, + 0xfa, 0x69, 0x09, 0x96, 0xfb, 0xf8, 0x6b, 0xf8, 0x31, 0xe0, 0xa9, 0x71, 0xd8, 0xb6, 0x1f, 0x0a, + 0x96, 0x94, 0xcd, 0x44, 0x60, 0xfb, 0xcc, 0x0f, 0x83, 0x1d, 0xe2, 0x71, 0x76, 0x94, 0x4d, 0x21, + 0x8d, 0xe9, 0xaa, 0x6f, 0x94, 0x40, 0x93, 0xfe, 0xb9, 0x68, 0x71, 0x6f, 0xb5, 0xbd, 0xa7, 0xdf, + 0x45, 0x8b, 0x30, 0x4b, 0x38, 0x5a, 0x41, 0x2a, 0x21, 0xf5, 0x38, 0xa3, 0x5c, 0xec, 0x8c, 0x4a, + 0xde, 0x19, 0x8f, 0x11, 0x1c, 0xcd, 0x3b, 0x23, 0xda, 0x74, 0xa2, 0x58, 0x1e, 0xea, 0xf1, 0x36, + 0xcc, 0x25, 0x76, 0x92, 0x23, 0x59, 0xb5, 0xb1, 0x39, 0x6e, 0xa2, 0xce, 0x39, 0x5e, 0x2a, 0x37, + 0x5e, 0x86, 0xa3, 0x7d, 0xa3, 0x9c, 0x80, 0xa1, 0x43, 0x59, 0x1e, 0x4e, 0xc4, 0xd2, 0xa4, 0xb2, + 0xf1, 0x78, 0x3a, 0x9f, 0x72, 0x7c, 0x7b, 0xd3, 0x6f, 0x16, 0xdc, 0xaf, 0x8b, 0x97, 0x93, 0xb9, + 0xca, 0xb7, 0x95, 0xab, 0xb4, 0x14, 0xd9, 0x38, 0xcb, 0xf7, 0x62, 0xe2, 0x78, 0x34, 0x14, 0x59, + 0x31, 0x6b, 0x60, 0xcb, 0x10, 0x39, 0x9e, 0x45, 0xb7, 0xa8, 0xe5, 0x7b, 0x76, 0xc4, 0xd7, 0x73, + 0xca, 0xcc, 0xb5, 0xe1, 0xeb, 0x50, 0xe1, 0xf2, 0x1d, 0xa7, 0x95, 0xa4, 0x81, 0x6a, 0x63, 0xb5, + 0x96, 0xd4, 0xac, 0x6a, 0x6a, 0xcd, 0x2a, 0xf3, 0x61, 0x8b, 0xc6, 0xa4, 0xd6, 0x39, 0x57, 0x63, + 0x23, 0xcc, 0x6c, 0x30, 0xc3, 0x12, 0x13, 0xc7, 0xdd, 0x74, 0x3c, 0x7e, 0x60, 0x64, 0xa6, 0xb2, + 0x06, 0x46, 0x95, 0x6d, 0xdf, 0x75, 0xfd, 0x07, 0x72, 0xdf, 0x24, 0x12, 0x1b, 0xd5, 0xf6, 0x62, + 0xc7, 0xe5, 0xf6, 0x13, 0x22, 0x64, 0x0d, 0x7c, 0x94, 0xe3, 0xc6, 0x34, 0x14, 0x1b, 0x46, 0x48, + 0x29, 0x19, 0xab, 0x49, 0x19, 0x46, 0xee, 0xd7, 0x84, 0xb6, 0xf3, 0x2a, 0x6d, 0xbb, 0xb7, 0xc2, + 0x42, 0x9f, 0x5a, 0x04, 0xaf, 0x4a, 0xd1, 0x8e, 0xe3, 0xb7, 0x23, 0xed, 0x40, 0x72, 0xf4, 0x90, + 0x72, 0x0f, 0x95, 0x0f, 0x16, 0x53, 0xf9, 0x50, 0x9e, 0xca, 0xbf, 0x43, 0x50, 0xde, 0xf4, 0x9b, + 0x57, 0xbc, 0x38, 0xdc, 0xe3, 0xb7, 0x1b, 0xdf, 0x8b, 0xa9, 0x27, 0xf9, 0x22, 0x45, 0xb6, 0x08, + 0xb1, 0xd3, 0xa2, 0x5b, 0x31, 0x69, 0x05, 0xe2, 0x8c, 0xb5, 0xaf, 0x45, 0x48, 0x07, 0x33, 0xc7, + 0xb8, 0x24, 0x8a, 0xf9, 0x8e, 0x2f, 0x9b, 0xfc, 0x9b, 0x4d, 0x21, 0xed, 0xb0, 0x15, 0x87, 0x62, + 0xbb, 0xe7, 0xda, 0x54, 0x8a, 0xcd, 0x24, 0xd8, 0x84, 0x68, 0xb4, 0xe0, 0xb9, 0xf4, 0xd0, 0x7e, + 0x87, 0x86, 0x2d, 0xc7, 0x23, 0xc5, 0xd1, 0x7b, 0x84, 0x72, 0x58, 0xc1, 0x9d, 0xd1, 0xcf, 0x6d, + 0x3a, 0x76, 0x06, 0xbe, 0xe7, 0x78, 0xb6, 0xff, 0xa0, 0x60, 0xf3, 0x8c, 0x67, 0xf0, 0xaf, 0xf9, + 0x8a, 0x98, 0x62, 0x31, 0xdd, 0xe9, 0xd7, 0x61, 0x81, 0xc5, 0x84, 0x0e, 0x15, 0x3f, 0x88, 0xb0, + 0x63, 0x0c, 0x2a, 0x72, 0x64, 0x3a, 0xcc, 0xfc, 0x40, 0xbc, 0x09, 0x07, 0x49, 0x14, 0x39, 0x4d, + 0x8f, 0xda, 0x52, 0x57, 0x69, 0x64, 0x5d, 0xdd, 0x43, 0x93, 0xeb, 0x32, 0xef, 0x21, 0xd6, 0x5b, + 0x8a, 0xc6, 0xd7, 0x10, 0x1c, 0xe9, 0xab, 0x24, 0xdd, 0x39, 0x48, 0x09, 0xe3, 0x3a, 0x94, 0x23, + 0x6b, 0x87, 0xda, 0x6d, 0x97, 0xca, 0x1a, 0x92, 0x94, 0xd9, 0x6f, 0x76, 0x3b, 0x59, 0x7d, 0x91, + 0x46, 0x52, 0x19, 0x1f, 0x03, 0x68, 0x11, 0xaf, 0x4d, 0x5c, 0x0e, 0x61, 0x9a, 0x43, 0x50, 0x5a, + 0x8c, 0x25, 0xd0, 0xfb, 0x51, 0x47, 0xd4, 0x66, 0xfe, 0x8d, 0xe0, 0x80, 0x0c, 0xaa, 0x62, 0x75, + 0x57, 0xe0, 0xa0, 0xe2, 0x86, 0x5b, 0xd9, 0x42, 0x77, 0x37, 0x0f, 0x09, 0x98, 0x92, 0x25, 0x53, + 0xf9, 0xa2, 0x74, 0x27, 0x57, 0x56, 0x1e, 0x39, 0xdf, 0xa1, 0x09, 0x9d, 0x1f, 0xbf, 0x0a, 0xda, + 0x4d, 0xe2, 0x91, 0x26, 0xb5, 0xd3, 0x69, 0xa7, 0x14, 0xfb, 0xb2, 0x5a, 0x64, 0x18, 0xfb, 0x4a, + 0x9f, 0x1e, 0xb5, 0x9c, 0xed, 0x6d, 0x59, 0xb0, 0x08, 0xa1, 0xbc, 0xe9, 0x78, 0xbb, 0xec, 0xde, + 0xcb, 0x66, 0x1c, 0x3b, 0xb1, 0x2b, 0xbd, 0x9b, 0x08, 0xf8, 0x10, 0x4c, 0xb5, 0x43, 0x57, 0x30, + 0x80, 0x7d, 0xe2, 0x65, 0xa8, 0xda, 0x34, 0xb2, 0x42, 0x27, 0x10, 0xeb, 0xcf, 0x8b, 0xb4, 0x4a, + 0x13, 0x5b, 0x07, 0xc7, 0xf2, 0xbd, 0x0d, 0x97, 0x44, 0x91, 0x4c, 0x40, 0x69, 0x83, 0xf1, 0x2a, + 0x2c, 0x30, 0x9b, 0xd9, 0x34, 0x4f, 0xe7, 0xa7, 0x79, 0x24, 0x07, 0x5f, 0xc2, 0x93, 0x88, 0x09, + 0x3c, 0xc3, 0xf2, 0xfe, 0xc5, 0x20, 0x10, 0x4a, 0x46, 0x3c, 0x0e, 0x4d, 0xf5, 0xcb, 0x9f, 0x7d, + 0x6b, 0x9c, 0x8d, 0xbf, 0x1f, 0x07, 0xac, 0xee, 0x13, 0x1a, 0x76, 0x1c, 0x8b, 0xe2, 0xef, 0x20, + 0x98, 0x66, 0xa6, 0xf1, 0xf3, 0x83, 0xb6, 0x25, 0xe7, 0xab, 0x3e, 0xb9, 0x8b, 0x30, 0xb3, 0x66, + 0x2c, 0xbd, 0xf5, 0xb7, 0x7f, 0x7e, 0xb7, 0xb4, 0x88, 0x9f, 0xe5, 0x2f, 0x4a, 0x9d, 0x73, 0xea, + 0xeb, 0x4e, 0x84, 0xdf, 0x46, 0x80, 0xc5, 0x39, 0x48, 0xa9, 0xd9, 0xe3, 0xd3, 0x83, 0x20, 0xf6, + 0xa9, 0xed, 0xeb, 0xcf, 0x2b, 0x59, 0xa5, 0x66, 0xf9, 0x21, 0x65, 0x39, 0x84, 0x77, 0xe0, 0x00, + 0x56, 0x39, 0x80, 0x13, 0xd8, 0xe8, 0x07, 0xa0, 0xfe, 0x90, 0x79, 0xf4, 0x51, 0x9d, 0x26, 0x76, + 0xdf, 0x45, 0x30, 0x73, 0x8f, 0xdf, 0x21, 0x86, 0x38, 0x69, 0x6b, 0x62, 0x4e, 0xe2, 0xe6, 0x38, + 0x5a, 0xe3, 0x38, 0x47, 0xfa, 0x3c, 0x3e, 0x2a, 0x91, 0x46, 0x71, 0x48, 0x49, 0x2b, 0x07, 0xf8, + 0x2c, 0xc2, 0xef, 0x21, 0x98, 0x4d, 0x8a, 0xbe, 0xf8, 0xe4, 0x20, 0x94, 0xb9, 0xa2, 0xb0, 0x3e, + 0xb9, 0x0a, 0xaa, 0xf1, 0x12, 0xc7, 0x78, 0xdc, 0xe8, 0xbb, 0x9c, 0xeb, 0xb9, 0xfa, 0xea, 0x3b, + 0x08, 0xa6, 0xae, 0xd1, 0xa1, 0x7c, 0x9b, 0x20, 0xb8, 0x1e, 0x07, 0xf6, 0x59, 0x6a, 0xfc, 0x13, + 0x04, 0xcf, 0x5d, 0xa3, 0x71, 0xff, 0xf4, 0x88, 0x57, 0x86, 0xe7, 0x2c, 0x41, 0xbb, 0xd3, 0x23, + 0xf4, 0x4c, 0xf3, 0x42, 0x9d, 0x23, 0x7b, 0x09, 0x9f, 0x2a, 0x22, 0x61, 0xb4, 0xe7, 0x59, 0x0f, + 0x04, 0x8e, 0x3f, 0x21, 0x38, 0xd4, 0xfd, 0xb6, 0x86, 0xf3, 0x09, 0xb5, 0xef, 0xd3, 0x9b, 0x7e, + 0x6b, 0xdc, 0x28, 0x9b, 0x57, 0x6a, 0x5c, 0xe4, 0xc8, 0x5f, 0xc1, 0x2f, 0x17, 0x21, 0x97, 0x65, + 0xdf, 0xa8, 0xfe, 0x50, 0x7e, 0x3e, 0xe2, 0xef, 0xc0, 0x1c, 0xf6, 0x9f, 0x11, 0x3c, 0x2b, 0xf5, + 0x6e, 0xec, 0x90, 0x30, 0xbe, 0x4c, 0xd9, 0x19, 0x3a, 0x1a, 0x69, 0x3e, 0x63, 0x66, 0x0d, 0xd5, + 0x9e, 0x71, 0x85, 0xcf, 0xe5, 0x53, 0xf8, 0xb5, 0x7d, 0xcf, 0xc5, 0x62, 0x6a, 0x6c, 0x01, 0xfb, + 0x2d, 0x04, 0xf3, 0xd7, 0x68, 0x7c, 0x33, 0xad, 0xe2, 0x9e, 0x1c, 0xe9, 0x65, 0x48, 0x5f, 0xaa, + 0x29, 0xcf, 0xcf, 0xf2, 0xa7, 0x94, 0x22, 0x6b, 0x1c, 0xdc, 0x29, 0x7c, 0xb2, 0x08, 0x5c, 0x56, + 0x39, 0x7e, 0x17, 0xc1, 0x11, 0x15, 0x44, 0xf6, 0xa2, 0xf6, 0x89, 0xfd, 0xbd, 0x53, 0x89, 0xd7, + 0xae, 0x21, 0xe8, 0x1a, 0x1c, 0xdd, 0x19, 0xa3, 0x3f, 0x81, 0x5b, 0x3d, 0x28, 0xd6, 0xd1, 0xea, + 0x0a, 0xc2, 0xbf, 0x47, 0x30, 0x9b, 0x14, 0x63, 0x07, 0xfb, 0x28, 0xf7, 0x02, 0x34, 0xc9, 0x68, + 0x20, 0x56, 0x5b, 0x3f, 0xdb, 0xdf, 0xa1, 0xea, 0x78, 0x49, 0xd5, 0x1a, 0xf7, 0x72, 0x3e, 0x8c, + 0xbd, 0x8f, 0x00, 0xb2, 0x82, 0x32, 0x7e, 0xa9, 0x78, 0x1e, 0x4a, 0xd1, 0x59, 0x9f, 0x6c, 0x49, + 0xd9, 0xa8, 0xf1, 0xf9, 0xac, 0xe8, 0xcb, 0x85, 0x31, 0x24, 0xa0, 0xd6, 0x7a, 0x52, 0x7c, 0xfe, + 0x31, 0x82, 0x19, 0x5e, 0xc7, 0xc3, 0x27, 0x06, 0x61, 0x56, 0xcb, 0x7c, 0x93, 0x74, 0xfd, 0x8b, + 0x1c, 0xea, 0x72, 0xa3, 0x28, 0x10, 0xaf, 0xa3, 0x55, 0xdc, 0x81, 0xd9, 0xa4, 0x72, 0x36, 0x98, + 0x1e, 0xb9, 0xca, 0x9a, 0xbe, 0x5c, 0x70, 0x30, 0x48, 0x88, 0x2a, 0x72, 0xc0, 0xea, 0xb0, 0x1c, + 0x30, 0xcd, 0xc2, 0x34, 0x3e, 0x5e, 0x14, 0xc4, 0xff, 0x0f, 0x8e, 0x39, 0xcd, 0xd1, 0x9d, 0x34, + 0x96, 0x87, 0xe5, 0x01, 0xe6, 0x9d, 0xef, 0x21, 0x38, 0xd4, 0x7d, 0xb8, 0xc6, 0x47, 0xbb, 0x62, + 0xa6, 0x7a, 0xd7, 0xd0, 0xf3, 0x5e, 0x1c, 0x74, 0x30, 0x37, 0x3e, 0xcd, 0x51, 0xac, 0xe3, 0x0b, + 0x43, 0x77, 0xc6, 0x2d, 0x19, 0x75, 0x98, 0xa2, 0xb5, 0xec, 0x55, 0xeb, 0xd7, 0x08, 0xe6, 0xa5, + 0xde, 0x3b, 0x21, 0xa5, 0xc5, 0xb0, 0x26, 0xb7, 0x11, 0x98, 0x2d, 0xe3, 0x55, 0x0e, 0xff, 0x93, + 0xf8, 0xfc, 0x88, 0xf0, 0x25, 0xec, 0xb5, 0x98, 0x21, 0xfd, 0x03, 0x82, 0xc3, 0xf7, 0x12, 0xde, + 0x7f, 0x48, 0xf8, 0x37, 0x38, 0xfe, 0xd7, 0xf0, 0x2b, 0x05, 0xe7, 0xbc, 0x61, 0xd3, 0x38, 0x8b, + 0xf0, 0x2f, 0x11, 0x94, 0xe5, 0xab, 0x0a, 0x3e, 0x35, 0x70, 0x63, 0xe4, 0xdf, 0x5d, 0x26, 0x49, + 0x66, 0x71, 0xa8, 0x31, 0x4e, 0x14, 0xa6, 0x53, 0x61, 0x9f, 0x11, 0xfa, 0x1d, 0x04, 0x38, 0xbd, + 0x33, 0xa7, 0xb7, 0x68, 0xfc, 0x62, 0xce, 0xd4, 0xc0, 0xc2, 0x8c, 0x7e, 0x6a, 0x68, 0xbf, 0x7c, + 0x2a, 0x5d, 0x2d, 0x4c, 0xa5, 0x7e, 0x6a, 0xff, 0x9b, 0x08, 0xaa, 0xd7, 0x68, 0x7a, 0x07, 0x29, + 0xf0, 0x65, 0xfe, 0x51, 0x48, 0x5f, 0x19, 0xde, 0x51, 0x20, 0x3a, 0xc3, 0x11, 0xbd, 0x88, 0x8b, + 0x5d, 0x25, 0x01, 0xfc, 0x00, 0xc1, 0xc2, 0x6d, 0x95, 0xa2, 0xf8, 0xcc, 0x30, 0x4b, 0xb9, 0x48, + 0x3e, 0x3a, 0xae, 0x8f, 0x73, 0x5c, 0x6b, 0xc6, 0x48, 0xb8, 0xd6, 0xc5, 0xfb, 0xca, 0x0f, 0x51, + 0x72, 0x89, 0xed, 0xaa, 0x67, 0xff, 0xaf, 0x7e, 0x2b, 0x28, 0x8b, 0x1b, 0xe7, 0x39, 0xbe, 0x1a, + 0x3e, 0x33, 0x0a, 0xbe, 0xba, 0x28, 0x72, 0xe3, 0xef, 0x23, 0x38, 0xcc, 0xdf, 0x1a, 0x54, 0xc5, + 0x5d, 0x29, 0x66, 0xd0, 0xcb, 0xc4, 0x08, 0x29, 0x46, 0xc4, 0x1f, 0x63, 0x5f, 0xa0, 0xd6, 0xe5, + 0x3b, 0xc2, 0xb7, 0x10, 0x1c, 0x90, 0x49, 0x4d, 0xac, 0xee, 0xda, 0x30, 0xc7, 0xed, 0x37, 0x09, + 0x0a, 0xba, 0xad, 0x8e, 0x46, 0xb7, 0xf7, 0x10, 0xcc, 0x89, 0x6a, 0x7e, 0xc1, 0x51, 0x41, 0x29, + 0xf7, 0xeb, 0x5d, 0x35, 0x0e, 0x51, 0x0c, 0x36, 0xbe, 0xc8, 0xcd, 0xde, 0xc5, 0xf5, 0x22, 0xb3, + 0x81, 0x6f, 0x47, 0xf5, 0x87, 0xa2, 0x12, 0xfb, 0xa8, 0xee, 0xfa, 0xcd, 0xe8, 0x0d, 0x03, 0x17, + 0x26, 0x44, 0xd6, 0xe7, 0x2c, 0xc2, 0x31, 0x54, 0x18, 0x39, 0x78, 0xe1, 0x04, 0x2f, 0x77, 0x95, + 0x59, 0x7a, 0x6a, 0x2a, 0xba, 0xde, 0x53, 0x88, 0xc9, 0x32, 0xa0, 0xb8, 0xc6, 0xe2, 0x17, 0x0a, + 0xcd, 0x72, 0x43, 0x6f, 0x23, 0x38, 0xac, 0xb2, 0x3d, 0x31, 0x3f, 0x32, 0xd7, 0x8b, 0x50, 0x88, + 0x43, 0x35, 0x5e, 0x1d, 0x89, 0x48, 0x1c, 0xce, 0xa5, 0xab, 0x7f, 0x7c, 0x72, 0x0c, 0xfd, 0xe5, + 0xc9, 0x31, 0xf4, 0x8f, 0x27, 0xc7, 0xd0, 0x1b, 0x17, 0x46, 0xfb, 0x4f, 0xad, 0xe5, 0x3a, 0xd4, + 0x8b, 0x55, 0xf5, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x30, 0xc0, 0x40, 0x7a, 0x39, 0x2c, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4180,6 +4339,13 @@ func (m *RevisionMetadataQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x22 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4232,6 +4398,13 @@ func (m *ApplicationResourceEventsQuery) MarshalToSizedBuffer(dAtA []byte) (int, i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x32 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4296,6 +4469,13 @@ func (m *ApplicationManifestQuery) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x22 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4382,6 +4562,13 @@ func (m *ApplicationManifestQueryWithFiles) MarshalToSizedBuffer(dAtA []byte) (i i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x22 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4600,6 +4787,13 @@ func (m *ApplicationUpdateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x1a + } if m.Validate != nil { i-- if *m.Validate { @@ -4651,6 +4845,13 @@ func (m *ApplicationDeleteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x2a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4747,6 +4948,13 @@ func (m *ApplicationSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x6a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4890,6 +5098,13 @@ func (m *ApplicationUpdateSpecRequest) MarshalToSizedBuffer(dAtA []byte) (int, e i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x2a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -4957,6 +5172,13 @@ func (m *ApplicationPatchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x32 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5018,6 +5240,13 @@ func (m *ApplicationRollbackRequest) MarshalToSizedBuffer(dAtA []byte) (int, err i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x3a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5088,6 +5317,13 @@ func (m *ApplicationResourceRequest) MarshalToSizedBuffer(dAtA []byte) (int, err i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x42 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5172,6 +5408,13 @@ func (m *ApplicationResourcePatchRequest) MarshalToSizedBuffer(dAtA []byte) (int i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x52 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5274,6 +5517,13 @@ func (m *ApplicationResourceDeleteRequest) MarshalToSizedBuffer(dAtA []byte) (in i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x52 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5378,6 +5628,13 @@ func (m *ResourceActionRunRequest) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x4a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5548,6 +5805,15 @@ func (m *ApplicationPodLogsQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5769,6 +6035,13 @@ func (m *OperationTerminateRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x1a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -5812,6 +6085,13 @@ func (m *ApplicationSyncWindowsQuery) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x1a + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -6015,6 +6295,13 @@ func (m *ResourcesQuery) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x42 + } if m.AppNamespace != nil { i -= len(*m.AppNamespace) copy(dAtA[i:], *m.AppNamespace) @@ -6234,6 +6521,13 @@ func (m *ListAppLinksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Project != nil { + i -= len(*m.Project) + copy(dAtA[i:], *m.Project) + i = encodeVarintApplication(dAtA, i, uint64(len(*m.Project))) + i-- + dAtA[i] = 0x22 + } if m.Namespace != nil { i -= len(*m.Namespace) copy(dAtA[i:], *m.Namespace) @@ -6350,6 +6644,10 @@ func (m *RevisionMetadataQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6382,6 +6680,10 @@ func (m *ApplicationResourceEventsQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6406,6 +6708,10 @@ func (m *ApplicationManifestQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6446,6 +6752,10 @@ func (m *ApplicationManifestQueryWithFiles) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6538,6 +6848,10 @@ func (m *ApplicationUpdateRequest) Size() (n int) { if m.Validate != nil { n += 2 } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6565,6 +6879,10 @@ func (m *ApplicationDeleteRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6643,6 +6961,10 @@ func (m *ApplicationSyncRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6670,6 +6992,10 @@ func (m *ApplicationUpdateSpecRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6698,6 +7024,10 @@ func (m *ApplicationPatchRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6727,6 +7057,10 @@ func (m *ApplicationRollbackRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6767,6 +7101,10 @@ func (m *ApplicationResourceRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6815,6 +7153,10 @@ func (m *ApplicationResourcePatchRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6861,6 +7203,10 @@ func (m *ApplicationResourceDeleteRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6905,6 +7251,10 @@ func (m *ResourceActionRunRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7007,6 +7357,10 @@ func (m *ApplicationPodLogsQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 2 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7058,6 +7412,10 @@ func (m *OperationTerminateRequest) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7078,6 +7436,10 @@ func (m *ApplicationSyncWindowsQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7184,6 +7546,10 @@ func (m *ResourcesQuery) Size() (n int) { l = len(*m.AppNamespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7268,6 +7634,10 @@ func (m *ListAppLinksRequest) Size() (n int) { l = len(*m.Namespace) n += 1 + l + sovApplication(uint64(l)) } + if m.Project != nil { + l = len(*m.Project) + n += 1 + l + sovApplication(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -7841,6 +8211,39 @@ func (m *RevisionMetadataQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -8065,6 +8468,39 @@ func (m *ApplicationResourceEventsQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -8220,26 +8656,59 @@ func (m *ApplicationManifestQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipApplication(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthApplication - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") - } - + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipApplication(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthApplication + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("name") + } + if iNdEx > l { return io.ErrUnexpectedEOF } @@ -8466,6 +8935,39 @@ func (m *ApplicationManifestQueryWithFiles) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -8888,6 +9390,39 @@ func (m *ApplicationUpdateRequest) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.Validate = &b + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -9064,6 +9599,39 @@ func (m *ApplicationDeleteRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -9552,6 +10120,39 @@ func (m *ApplicationSyncRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -9732,6 +10333,39 @@ func (m *ApplicationUpdateSpecRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -9925,6 +10559,39 @@ func (m *ApplicationPatchRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -10116,6 +10783,39 @@ func (m *ApplicationRollbackRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -10407,7 +11107,40 @@ func (m *ApplicationResourceRequest) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } s := string(dAtA[iNdEx:postIndex]) - m.AppNamespace = &s + m.AppNamespace = &s + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s iNdEx = postIndex default: iNdEx = preIndex @@ -10776,6 +11509,39 @@ func (m *ApplicationResourcePatchRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -11123,6 +11889,39 @@ func (m *ApplicationResourceDeleteRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -11456,6 +12255,39 @@ func (m *ResourceActionRunRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -12146,6 +12978,39 @@ func (m *ApplicationPodLogsQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -12496,6 +13361,39 @@ func (m *OperationTerminateRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -12618,6 +13516,39 @@ func (m *ApplicationSyncWindowsQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -13289,6 +14220,39 @@ func (m *ResourcesQuery) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.AppNamespace = &s iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) @@ -13773,6 +14737,39 @@ func (m *ListAppLinksRequest) Unmarshal(dAtA []byte) error { s := string(dAtA[iNdEx:postIndex]) m.Namespace = &s iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Project", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApplication + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthApplication + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthApplication + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Project = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApplication(dAtA[iNdEx:]) diff --git a/server/application/application.go b/server/application/application.go index ec5516dac6d2b..66908fdae7096 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -140,42 +140,88 @@ func NewServer( // getAppEnforceRBAC gets the Application with the given name in the given namespace. If no namespace is // specified, the Application is fetched from the default namespace (the one in which the API server is running). // -// If the Application does not exist, then we have no way of determining if the user would have had access to get that -// Application. Verifying access requires knowing the Application's name, namespace, and project. The user may specify, -// at minimum, the Application name. +// If the user does not provide a "project," then we have to be very careful how we respond. If an app with the given +// name exists, and the user has access to that app in the app's project, we return the app. If the app exists but the +// user does not have access, we return "permission denied." If the app does not exist, we return "permission denied" - +// if we responded with a 404, then the user could infer that the app exists when they get "permission denied." // -// So to prevent a malicious user from inferring the existence or absense of the Application or namespace, we respond -// "permission denied" if the Application does not exist. -func (s *Server) getAppEnforceRBAC(ctx context.Context, action, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, error) { +// If the user does provide a "project," we can respond more specifically. If the user does not have access to the given +// app name in the given project, we return "permission denied." If the app exists, but the project is different from +func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, error) { logCtx := log.WithFields(map[string]interface{}{ "application": name, "namespace": namespace, }) + if project != "" { + // The user has provided everything we need to perform an initial RBAC check. + givenRBACName := security.RBACName(s.ns, project, namespace, name) + if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, action, givenRBACName); err != nil { + logCtx.WithFields(map[string]interface{}{ + "project": project, + argocommon.SecurityField: argocommon.SecurityMedium, + }).Warnf("user tried to %s application which they do not have access to: %s", action, err) + // Do a GET on the app. This ensures that the timing of a "no access" response is the same as a "yes access, + // but the app is in a different project" response. We don't want the user inferring the existence of the + // app from response time. + _, _ = getApp() + return nil, permissionDeniedErr + } + } a, err := getApp() if err != nil { if apierr.IsNotFound(err) { + if project != "" { + // We know that the user was allowed to get the Application, but the Application does not exist. Return 404. + return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + } + // We don't know if the user was allowed to get the Application, and we don't want to leak information about + // the Application's existence. Return 403. logCtx.Warn("application does not exist") return nil, permissionDeniedErr } logCtx.Errorf("failed to get application: %s", err) return nil, permissionDeniedErr } + // Even if we performed an initial RBAC check (because the request was fully parameterized), we still need to + // perform a second RBAC check to ensure that the user has access to the actual Application's project (not just the + // project they specified in the request). if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, action, a.RBACName(s.ns)); err != nil { logCtx.WithFields(map[string]interface{}{ "project": a.Spec.Project, argocommon.SecurityField: argocommon.SecurityMedium, }).Warnf("user tried to %s application which they do not have access to: %s", action, err) + if project != "" { + // The user specified a project. We would have returned a 404 if the user had access to the app, but the app + // did not exist. So we have to return a 404 when the app does exist, but the user does not have access. + // Otherwise, they could infer that the app exists based on the error code. + return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + } + // The user didn't specify a project. We always return permission denied for both lack of access and lack of + // existence. return nil, permissionDeniedErr } + effectiveProject := "default" + if a.Spec.Project != "" { + effectiveProject = a.Spec.Project + } + if project != "" && effectiveProject != project { + logCtx.WithFields(map[string]interface{}{ + "project": a.Spec.Project, + argocommon.SecurityField: argocommon.SecurityMedium, + }).Warnf("user tried to %s application in project %s, but the application is in project %s", action, project, effectiveProject) + // The user has access to the app, but the app is in a different project. Return 404, meaning "app doesn't + // exist in that project". + return nil, status.Errorf(codes.NotFound, apierr.NewNotFound(schema.GroupResource{Group: "argoproj.io", Resource: "applications"}, name).Error()) + } return a, nil } // getApplicationEnforceRBACInformer uses an informer to get an Application. If the app does not exist, permission is // denied, or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive // information. -func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, namespace, name string) (*appv1.Application, error) { +func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, project, namespace, name string) (*appv1.Application, error) { namespaceOrDefault := s.appNamespaceOrDefault(namespace) - return s.getAppEnforceRBAC(ctx, action, namespaceOrDefault, name, func() (*appv1.Application, error) { + return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) { return s.appLister.Applications(namespaceOrDefault).Get(name) }) } @@ -183,9 +229,9 @@ func (s *Server) getApplicationEnforceRBACInformer(ctx context.Context, action, // getApplicationEnforceRBACClient uses a client to get an Application. If the app does not exist, permission is denied, // or any other error occurs when getting the app, we return a permission denied error to obscure any sensitive // information. -func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, namespace, name, resourceVersion string) (*appv1.Application, error) { +func (s *Server) getApplicationEnforceRBACClient(ctx context.Context, action, project, namespace, name, resourceVersion string) (*appv1.Application, error) { namespaceOrDefault := s.appNamespaceOrDefault(namespace) - return s.getAppEnforceRBAC(ctx, action, namespaceOrDefault, name, func() (*appv1.Application, error) { + return s.getAppEnforceRBAC(ctx, action, project, namespaceOrDefault, name, func() (*appv1.Application, error) { return s.appclientset.ArgoprojV1alpha1().Applications(namespaceOrDefault).Get(ctx, name, metav1.GetOptions{ ResourceVersion: resourceVersion, }) @@ -379,7 +425,7 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan if q.Name == nil || *q.Name == "" { return nil, fmt.Errorf("invalid request: application name is missing") } - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err } @@ -484,7 +530,7 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get return fmt.Errorf("invalid request: application name is missing") } - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, query.GetAppNamespace(), query.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, query.GetProject(), query.GetAppNamespace(), query.GetName()) if err != nil { return err } @@ -590,10 +636,17 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app appName := q.GetName() appNs := s.appNamespaceOrDefault(q.GetAppNamespace()) + project := "" + projects := getProjectsFromApplicationQuery(*q) + if len(projects) == 1 { + project = projects[0] + } else if len(projects) > 1 { + return nil, status.Errorf(codes.InvalidArgument, "multiple projects specified - the get endpoint accepts either zero or one project") + } // We must use a client Get instead of an informer Get, because it's common to call Get immediately // following a Watch (which is not yet powered by an informer), and the Get must reflect what was // previously seen by the client. - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, appNs, appName, q.GetResourceVersion()) + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, project, appNs, appName, q.GetResourceVersion()) if err != nil { return nil, err } @@ -676,7 +729,7 @@ func (s *Server) Get(ctx context.Context, q *application.ApplicationQuery) (*app // ListResourceEvents returns a list of event resources func (s *Server) ListResourceEvents(ctx context.Context, q *application.ApplicationResourceEventsQuery) (*v1.EventList, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err } @@ -738,11 +791,13 @@ func (s *Server) ListResourceEvents(ctx context.Context, q *application.Applicat return list, nil } -func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *appv1.Application, merge bool, validate bool, action string) (*appv1.Application, error) { +// validateAndUpdateApp validates and updates the application. currentProject is the name of the project the app +// currently is under. If not specified, we assume that the app is under the project specified in the app spec. +func (s *Server) validateAndUpdateApp(ctx context.Context, newApp *appv1.Application, merge bool, validate bool, action string, currentProject string) (*appv1.Application, error) { s.projectLock.RLock(newApp.Spec.GetProject()) defer s.projectLock.RUnlock(newApp.Spec.GetProject()) - app, err := s.getApplicationEnforceRBACClient(ctx, action, newApp.Namespace, newApp.Name, "") + app, err := s.getApplicationEnforceRBACClient(ctx, action, currentProject, newApp.Namespace, newApp.Name, "") if err != nil { return nil, err } @@ -840,7 +895,7 @@ func (s *Server) updateApp(app *appv1.Application, newApp *appv1.Application, ct // Update updates an application func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateRequest) (*appv1.Application, error) { if q.GetApplication() == nil { - return nil, fmt.Errorf("error creating application: application is nil in request") + return nil, fmt.Errorf("error updating application: application is nil in request") } a := q.GetApplication() if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionUpdate, a.RBACName(s.ns)); err != nil { @@ -851,7 +906,7 @@ func (s *Server) Update(ctx context.Context, q *application.ApplicationUpdateReq if q.Validate != nil { validate = *q.Validate } - return s.validateAndUpdateApp(ctx, q.Application, false, validate, rbacpolicy.ActionUpdate) + return s.validateAndUpdateApp(ctx, q.Application, false, validate, rbacpolicy.ActionUpdate, q.GetProject()) } // UpdateSpec updates an application spec and filters out any invalid parameter overrides @@ -859,7 +914,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat if q.GetSpec() == nil { return nil, fmt.Errorf("error updating application spec: spec is nil in request") } - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionUpdate, q.GetAppNamespace(), q.GetName(), "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionUpdate, q.GetProject(), q.GetAppNamespace(), q.GetName(), "") if err != nil { return nil, err } @@ -869,7 +924,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat if q.Validate != nil { validate = *q.Validate } - a, err = s.validateAndUpdateApp(ctx, a, false, validate, rbacpolicy.ActionUpdate) + a, err = s.validateAndUpdateApp(ctx, a, false, validate, rbacpolicy.ActionUpdate, q.GetProject()) if err != nil { return nil, fmt.Errorf("error validating and updating app: %w", err) } @@ -878,7 +933,7 @@ func (s *Server) UpdateSpec(ctx context.Context, q *application.ApplicationUpdat // Patch patches an application func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchRequest) (*appv1.Application, error) { - app, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName(), "") + app, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "") if err != nil { return nil, err } @@ -918,14 +973,14 @@ func (s *Server) Patch(ctx context.Context, q *application.ApplicationPatchReque if err != nil { return nil, fmt.Errorf("error unmarshaling patched app: %w", err) } - return s.validateAndUpdateApp(ctx, newApp, false, true, rbacpolicy.ActionUpdate) + return s.validateAndUpdateApp(ctx, newApp, false, true, rbacpolicy.ActionUpdate, q.GetProject()) } // Delete removes an application and all associated resources func (s *Server) Delete(ctx context.Context, q *application.ApplicationDeleteRequest) (*application.ApplicationResponse, error) { appName := q.GetName() appNs := s.appNamespaceOrDefault(q.GetAppNamespace()) - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, appNs, appName, "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), appNs, appName, "") if err != nil { return nil, err } @@ -1193,7 +1248,7 @@ func (s *Server) getAppResources(ctx context.Context, a *appv1.Application) (*ap } func (s *Server) getAppLiveResource(ctx context.Context, action string, q *application.ApplicationResourceRequest) (*appv1.ResourceNode, *rest.Config, *appv1.Application, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, action, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, action, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, nil, nil, err } @@ -1260,6 +1315,7 @@ func (s *Server) PatchResource(ctx context.Context, q *application.ApplicationRe Kind: q.Kind, Version: q.Version, Group: q.Group, + Project: q.Project, } res, config, a, err := s.getAppLiveResource(ctx, rbacpolicy.ActionUpdate, resourceRequest) if err != nil { @@ -1302,6 +1358,7 @@ func (s *Server) DeleteResource(ctx context.Context, q *application.ApplicationR Kind: q.Kind, Version: q.Version, Group: q.Group, + Project: q.Project, } res, config, a, err := s.getAppLiveResource(ctx, rbacpolicy.ActionDelete, resourceRequest) if err != nil { @@ -1328,7 +1385,7 @@ func (s *Server) DeleteResource(ctx context.Context, q *application.ApplicationR } func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery) (*appv1.ApplicationTree, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetApplicationName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName()) if err != nil { return nil, err } @@ -1337,7 +1394,7 @@ func (s *Server) ResourceTree(ctx context.Context, q *application.ResourcesQuery } func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application.ApplicationService_WatchResourceTreeServer) error { - _, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetApplicationName()) + _, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName()) if err != nil { return err } @@ -1353,7 +1410,7 @@ func (s *Server) WatchResourceTree(q *application.ResourcesQuery, ws application } func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.RevisionMetadata, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err } @@ -1383,7 +1440,7 @@ func (s *Server) RevisionMetadata(ctx context.Context, q *application.RevisionMe // RevisionChartDetails returns the helm chart metadata, as fetched from the reposerver func (s *Server) RevisionChartDetails(ctx context.Context, q *application.RevisionMetadataQuery) (*appv1.ChartDetails, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, err } @@ -1414,7 +1471,7 @@ func isMatchingResource(q *application.ResourcesQuery, key kube.ResourceKey) boo } func (s *Server) ManagedResources(ctx context.Context, q *application.ResourcesQuery) (*application.ManagedResourcesResponse, error) { - a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetApplicationName()) + a, err := s.getApplicationEnforceRBACInformer(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetApplicationName()) if err != nil { return nil, err } @@ -1471,7 +1528,7 @@ func (s *Server) PodLogs(q *application.ApplicationPodLogsQuery, ws application. } } - a, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName()) + a, err := s.getApplicationEnforceRBACInformer(ws.Context(), rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return err } @@ -1663,7 +1720,7 @@ func isTheSelectedOne(currentNode *appv1.ResourceNode, q *application.Applicatio // Sync syncs an application to its target state func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncRequest) (*appv1.Application, error) { - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, syncReq.GetAppNamespace(), syncReq.GetName(), "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, syncReq.GetProject(), syncReq.GetAppNamespace(), syncReq.GetName(), "") if err != nil { return nil, err } @@ -1772,7 +1829,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR } func (s *Server) Rollback(ctx context.Context, rollbackReq *application.ApplicationRollbackRequest) (*appv1.Application, error) { - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, rollbackReq.GetAppNamespace(), rollbackReq.GetName(), "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, rollbackReq.GetProject(), rollbackReq.GetAppNamespace(), rollbackReq.GetName(), "") if err != nil { return nil, err } @@ -1831,7 +1888,7 @@ func (s *Server) Rollback(ctx context.Context, rollbackReq *application.Applicat } func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksRequest) (*application.LinksResponse, error) { - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, req.GetNamespace(), req.GetName(), "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, req.GetProject(), req.GetNamespace(), req.GetName(), "") if err != nil { return nil, err } @@ -1985,7 +2042,7 @@ func (s *Server) resolveRevision(ctx context.Context, app *appv1.Application, sy func (s *Server) TerminateOperation(ctx context.Context, termOpReq *application.OperationTerminateRequest) (*application.OperationTerminateResponse, error) { appName := termOpReq.GetName() appNs := s.appNamespaceOrDefault(termOpReq.GetAppNamespace()) - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, appNs, appName, "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionSync, termOpReq.GetProject(), appNs, appName, "") if err != nil { return nil, err } @@ -2058,7 +2115,7 @@ func (s *Server) ListResourceActions(ctx context.Context, q *application.Applica func (s *Server) getUnstructuredLiveResourceOrApp(ctx context.Context, rbacRequest string, q *application.ApplicationResourceRequest) (obj *unstructured.Unstructured, res *appv1.ResourceNode, app *appv1.Application, config *rest.Config, err error) { if q.GetKind() == applicationType.ApplicationKind && q.GetGroup() == applicationType.Group && q.GetName() == q.GetResourceName() { - app, err = s.getApplicationEnforceRBACInformer(ctx, rbacRequest, q.GetAppNamespace(), q.GetName()) + app, err = s.getApplicationEnforceRBACInformer(ctx, rbacRequest, q.GetProject(), q.GetAppNamespace(), q.GetName()) if err != nil { return nil, nil, nil, nil, err } @@ -2113,6 +2170,7 @@ func (s *Server) RunResourceAction(ctx context.Context, q *application.ResourceA Kind: q.Kind, Version: q.Version, Group: q.Group, + Project: q.Project, } actionRequest := fmt.Sprintf("%s/%s/%s/%s", rbacpolicy.ActionAction, q.GetGroup(), q.GetKind(), q.GetAction()) liveObj, res, a, config, err := s.getUnstructuredLiveResourceOrApp(ctx, actionRequest, resourceRequest) @@ -2321,7 +2379,7 @@ func splitStatusPatch(patch []byte) ([]byte, []byte, error) { } func (s *Server) GetApplicationSyncWindows(ctx context.Context, q *application.ApplicationSyncWindowsQuery) (*application.ApplicationSyncWindowsResponse, error) { - a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetAppNamespace(), q.GetName(), "") + a, err := s.getApplicationEnforceRBACClient(ctx, rbacpolicy.ActionGet, q.GetProject(), q.GetAppNamespace(), q.GetName(), "") if err != nil { return nil, err } diff --git a/server/application/application.proto b/server/application/application.proto index 7cb268d7d2a7d..53f161795902d 100644 --- a/server/application/application.proto +++ b/server/application/application.proto @@ -13,7 +13,11 @@ import "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1/generated.p import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto"; -// ApplicationQuery is a query for application resources +// ApplicationQuery is a query for application resources. When getting multiple applications, the "projects" field acts +// as a filter. When getting a single application, you may specify either zero or one project. If you specify zero +// projects, the application will be returned regardless of which project it belongs to (assuming you have access). If +// you specify one project, the application will only be returned if it exists and belongs to the specified project. +// Otherwise you will receive a 404. message ApplicationQuery { // the application's name optional string name = 1; @@ -46,6 +50,7 @@ message RevisionMetadataQuery{ required string revision = 2; // the application's namespace optional string appNamespace = 3; + optional string project = 4; } // ApplicationEventsQuery is a query for application resource events @@ -55,6 +60,7 @@ message ApplicationResourceEventsQuery { optional string resourceName = 3; optional string resourceUID = 4; optional string appNamespace = 5; + optional string project = 6; } // ManifestQuery is a query for manifest resources @@ -62,6 +68,7 @@ message ApplicationManifestQuery { required string name = 1; optional string revision = 2; optional string appNamespace = 3; + optional string project = 4; } message FileChunk { @@ -72,6 +79,7 @@ message ApplicationManifestQueryWithFiles { required string name = 1; required string checksum = 2; optional string appNamespace = 3; + optional string project = 4; } message ApplicationManifestQueryWithFilesWrapper { @@ -92,6 +100,7 @@ message ApplicationCreateRequest { message ApplicationUpdateRequest { required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Application application = 1; optional bool validate = 2; + optional string project = 3; } message ApplicationDeleteRequest { @@ -99,6 +108,7 @@ message ApplicationDeleteRequest { optional bool cascade = 2; optional string propagationPolicy = 3; optional string appNamespace = 4; + optional string project = 5; } message SyncOptions { @@ -118,6 +128,7 @@ message ApplicationSyncRequest { optional github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.RetryStrategy retryStrategy = 10; optional SyncOptions syncOptions = 11; optional string appNamespace = 12; + optional string project = 13; } // ApplicationUpdateSpecRequest is a request to update application spec @@ -126,6 +137,7 @@ message ApplicationUpdateSpecRequest { required github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.ApplicationSpec spec = 2; optional bool validate = 3; optional string appNamespace = 4; + optional string project = 5; } // ApplicationPatchRequest is a request to patch an application @@ -134,6 +146,7 @@ message ApplicationPatchRequest { required string patch = 2; required string patchType = 3; optional string appNamespace = 5; + optional string project = 6; } message ApplicationRollbackRequest { @@ -142,6 +155,7 @@ message ApplicationRollbackRequest { optional bool dryRun = 3; optional bool prune = 4; optional string appNamespace = 6; + optional string project = 7; } message ApplicationResourceRequest { @@ -152,6 +166,7 @@ message ApplicationResourceRequest { optional string group = 5; required string kind = 6; optional string appNamespace = 7; + optional string project = 8; } message ApplicationResourcePatchRequest { @@ -164,6 +179,7 @@ message ApplicationResourcePatchRequest { required string patch = 7; required string patchType = 8; optional string appNamespace = 9; + optional string project = 10; } message ApplicationResourceDeleteRequest { @@ -176,6 +192,7 @@ message ApplicationResourceDeleteRequest { optional bool force = 7; optional bool orphan = 8; optional string appNamespace = 9; + optional string project = 10; } message ResourceActionRunRequest { @@ -187,6 +204,7 @@ message ResourceActionRunRequest { required string kind = 6; required string action = 7; optional string appNamespace = 8; + optional string project = 9; } message ResourceActionsListResponse { @@ -213,6 +231,7 @@ message ApplicationPodLogsQuery { optional string resourceName = 13 ; optional bool previous = 14; optional string appNamespace = 15; + optional string project = 16; } message LogEntry { @@ -227,11 +246,13 @@ message LogEntry { message OperationTerminateRequest { required string name = 1; optional string appNamespace = 2; + optional string project = 3; } message ApplicationSyncWindowsQuery { required string name = 1; optional string appNamespace = 2; + optional string project = 3; } message ApplicationSyncWindowsResponse { @@ -260,6 +281,7 @@ message ResourcesQuery { optional string group = 5; optional string kind = 6; optional string appNamespace = 7; + optional string project = 8; } message ManagedResourcesResponse { @@ -280,6 +302,7 @@ message LinksResponse { message ListAppLinksRequest { required string name = 1; optional string namespace = 3; + optional string project = 4; } diff --git a/server/application/application_test.go b/server/application/application_test.go index de647bfede4c8..57b740a6f1ea4 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -5,12 +5,13 @@ import ( coreerrors "errors" "fmt" "io" - "k8s.io/apimachinery/pkg/labels" "strconv" "sync/atomic" "testing" "time" + "k8s.io/apimachinery/pkg/labels" + "github.com/argoproj/gitops-engine/pkg/health" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -570,6 +571,7 @@ type TestServerStream struct { ctx context.Context appName string headerSent bool + project string } func (t *TestServerStream) SetHeader(metadata.MD) error { @@ -604,6 +606,7 @@ func (t *TestServerStream) Recv() (*application.ApplicationManifestQueryWithFile return &application.ApplicationManifestQueryWithFilesWrapper{Part: &application.ApplicationManifestQueryWithFilesWrapper_Query{ Query: &application.ApplicationManifestQueryWithFiles{ Name: pointer.String(t.appName), + Project: pointer.String(t.project), Checksum: pointer.String(""), }, }}, nil @@ -764,6 +767,9 @@ func TestNoAppEnumeration(t *testing.T) { // nolint:staticcheck _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + // nolint:staticcheck + _, err = appServer.Get(adminCtx, &application.ApplicationQuery{Name: pointer.String("doest-not-exist"), Project: []string{"test"}}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetManifests", func(t *testing.T) { @@ -773,6 +779,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.GetManifests(adminCtx, &application.ApplicationManifestQuery{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceEvents", func(t *testing.T) { @@ -782,6 +790,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ListResourceEvents(adminCtx, &application.ApplicationResourceEventsQuery{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("UpdateSpec", func(t *testing.T) { @@ -800,6 +810,11 @@ func TestNoAppEnumeration(t *testing.T) { Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test"), Spec: &appsv1.ApplicationSpec{ + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.com"}, + Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, + }}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Patch", func(t *testing.T) { @@ -809,6 +824,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.Patch(adminCtx, &application.ApplicationPatchRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetResource", func(t *testing.T) { @@ -818,6 +835,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("doest-not-exist"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.GetResource(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("PatchResource", func(t *testing.T) { @@ -829,6 +848,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: pointer.String("doest-not-exist"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test"), Patch: pointer.String(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.PatchResource(adminCtx, &application.ApplicationResourcePatchRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test"), Patch: pointer.String(`[{"op": "replace", "path": "/spec/replicas", "value": 3}]`)}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("DeleteResource", func(t *testing.T) { @@ -838,6 +859,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: pointer.String("doest-not-exist"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.DeleteResource(adminCtx, &application.ApplicationResourceDeleteRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ResourceTree", func(t *testing.T) { @@ -847,6 +870,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ResourceTree(adminCtx, &application.ResourcesQuery{ApplicationName: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RevisionMetadata", func(t *testing.T) { @@ -856,6 +881,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.RevisionMetadata(adminCtx, &application.RevisionMetadataQuery{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RevisionChartDetails", func(t *testing.T) { @@ -865,6 +892,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.RevisionChartDetails(adminCtx, &application.RevisionMetadataQuery{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ManagedResources", func(t *testing.T) { @@ -874,6 +903,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ManagedResources(adminCtx, &application.ResourcesQuery{ApplicationName: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Sync", func(t *testing.T) { @@ -883,6 +914,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.Sync(adminCtx, &application.ApplicationSyncRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("TerminateOperation", func(t *testing.T) { @@ -895,6 +928,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.TerminateOperation(adminCtx, &application.OperationTerminateRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("Rollback", func(t *testing.T) { @@ -905,6 +940,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.Rollback(adminCtx, &application.ApplicationRollbackRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceActions", func(t *testing.T) { @@ -916,6 +953,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ListResourceActions(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("RunResourceAction", func(t *testing.T) { @@ -927,6 +966,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.RunResourceAction(adminCtx, &application.ResourceActionRunRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetApplicationSyncWindows", func(t *testing.T) { @@ -936,6 +977,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.GetApplicationSyncWindows(adminCtx, &application.ApplicationSyncWindowsQuery{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("GetManifestsWithFiles", func(t *testing.T) { @@ -945,6 +988,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist"}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + err = appServer.GetManifestsWithFiles(&TestServerStream{ctx: adminCtx, appName: "does-not-exist", project: "test"}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("WatchResourceTree", func(t *testing.T) { @@ -954,6 +999,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: pointer.String("does-not-exist")}, &TestResourceTreeServer{ctx: adminCtx}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + err = appServer.WatchResourceTree(&application.ResourcesQuery{ApplicationName: pointer.String("does-not-exist"), Project: pointer.String("test")}, &TestResourceTreeServer{ctx: adminCtx}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("PodLogs", func(t *testing.T) { @@ -963,6 +1010,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: pointer.String("does-not-exist")}, &TestPodLogsServer{ctx: adminCtx}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + err = appServer.PodLogs(&application.ApplicationPodLogsQuery{Name: pointer.String("does-not-exist"), Project: pointer.String("test")}, &TestPodLogsServer{ctx: adminCtx}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListLinks", func(t *testing.T) { @@ -972,6 +1021,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: pointer.String("does-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ListLinks(adminCtx, &application.ListAppLinksRequest{Name: pointer.String("does-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) t.Run("ListResourceLinks", func(t *testing.T) { @@ -981,6 +1032,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("does-not-exist"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.ListResourceLinks(adminCtx, &application.ApplicationResourceRequest{Name: pointer.String("does-not-exist"), ResourceName: pointer.String("test"), Group: pointer.String("apps"), Kind: pointer.String("Deployment"), Namespace: pointer.String("test"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"does-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) // Do this last so other stuff doesn't fail. @@ -991,6 +1044,8 @@ func TestNoAppEnumeration(t *testing.T) { assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: pointer.String("doest-not-exist")}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") + _, err = appServer.Delete(adminCtx, &application.ApplicationDeleteRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test")}) + assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") }) } @@ -1650,7 +1705,7 @@ p, admin, applications, update, default/test-app, allow p, admin, applications, create, my-proj/test-app, allow `) _, err := appServer.Update(ctx, &application.ApplicationUpdateRequest{Application: testApp}) - assert.Equal(t, status.Code(err), codes.PermissionDenied) + assert.Equal(t, codes.PermissionDenied, status.Code(err)) }) t.Run("cannot change projects without update privileges in old project", func(t *testing.T) {