diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 20acdf45a9892..953b2591f3bdd 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -845,9 +845,9 @@ func targetObjects(resources []*argoappv1.ResourceDiff) ([]*unstructured.Unstruc return objs, nil } -func getLocalObjects(ctx context.Context, app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions, +func getLocalObjects(ctx context.Context, app *argoappv1.Application, proj *argoappv1.AppProject, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions, configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []*unstructured.Unstructured { - manifestStrings := getLocalObjectsString(ctx, app, local, localRepoRoot, appLabelKey, kubeVersion, apiVersions, kustomizeOptions, configManagementPlugins, trackingMethod) + manifestStrings := getLocalObjectsString(ctx, app, proj, local, localRepoRoot, appLabelKey, kubeVersion, apiVersions, kustomizeOptions, configManagementPlugins, trackingMethod) objs := make([]*unstructured.Unstructured, len(manifestStrings)) for i := range manifestStrings { obj := unstructured.Unstructured{} @@ -858,20 +858,22 @@ func getLocalObjects(ctx context.Context, app *argoappv1.Application, local, loc return objs } -func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions, +func getLocalObjectsString(ctx context.Context, app *argoappv1.Application, proj *argoappv1.AppProject, local, localRepoRoot, appLabelKey, kubeVersion string, apiVersions []string, kustomizeOptions *argoappv1.KustomizeOptions, configManagementPlugins []*argoappv1.ConfigManagementPlugin, trackingMethod string) []string { source := app.Spec.GetSource() res, err := repository.GenerateManifests(ctx, local, localRepoRoot, source.TargetRevision, &repoapiclient.ManifestRequest{ - Repo: &argoappv1.Repository{Repo: source.RepoURL}, - AppLabelKey: appLabelKey, - AppName: app.Name, - Namespace: app.Spec.Destination.Namespace, - ApplicationSource: &source, - KustomizeOptions: kustomizeOptions, - KubeVersion: kubeVersion, - ApiVersions: apiVersions, - Plugins: configManagementPlugins, - TrackingMethod: trackingMethod, + Repo: &argoappv1.Repository{Repo: source.RepoURL}, + AppLabelKey: appLabelKey, + AppName: app.Name, + Namespace: app.Spec.Destination.Namespace, + ApplicationSource: &source, + KustomizeOptions: kustomizeOptions, + KubeVersion: kubeVersion, + ApiVersions: apiVersions, + Plugins: configManagementPlugins, + TrackingMethod: trackingMethod, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, }, true, &git.NoopCredsStore{}, resource.MustParse("0"), nil) errors.CheckError(err) @@ -989,7 +991,8 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co diffOption.cluster = cluster } } - foundDiffs := findandPrintDiff(ctx, app, resources, argoSettings, appName, diffOption) + proj := getProject(c, clientOpts, ctx, app.Spec.Project) + foundDiffs := findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, appName, diffOption) if foundDiffs && exitCode { os.Exit(1) } @@ -1017,13 +1020,13 @@ type DifferenceOption struct { } // findandPrintDiff ... Prints difference between application current state and state stored in git or locally, returns boolean as true if difference is found else returns false -func findandPrintDiff(ctx context.Context, app *argoappv1.Application, resources *application.ManagedResourcesResponse, argoSettings *settingspkg.Settings, appName string, diffOptions *DifferenceOption) bool { +func findandPrintDiff(ctx context.Context, app *argoappv1.Application, proj *argoappv1.AppProject, resources *application.ManagedResourcesResponse, argoSettings *settingspkg.Settings, appName string, diffOptions *DifferenceOption) bool { var foundDiffs bool liveObjs, err := cmdutil.LiveObjects(resources.Items) errors.CheckError(err) items := make([]objKeyLiveTarget, 0) if diffOptions.local != "" { - localObjs := groupObjsByKey(getLocalObjects(ctx, app, diffOptions.local, diffOptions.localRepoRoot, argoSettings.AppLabelKey, diffOptions.cluster.Info.ServerVersion, diffOptions.cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace) + localObjs := groupObjsByKey(getLocalObjects(ctx, app, proj, diffOptions.local, diffOptions.localRepoRoot, argoSettings.AppLabelKey, diffOptions.cluster.Info.ServerVersion, diffOptions.cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod), liveObjs, app.Spec.Destination.Namespace) items = groupObjsForDiff(resources, localObjs, items, argoSettings, app.InstanceName(argoSettings.ControllerNamespace)) } else if diffOptions.revision != "" { var unstructureds []*unstructured.Unstructured @@ -1686,7 +1689,9 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co cluster, err := clusterIf.Get(ctx, &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) argoio.Close(conn) - localObjsStrings = getLocalObjectsString(ctx, app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.Info.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod) + + proj := getProject(c, clientOpts, ctx, app.Spec.Project) + localObjsStrings = getLocalObjectsString(ctx, app, proj.Project, local, localRepoRoot, argoSettings.AppLabelKey, cluster.Info.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod) errors.CheckError(err) diffOption.local = local diffOption.localRepoRoot = localRepoRoot @@ -1755,7 +1760,9 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co errors.CheckError(err) foundDiffs := false fmt.Printf("====== Previewing differences between live and desired state of application %s ======\n", appQualifiedName) - foundDiffs = findandPrintDiff(ctx, app, resources, argoSettings, appQualifiedName, diffOption) + + proj := getProject(c, clientOpts, ctx, app.Spec.Project) + foundDiffs = findandPrintDiff(ctx, app, proj.Project, resources, argoSettings, appQualifiedName, diffOption) if foundDiffs { if !diffChangesConfirm { yesno := cli.AskToProceed(fmt.Sprintf("Please review changes to application %s shown above. Do you want to continue the sync process? (y/n): ", appQualifiedName)) @@ -2354,7 +2361,8 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob cluster, err := clusterIf.Get(context.Background(), &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) - unstructureds = getLocalObjects(context.Background(), app, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod) + proj := getProject(c, clientOpts, ctx, app.Spec.Project) + unstructureds = getLocalObjects(context.Background(), app, proj.Project, local, localRepoRoot, argoSettings.AppLabelKey, cluster.ServerVersion, cluster.Info.APIVersions, argoSettings.KustomizeOptions, argoSettings.ConfigManagementPlugins, argoSettings.TrackingMethod) } else if revision != "" { q := application.ApplicationManifestQuery{ Name: &appName, diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go index d8298101ddab1..56f6363b06bf0 100644 --- a/cmd/argocd/commands/project.go +++ b/cmd/argocd/commands/project.go @@ -1,6 +1,7 @@ package commands import ( + "context" "encoding/json" "fmt" "io" @@ -819,10 +820,7 @@ func NewProjectGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command os.Exit(1) } projName := args[0] - conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() - defer argoio.Close(conn) - detailedProject, err := projIf.GetDetailedProject(ctx, &projectpkg.ProjectQuery{Name: projName}) - errors.CheckError(err) + detailedProject := getProject(c, clientOpts, ctx, projName) switch output { case "yaml", "json": @@ -839,6 +837,14 @@ func NewProjectGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command return command } +func getProject(c *cobra.Command, clientOpts *argocdclient.ClientOptions, ctx context.Context, projName string) *projectpkg.DetailedProjectsResponse { + conn, projIf := headless.NewClientOrDie(clientOpts, c).NewProjectClientOrDie() + defer argoio.Close(conn) + detailedProject, err := projIf.GetDetailedProject(ctx, &projectpkg.ProjectQuery{Name: projName}) + errors.CheckError(err) + return detailedProject +} + func NewProjectEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "edit PROJECT", diff --git a/controller/state.go b/controller/state.go index 62b55bea9ce75..1d70dcae1cc30 100644 --- a/controller/state.go +++ b/controller/state.go @@ -210,6 +210,8 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alp HelmOptions: helmOptions, HasMultipleSources: app.Spec.HasMultipleSources(), RefSources: refSources, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, }) if err != nil { return nil, nil, err diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 3e9eab42178c2..784c0ecc52d34 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -45,17 +45,21 @@ type ManifestRequest struct { KubeVersion string `protobuf:"bytes,14,opt,name=kubeVersion,proto3" json:"kubeVersion,omitempty"` ApiVersions []string `protobuf:"bytes,15,rep,name=apiVersions,proto3" json:"apiVersions,omitempty"` // Request to verify the signature when generating the manifests (only for Git repositories) - VerifySignature bool `protobuf:"varint,16,opt,name=verifySignature,proto3" json:"verifySignature,omitempty"` - HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"` - NoRevisionCache bool `protobuf:"varint,18,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` - TrackingMethod string `protobuf:"bytes,19,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` - EnabledSourceTypes map[string]bool `protobuf:"bytes,20,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,21,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` - HasMultipleSources bool `protobuf:"varint,22,opt,name=hasMultipleSources,proto3" json:"hasMultipleSources,omitempty"` - RefSources map[string]*v1alpha1.RefTarget `protobuf:"bytes,23,rep,name=refSources,proto3" json:"refSources,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + VerifySignature bool `protobuf:"varint,16,opt,name=verifySignature,proto3" json:"verifySignature,omitempty"` + HelmRepoCreds []*v1alpha1.RepoCreds `protobuf:"bytes,17,rep,name=helmRepoCreds,proto3" json:"helmRepoCreds,omitempty"` + NoRevisionCache bool `protobuf:"varint,18,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` + TrackingMethod string `protobuf:"bytes,19,opt,name=trackingMethod,proto3" json:"trackingMethod,omitempty"` + EnabledSourceTypes map[string]bool `protobuf:"bytes,20,rep,name=enabledSourceTypes,proto3" json:"enabledSourceTypes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + HelmOptions *v1alpha1.HelmOptions `protobuf:"bytes,21,opt,name=helmOptions,proto3" json:"helmOptions,omitempty"` + HasMultipleSources bool `protobuf:"varint,22,opt,name=hasMultipleSources,proto3" json:"hasMultipleSources,omitempty"` + RefSources map[string]*v1alpha1.RefTarget `protobuf:"bytes,23,rep,name=refSources,proto3" json:"refSources,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // This is used to surface "source not permitted" errors for Helm repositories + ProjectSourceRepos []string `protobuf:"bytes,24,rep,name=projectSourceRepos,proto3" json:"projectSourceRepos,omitempty"` + // This is used to surface "source not permitted" errors for Helm repositories + ProjectName string `protobuf:"bytes,25,opt,name=projectName,proto3" json:"projectName,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ManifestRequest) Reset() { *m = ManifestRequest{} } @@ -231,6 +235,20 @@ func (m *ManifestRequest) GetRefSources() map[string]*v1alpha1.RefTarget { return nil } +func (m *ManifestRequest) GetProjectSourceRepos() []string { + if m != nil { + return m.ProjectSourceRepos + } + return nil +} + +func (m *ManifestRequest) GetProjectName() string { + if m != nil { + return m.ProjectName + } + return "" +} + type ManifestRequestWithFiles struct { // Types that are valid to be assigned to Part: // *ManifestRequestWithFiles_Request @@ -2162,136 +2180,138 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2061 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5a, 0x5b, 0x6f, 0x1c, 0x49, + // 2092 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0x5b, 0x6f, 0x1c, 0x49, 0x15, 0x9e, 0x9e, 0xf1, 0x65, 0xe6, 0xd8, 0xb1, 0xc7, 0x15, 0x5f, 0x3a, 0xb3, 0x59, 0xcb, 0xdb, 0x90, 0xc8, 0x24, 0xbb, 0x33, 0xb2, 0xa3, 0xdd, 0xa0, 0x2c, 0x2c, 0xf2, 0x7a, 0x13, 0x3b, 0x9b, 0x38, 0x31, 0x9d, 0x00, 0x5a, 0x08, 0xa0, 0x72, 0x4f, 0xcd, 0x4c, 0xed, 0xf4, 0x74, 0x57, 0xba, - 0xab, 0x8d, 0x1c, 0x89, 0x07, 0x04, 0xe2, 0x27, 0x20, 0xc4, 0xff, 0x40, 0x3c, 0x21, 0x9e, 0xb8, - 0x48, 0xbc, 0xac, 0xf8, 0x03, 0xa0, 0xfc, 0x12, 0x54, 0x97, 0xbe, 0x4e, 0xdb, 0xc9, 0x32, 0x8e, - 0x57, 0x68, 0x5f, 0x92, 0xae, 0xaa, 0x73, 0xab, 0x53, 0xa7, 0xce, 0xf9, 0x4e, 0x8d, 0xe1, 0x7a, - 0x40, 0x98, 0x1f, 0x92, 0xe0, 0x98, 0x04, 0x1d, 0xf9, 0x49, 0xb9, 0x1f, 0x9c, 0x64, 0x3e, 0xdb, - 0x2c, 0xf0, 0xb9, 0x8f, 0x20, 0x9d, 0x69, 0x3d, 0xec, 0x53, 0x3e, 0x88, 0x8e, 0xda, 0x8e, 0x3f, - 0xea, 0xe0, 0xa0, 0xef, 0xb3, 0xc0, 0xff, 0x5c, 0x7e, 0xbc, 0xe7, 0x74, 0x3b, 0xc7, 0xdb, 0x1d, - 0x36, 0xec, 0x77, 0x30, 0xa3, 0x61, 0x07, 0x33, 0xe6, 0x52, 0x07, 0x73, 0xea, 0x7b, 0x9d, 0xe3, - 0x2d, 0xec, 0xb2, 0x01, 0xde, 0xea, 0xf4, 0x89, 0x47, 0x02, 0xcc, 0x49, 0x57, 0x49, 0x6e, 0xbd, - 0xd5, 0xf7, 0xfd, 0xbe, 0x4b, 0x3a, 0x72, 0x74, 0x14, 0xf5, 0x3a, 0x64, 0xc4, 0xb8, 0x56, 0x6b, - 0xfd, 0x7e, 0x1e, 0x16, 0x0f, 0xb0, 0x47, 0x7b, 0x24, 0xe4, 0x36, 0x79, 0x1e, 0x91, 0x90, 0xa3, - 0x67, 0x30, 0x25, 0x8c, 0x31, 0x8d, 0x0d, 0x63, 0x73, 0x6e, 0x7b, 0xbf, 0x9d, 0x5a, 0xd3, 0x8e, - 0xad, 0x91, 0x1f, 0x3f, 0x77, 0xba, 0xed, 0xe3, 0xed, 0x36, 0x1b, 0xf6, 0xdb, 0xc2, 0x9a, 0x76, - 0xc6, 0x9a, 0x76, 0x6c, 0x4d, 0xdb, 0x4e, 0xb6, 0x65, 0x4b, 0xa9, 0xa8, 0x05, 0xf5, 0x80, 0x1c, - 0xd3, 0x90, 0xfa, 0x9e, 0x59, 0xdd, 0x30, 0x36, 0x1b, 0x76, 0x32, 0x46, 0x26, 0xcc, 0x7a, 0xfe, - 0x2e, 0x76, 0x06, 0xc4, 0xac, 0x6d, 0x18, 0x9b, 0x75, 0x3b, 0x1e, 0xa2, 0x0d, 0x98, 0xc3, 0x8c, - 0x3d, 0xc4, 0x47, 0xc4, 0x7d, 0x40, 0x4e, 0xcc, 0x29, 0xc9, 0x98, 0x9d, 0x12, 0xbc, 0x98, 0xb1, - 0x47, 0x78, 0x44, 0xcc, 0x69, 0xb9, 0x1a, 0x0f, 0xd1, 0x55, 0x68, 0x78, 0x78, 0x44, 0x42, 0x86, - 0x1d, 0x62, 0xd6, 0xe5, 0x5a, 0x3a, 0x81, 0x7e, 0x09, 0x4b, 0x19, 0xc3, 0x9f, 0xf8, 0x51, 0xe0, - 0x10, 0x13, 0xe4, 0xd6, 0x1f, 0x4f, 0xb6, 0xf5, 0x9d, 0xa2, 0x58, 0x7b, 0x5c, 0x13, 0xfa, 0x19, - 0x4c, 0xcb, 0x93, 0x37, 0xe7, 0x36, 0x6a, 0xe7, 0xea, 0x6d, 0x25, 0x16, 0x79, 0x30, 0xcb, 0xdc, - 0xa8, 0x4f, 0xbd, 0xd0, 0x9c, 0x97, 0x1a, 0x9e, 0x4e, 0xa6, 0x61, 0xd7, 0xf7, 0x7a, 0xb4, 0x7f, - 0x80, 0x3d, 0xdc, 0x27, 0x23, 0xe2, 0xf1, 0x43, 0x29, 0xdc, 0x8e, 0x95, 0xa0, 0x17, 0xd0, 0x1c, - 0x46, 0x21, 0xf7, 0x47, 0xf4, 0x05, 0x79, 0xcc, 0x04, 0x6f, 0x68, 0x5e, 0x92, 0xde, 0x7c, 0x34, - 0x99, 0xe2, 0x07, 0x05, 0xa9, 0xf6, 0x98, 0x1e, 0x11, 0x24, 0xc3, 0xe8, 0x88, 0xfc, 0x90, 0x04, - 0x32, 0xba, 0x16, 0x54, 0x90, 0x64, 0xa6, 0x54, 0x18, 0x51, 0x3d, 0x0a, 0xcd, 0xc5, 0x8d, 0x9a, - 0x0a, 0xa3, 0x64, 0x0a, 0x6d, 0xc2, 0xe2, 0x31, 0x09, 0x68, 0xef, 0xe4, 0x09, 0xed, 0x7b, 0x98, - 0x47, 0x01, 0x31, 0x9b, 0x32, 0x14, 0x8b, 0xd3, 0x68, 0x04, 0x97, 0x06, 0xc4, 0x1d, 0x09, 0x97, - 0xef, 0x06, 0xa4, 0x1b, 0x9a, 0x4b, 0xd2, 0xbf, 0x7b, 0x93, 0x9f, 0xa0, 0x14, 0x67, 0xe7, 0xa5, - 0x0b, 0xc3, 0x3c, 0xdf, 0xd6, 0x37, 0x45, 0xdd, 0x11, 0xa4, 0x0c, 0x2b, 0x4c, 0xa3, 0xeb, 0xb0, - 0xc0, 0x03, 0xec, 0x0c, 0xa9, 0xd7, 0x3f, 0x20, 0x7c, 0xe0, 0x77, 0xcd, 0xcb, 0xd2, 0x13, 0x85, - 0x59, 0xe4, 0x00, 0x22, 0x1e, 0x3e, 0x72, 0x49, 0x57, 0xc5, 0xe2, 0xd3, 0x13, 0x46, 0x42, 0x73, - 0x59, 0xee, 0xe2, 0x56, 0x3b, 0x93, 0xa1, 0x0a, 0x09, 0xa2, 0x7d, 0x77, 0x8c, 0xeb, 0xae, 0xc7, - 0x83, 0x13, 0xbb, 0x44, 0x1c, 0x1a, 0xc2, 0x9c, 0xd8, 0x47, 0x1c, 0x0a, 0x2b, 0x32, 0x14, 0xee, - 0x4f, 0xe6, 0xa3, 0xfd, 0x54, 0xa0, 0x9d, 0x95, 0x8e, 0xda, 0x80, 0x06, 0x38, 0x3c, 0x88, 0x5c, - 0x4e, 0x99, 0x4b, 0x94, 0x19, 0xa1, 0xb9, 0x2a, 0xdd, 0x54, 0xb2, 0x82, 0x1e, 0x00, 0x04, 0xa4, - 0x17, 0xd3, 0xad, 0xc9, 0x9d, 0xdf, 0x3c, 0x6b, 0xe7, 0x76, 0x42, 0xad, 0x76, 0x9c, 0x61, 0x6f, - 0xdd, 0x85, 0xb5, 0x53, 0x1c, 0x83, 0x9a, 0x50, 0x1b, 0x92, 0x13, 0x99, 0x50, 0x1b, 0xb6, 0xf8, - 0x44, 0xcb, 0x30, 0x7d, 0x8c, 0xdd, 0x88, 0xc8, 0x14, 0x58, 0xb7, 0xd5, 0xe0, 0x4e, 0xf5, 0xdb, - 0x46, 0xeb, 0xb7, 0x06, 0x2c, 0x16, 0xd4, 0x94, 0xf0, 0xff, 0x34, 0xcb, 0x7f, 0x0e, 0x41, 0xd7, - 0x7b, 0x8a, 0x83, 0x3e, 0xe1, 0x19, 0x43, 0xac, 0x7f, 0x19, 0x60, 0x16, 0xf6, 0xff, 0x23, 0xca, - 0x07, 0xf7, 0xa8, 0x4b, 0x42, 0x74, 0x1b, 0x66, 0x03, 0x35, 0xa7, 0xcb, 0xc4, 0x5b, 0x67, 0xb8, - 0x6d, 0xbf, 0x62, 0xc7, 0xd4, 0xe8, 0x23, 0xa8, 0x8f, 0x08, 0xc7, 0x5d, 0xcc, 0xb1, 0xb6, 0x7d, - 0xa3, 0x8c, 0x53, 0x68, 0x39, 0xd0, 0x74, 0xfb, 0x15, 0x3b, 0xe1, 0x41, 0xef, 0xc3, 0xb4, 0x33, - 0x88, 0xbc, 0xa1, 0x2c, 0x10, 0x73, 0xdb, 0x6f, 0x9f, 0xc6, 0xbc, 0x2b, 0x88, 0xf6, 0x2b, 0xb6, - 0xa2, 0xfe, 0x78, 0x06, 0xa6, 0x18, 0x0e, 0xb8, 0x75, 0x0f, 0x96, 0xcb, 0x54, 0x88, 0xaa, 0xe4, - 0x0c, 0x88, 0x33, 0x0c, 0xa3, 0x91, 0x76, 0x73, 0x32, 0x46, 0x08, 0xa6, 0x42, 0xfa, 0x42, 0xb9, - 0xba, 0x66, 0xcb, 0x6f, 0xeb, 0x5b, 0xb0, 0x34, 0xa6, 0x4d, 0x1c, 0xaa, 0xb2, 0x4d, 0x48, 0x98, - 0xd7, 0xaa, 0xad, 0x08, 0x56, 0x9e, 0x4a, 0x5f, 0x24, 0xa9, 0xf9, 0x22, 0xea, 0xac, 0xb5, 0x0f, - 0xab, 0x45, 0xb5, 0x21, 0xf3, 0xbd, 0x90, 0x88, 0x5b, 0x22, 0x73, 0x19, 0x25, 0xdd, 0x74, 0x55, - 0x5a, 0x51, 0xb7, 0x4b, 0x56, 0xac, 0x5f, 0x55, 0x61, 0xd5, 0x26, 0xa1, 0xef, 0x1e, 0x93, 0x38, - 0xd1, 0x5c, 0x0c, 0x54, 0xf8, 0x09, 0xd4, 0x30, 0x63, 0x3a, 0x4c, 0xee, 0x9f, 0x5b, 0x31, 0xb6, - 0x85, 0x54, 0xf4, 0x2e, 0x2c, 0xe1, 0xd1, 0x11, 0xed, 0x47, 0x7e, 0x14, 0xc6, 0xdb, 0x92, 0x41, - 0xd5, 0xb0, 0xc7, 0x17, 0x2c, 0x07, 0xd6, 0xc6, 0x5c, 0xa0, 0xdd, 0x99, 0x05, 0x34, 0x46, 0x01, - 0xd0, 0x94, 0x2a, 0xa9, 0x9e, 0xa6, 0xe4, 0x6f, 0x06, 0x34, 0xd3, 0xab, 0xa3, 0xc5, 0x5f, 0x85, - 0xc6, 0x48, 0xcf, 0x85, 0xa6, 0x21, 0x0b, 0x56, 0x3a, 0x91, 0xc7, 0x36, 0xd5, 0x22, 0xb6, 0x59, - 0x85, 0x19, 0x05, 0x3d, 0xf5, 0xc6, 0xf4, 0x28, 0x67, 0xf2, 0x54, 0xc1, 0xe4, 0x75, 0x80, 0x30, - 0xc9, 0x5f, 0xe6, 0x8c, 0x5c, 0xcd, 0xcc, 0x20, 0x0b, 0xe6, 0x55, 0x25, 0xb4, 0x49, 0x18, 0xb9, - 0xdc, 0x9c, 0x95, 0x14, 0xb9, 0x39, 0xcb, 0x87, 0xc5, 0x87, 0x54, 0xec, 0xa1, 0x17, 0x5e, 0x4c, - 0xb0, 0x7f, 0x00, 0x53, 0x42, 0x99, 0xd8, 0xd8, 0x51, 0x80, 0x3d, 0x67, 0x40, 0x62, 0x5f, 0x25, - 0x63, 0x71, 0x8d, 0x39, 0xee, 0x87, 0x66, 0x55, 0xce, 0xcb, 0x6f, 0xeb, 0x4f, 0x55, 0x65, 0xe9, - 0x0e, 0x63, 0xe1, 0x57, 0x0f, 0x7f, 0xcb, 0x0b, 0x72, 0x6d, 0xbc, 0x20, 0x17, 0x4c, 0xfe, 0x32, - 0x05, 0xf9, 0x9c, 0xca, 0x94, 0x15, 0xc1, 0xec, 0x0e, 0x63, 0xc2, 0x10, 0xb4, 0x05, 0x53, 0x98, - 0x31, 0xe5, 0xf0, 0x42, 0x46, 0xd6, 0x24, 0xe2, 0x7f, 0x6d, 0x92, 0x24, 0x6d, 0xdd, 0x86, 0x46, - 0x32, 0xf5, 0x2a, 0xb5, 0x8d, 0xac, 0xda, 0x0d, 0x00, 0x85, 0x38, 0xef, 0x7b, 0x3d, 0x5f, 0x1c, - 0xa9, 0x08, 0x76, 0xcd, 0x2a, 0xbf, 0xad, 0x3b, 0x31, 0x85, 0xb4, 0xed, 0x5d, 0x98, 0xa6, 0x9c, - 0x8c, 0x62, 0xe3, 0x56, 0xb3, 0xc6, 0xa5, 0x82, 0x6c, 0x45, 0x64, 0xfd, 0xbd, 0x0e, 0x57, 0xc4, - 0x89, 0x3d, 0x91, 0xd7, 0x64, 0x87, 0xb1, 0x4f, 0x08, 0xc7, 0xd4, 0x0d, 0xbf, 0x1f, 0x91, 0xe0, - 0xe4, 0x0d, 0x07, 0x46, 0x1f, 0x66, 0xd4, 0x2d, 0xd3, 0xf9, 0xee, 0xdc, 0x9b, 0x0f, 0x2d, 0x3e, - 0xed, 0x38, 0x6a, 0x6f, 0xa6, 0xe3, 0x28, 0xeb, 0x00, 0xa6, 0x2e, 0xa8, 0x03, 0x38, 0xbd, 0x09, - 0xcc, 0xb4, 0x96, 0x33, 0xf9, 0xd6, 0xb2, 0x04, 0x58, 0xcf, 0xbe, 0x2e, 0xb0, 0xae, 0x97, 0x02, - 0xeb, 0x51, 0xe9, 0x3d, 0x6e, 0x48, 0x77, 0x7f, 0x37, 0x1b, 0x81, 0xa7, 0xc6, 0xda, 0x24, 0x10, - 0x1b, 0xde, 0x28, 0xc4, 0xfe, 0x41, 0x0e, 0x32, 0xab, 0xa6, 0xf5, 0xfd, 0xd7, 0xdb, 0xd3, 0xd7, - 0x09, 0x3c, 0xff, 0x46, 0x62, 0x26, 0xe6, 0xa7, 0x3e, 0x48, 0x0a, 0xba, 0xa8, 0x43, 0xa2, 0xb4, - 0xea, 0xa4, 0x25, 0xbe, 0xd1, 0x4d, 0x98, 0x12, 0x4e, 0xd6, 0xa0, 0x76, 0x2d, 0xeb, 0x4f, 0x71, - 0x12, 0x3b, 0x8c, 0x3d, 0x61, 0xc4, 0xb1, 0x25, 0x11, 0xba, 0x03, 0x8d, 0x24, 0xf0, 0xf5, 0xcd, - 0xba, 0x9a, 0xe5, 0x48, 0xee, 0x49, 0xcc, 0x96, 0x92, 0x0b, 0xde, 0x2e, 0x0d, 0x88, 0x23, 0x21, - 0xdf, 0xf4, 0x38, 0xef, 0x27, 0xf1, 0x62, 0xc2, 0x9b, 0x90, 0xa3, 0x2d, 0x98, 0x51, 0x5d, 0xbe, - 0xbc, 0x41, 0x73, 0xdb, 0x57, 0xc6, 0x93, 0x69, 0xcc, 0xa5, 0x09, 0xad, 0xbf, 0x1a, 0xf0, 0x4e, - 0x1a, 0x10, 0xf1, 0x6d, 0x8a, 0x51, 0xf7, 0x57, 0x5f, 0x71, 0xaf, 0xc3, 0x82, 0x84, 0xf9, 0x69, - 0xb3, 0xaf, 0xde, 0x9d, 0x0a, 0xb3, 0xd6, 0x1f, 0x0d, 0xb8, 0x36, 0xbe, 0x8f, 0xdd, 0x01, 0x0e, - 0x78, 0x72, 0xbc, 0x17, 0xb1, 0x97, 0xb8, 0xe0, 0x55, 0xd3, 0x82, 0x97, 0xdb, 0x5f, 0x2d, 0xbf, - 0x3f, 0xeb, 0x2f, 0x55, 0x98, 0xcb, 0x04, 0x50, 0x59, 0xc1, 0x14, 0x80, 0x4f, 0xc6, 0xad, 0x6c, - 0xec, 0x64, 0x51, 0x68, 0xd8, 0x99, 0x19, 0x34, 0x04, 0x60, 0x38, 0xc0, 0x23, 0xc2, 0x49, 0x20, - 0x32, 0xb9, 0xb8, 0xf1, 0x0f, 0x26, 0xcf, 0x2e, 0x87, 0xb1, 0x4c, 0x3b, 0x23, 0x5e, 0x20, 0x56, - 0xa9, 0x3a, 0xd4, 0xf9, 0x5b, 0x8f, 0xd0, 0x2f, 0x60, 0xa1, 0x47, 0x5d, 0x72, 0x98, 0x1a, 0x32, - 0x23, 0x0d, 0x79, 0x3c, 0xb9, 0x21, 0xf7, 0xb2, 0x72, 0xed, 0x82, 0x1a, 0xeb, 0x06, 0x34, 0x8b, - 0xf7, 0x49, 0x18, 0x49, 0x47, 0xb8, 0x9f, 0x78, 0x4b, 0x8f, 0x2c, 0x04, 0xcd, 0xe2, 0xfd, 0xb1, - 0xfe, 0x5d, 0x85, 0x95, 0x44, 0xdc, 0x8e, 0xe7, 0xf9, 0x91, 0xe7, 0xc8, 0x87, 0xb3, 0xd2, 0xb3, - 0x58, 0x86, 0x69, 0x4e, 0xb9, 0x9b, 0x00, 0x1f, 0x39, 0x10, 0xb5, 0x8b, 0xfb, 0xbe, 0xcb, 0x29, - 0xd3, 0x07, 0x1c, 0x0f, 0xd5, 0xd9, 0x3f, 0x8f, 0x68, 0x40, 0xba, 0x32, 0x13, 0xd4, 0xed, 0x64, - 0x2c, 0xd6, 0x04, 0xaa, 0x91, 0x30, 0x5e, 0x39, 0x33, 0x19, 0xcb, 0xb8, 0xf7, 0x5d, 0x97, 0x38, - 0xc2, 0x1d, 0x19, 0xa0, 0x5f, 0x98, 0x95, 0x0d, 0x04, 0x0f, 0xa8, 0xd7, 0xd7, 0x30, 0x5f, 0x8f, - 0x84, 0x9d, 0x38, 0x08, 0xf0, 0x89, 0x59, 0x97, 0x0e, 0x50, 0x03, 0xf4, 0x1d, 0xa8, 0x8d, 0x30, - 0xd3, 0x85, 0xee, 0x46, 0x2e, 0x3b, 0x94, 0x79, 0xa0, 0x7d, 0x80, 0x99, 0xaa, 0x04, 0x82, 0xad, - 0xf5, 0x01, 0xd4, 0xe3, 0x89, 0x2f, 0x05, 0x09, 0x3f, 0x87, 0x4b, 0xb9, 0xe4, 0x83, 0x3e, 0x83, - 0xd5, 0x34, 0xa2, 0xb2, 0x0a, 0x35, 0x08, 0x7c, 0xe7, 0x95, 0x96, 0xd9, 0xa7, 0x08, 0xb0, 0x9e, - 0xc3, 0x92, 0x08, 0x19, 0x79, 0xf1, 0x2f, 0xa8, 0xb5, 0xf9, 0x10, 0x1a, 0x89, 0xca, 0xd2, 0x98, - 0x69, 0x41, 0xfd, 0x38, 0x7e, 0xd0, 0x54, 0xbd, 0x4d, 0x32, 0xb6, 0x76, 0x00, 0x65, 0xed, 0xd5, - 0x15, 0xe8, 0x66, 0x1e, 0x14, 0xaf, 0x14, 0xcb, 0x8d, 0x24, 0x8f, 0x31, 0xf1, 0x3f, 0x0d, 0x58, - 0xdc, 0xa3, 0xf2, 0x95, 0xe3, 0x82, 0x92, 0xdc, 0x0d, 0x68, 0x86, 0xd1, 0xd1, 0xc8, 0xef, 0x46, - 0x2e, 0xd1, 0xa0, 0x40, 0x57, 0xfa, 0xb1, 0xf9, 0xb3, 0x92, 0x9f, 0x70, 0x16, 0xc3, 0x7c, 0xa0, - 0x3b, 0x5c, 0xf9, 0x6d, 0xfd, 0xda, 0x80, 0x66, 0xba, 0x1b, 0xed, 0x8f, 0xdb, 0x2a, 0x6e, 0x95, - 0x37, 0xae, 0x65, 0xbd, 0x51, 0x24, 0xfd, 0xdf, 0x43, 0x76, 0x3e, 0x1b, 0xb2, 0x7f, 0x36, 0x60, - 0x65, 0x8f, 0xf2, 0x38, 0x59, 0xd0, 0xff, 0x33, 0xcf, 0x5a, 0x6d, 0x58, 0x2d, 0x9a, 0xaf, 0x5d, - 0xb9, 0x0c, 0xd3, 0xc2, 0xcf, 0x71, 0xf7, 0xad, 0x06, 0xdb, 0x5f, 0x34, 0x60, 0x29, 0x2d, 0x9f, - 0xe2, 0x5f, 0xea, 0x10, 0xf4, 0x18, 0x9a, 0x7b, 0xfa, 0xb7, 0xaa, 0xf8, 0xd5, 0x03, 0x9d, 0xf5, - 0x8c, 0xd8, 0xba, 0x5a, 0xbe, 0xa8, 0x54, 0x5b, 0x15, 0xe4, 0xc0, 0x95, 0xa2, 0xc0, 0xf4, 0xc5, - 0xf2, 0x9b, 0x67, 0x48, 0x4e, 0xa8, 0x5e, 0xa5, 0x62, 0xd3, 0x40, 0x9f, 0xc1, 0x42, 0xfe, 0x5d, - 0x0d, 0xe5, 0xf2, 0x49, 0xe9, 0x53, 0x5f, 0xcb, 0x3a, 0x8b, 0x24, 0xb1, 0xff, 0x99, 0x00, 0xaf, - 0xb9, 0x47, 0x26, 0x64, 0xe5, 0xa1, 0x75, 0xd9, 0x23, 0x5c, 0xeb, 0x1b, 0x67, 0xd2, 0x24, 0xd2, - 0x3f, 0x84, 0x7a, 0xfc, 0x28, 0x93, 0x77, 0x73, 0xe1, 0xa9, 0xa6, 0xd5, 0xcc, 0xcb, 0xeb, 0x85, - 0x56, 0x05, 0x7d, 0xa4, 0x98, 0x45, 0xd3, 0x3e, 0xce, 0x9c, 0x79, 0x8a, 0x68, 0x5d, 0x2e, 0x69, - 0xff, 0xad, 0x0a, 0xfa, 0x1e, 0xcc, 0x89, 0xaf, 0x43, 0xfd, 0x2b, 0xd1, 0x6a, 0x5b, 0xfd, 0x28, - 0xd9, 0x8e, 0x7f, 0x94, 0x6c, 0xdf, 0x1d, 0x31, 0x7e, 0xd2, 0x2a, 0xe9, 0xcf, 0xb5, 0x80, 0x67, - 0x70, 0x69, 0x8f, 0xf0, 0x14, 0x4e, 0xa3, 0x6b, 0xaf, 0xd5, 0x74, 0xb4, 0xac, 0x22, 0xd9, 0x38, - 0x22, 0xb7, 0x2a, 0xe8, 0x77, 0x06, 0x5c, 0xde, 0x23, 0xbc, 0x08, 0x50, 0xd1, 0x7b, 0xe5, 0x4a, - 0x4e, 0x01, 0xb2, 0xad, 0x47, 0x93, 0xde, 0xd7, 0xbc, 0x58, 0xab, 0x82, 0xfe, 0x60, 0xc0, 0x5a, - 0xc6, 0xb0, 0x2c, 0xe2, 0x44, 0x5b, 0x67, 0x1b, 0x57, 0x82, 0x4e, 0x5b, 0x9f, 0x4e, 0xf8, 0xe3, - 0x5f, 0x46, 0xa4, 0x55, 0x41, 0x87, 0xf2, 0x4c, 0xd2, 0x02, 0x83, 0xde, 0x2e, 0xad, 0x24, 0x89, - 0xf6, 0xf5, 0xd3, 0x96, 0x93, 0x73, 0xf8, 0x14, 0xe6, 0xf6, 0x08, 0x8f, 0xb3, 0x6e, 0x3e, 0xd2, - 0x0a, 0x45, 0x28, 0x7f, 0x55, 0x8b, 0x89, 0x5a, 0x46, 0xcc, 0x92, 0x92, 0x95, 0xc9, 0x53, 0xf9, - 0xbb, 0x5a, 0x9a, 0x82, 0xf3, 0x11, 0x53, 0x9e, 0xe6, 0xac, 0xca, 0xc7, 0x3b, 0xff, 0x78, 0xb9, - 0x6e, 0x7c, 0xf1, 0x72, 0xdd, 0xf8, 0xcf, 0xcb, 0x75, 0xe3, 0xc7, 0xb7, 0x5e, 0xf1, 0x8b, 0x7d, - 0xe6, 0x8f, 0x00, 0x30, 0xa3, 0x8e, 0x4b, 0x89, 0xc7, 0x8f, 0x66, 0x64, 0xf0, 0xdf, 0xfa, 0x6f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xa8, 0x48, 0x92, 0x23, 0x20, 0x00, 0x00, + 0xab, 0x8d, 0x1c, 0x89, 0x07, 0x04, 0xe2, 0x27, 0xf0, 0xc0, 0xff, 0x40, 0x3c, 0x21, 0x9e, 0xb8, + 0x48, 0xbc, 0xac, 0xf8, 0x03, 0xa0, 0x3c, 0xf2, 0x2b, 0x50, 0x5d, 0xfa, 0x3a, 0x6d, 0x27, 0xcb, + 0x38, 0x5e, 0xb1, 0x2f, 0x49, 0xd7, 0xa9, 0x53, 0xe7, 0x9c, 0x3a, 0x75, 0x2e, 0x5f, 0xd5, 0x18, + 0xae, 0x07, 0x84, 0xf9, 0x21, 0x09, 0x8e, 0x49, 0xd0, 0x91, 0x9f, 0x94, 0xfb, 0xc1, 0x49, 0xe6, + 0xb3, 0xcd, 0x02, 0x9f, 0xfb, 0x08, 0x52, 0x4a, 0xeb, 0x61, 0x9f, 0xf2, 0x41, 0x74, 0xd4, 0x76, + 0xfc, 0x51, 0x07, 0x07, 0x7d, 0x9f, 0x05, 0xfe, 0xe7, 0xf2, 0xe3, 0x3d, 0xa7, 0xdb, 0x39, 0xde, + 0xee, 0xb0, 0x61, 0xbf, 0x83, 0x19, 0x0d, 0x3b, 0x98, 0x31, 0x97, 0x3a, 0x98, 0x53, 0xdf, 0xeb, + 0x1c, 0x6f, 0x61, 0x97, 0x0d, 0xf0, 0x56, 0xa7, 0x4f, 0x3c, 0x12, 0x60, 0x4e, 0xba, 0x4a, 0x72, + 0xeb, 0xad, 0xbe, 0xef, 0xf7, 0x5d, 0xd2, 0x91, 0xa3, 0xa3, 0xa8, 0xd7, 0x21, 0x23, 0xc6, 0xb5, + 0x5a, 0xeb, 0x3f, 0xf3, 0xb0, 0x78, 0x80, 0x3d, 0xda, 0x23, 0x21, 0xb7, 0xc9, 0xf3, 0x88, 0x84, + 0x1c, 0x3d, 0x83, 0x29, 0x61, 0x8c, 0x69, 0x6c, 0x18, 0x9b, 0x73, 0xdb, 0xfb, 0xed, 0xd4, 0x9a, + 0x76, 0x6c, 0x8d, 0xfc, 0xf8, 0xb9, 0xd3, 0x6d, 0x1f, 0x6f, 0xb7, 0xd9, 0xb0, 0xdf, 0x16, 0xd6, + 0xb4, 0x33, 0xd6, 0xb4, 0x63, 0x6b, 0xda, 0x76, 0xb2, 0x2d, 0x5b, 0x4a, 0x45, 0x2d, 0xa8, 0x07, + 0xe4, 0x98, 0x86, 0xd4, 0xf7, 0xcc, 0xea, 0x86, 0xb1, 0xd9, 0xb0, 0x93, 0x31, 0x32, 0x61, 0xd6, + 0xf3, 0x77, 0xb1, 0x33, 0x20, 0x66, 0x6d, 0xc3, 0xd8, 0xac, 0xdb, 0xf1, 0x10, 0x6d, 0xc0, 0x1c, + 0x66, 0xec, 0x21, 0x3e, 0x22, 0xee, 0x03, 0x72, 0x62, 0x4e, 0xc9, 0x85, 0x59, 0x92, 0x58, 0x8b, + 0x19, 0x7b, 0x84, 0x47, 0xc4, 0x9c, 0x96, 0xb3, 0xf1, 0x10, 0x5d, 0x85, 0x86, 0x87, 0x47, 0x24, + 0x64, 0xd8, 0x21, 0x66, 0x5d, 0xce, 0xa5, 0x04, 0xf4, 0x4b, 0x58, 0xca, 0x18, 0xfe, 0xc4, 0x8f, + 0x02, 0x87, 0x98, 0x20, 0xb7, 0xfe, 0x78, 0xb2, 0xad, 0xef, 0x14, 0xc5, 0xda, 0xe3, 0x9a, 0xd0, + 0xcf, 0x60, 0x5a, 0x9e, 0xbc, 0x39, 0xb7, 0x51, 0x3b, 0x57, 0x6f, 0x2b, 0xb1, 0xc8, 0x83, 0x59, + 0xe6, 0x46, 0x7d, 0xea, 0x85, 0xe6, 0xbc, 0xd4, 0xf0, 0x74, 0x32, 0x0d, 0xbb, 0xbe, 0xd7, 0xa3, + 0xfd, 0x03, 0xec, 0xe1, 0x3e, 0x19, 0x11, 0x8f, 0x1f, 0x4a, 0xe1, 0x76, 0xac, 0x04, 0xbd, 0x80, + 0xe6, 0x30, 0x0a, 0xb9, 0x3f, 0xa2, 0x2f, 0xc8, 0x63, 0x26, 0xd6, 0x86, 0xe6, 0x25, 0xe9, 0xcd, + 0x47, 0x93, 0x29, 0x7e, 0x50, 0x90, 0x6a, 0x8f, 0xe9, 0x11, 0x41, 0x32, 0x8c, 0x8e, 0xc8, 0x0f, + 0x49, 0x20, 0xa3, 0x6b, 0x41, 0x05, 0x49, 0x86, 0xa4, 0xc2, 0x88, 0xea, 0x51, 0x68, 0x2e, 0x6e, + 0xd4, 0x54, 0x18, 0x25, 0x24, 0xb4, 0x09, 0x8b, 0xc7, 0x24, 0xa0, 0xbd, 0x93, 0x27, 0xb4, 0xef, + 0x61, 0x1e, 0x05, 0xc4, 0x6c, 0xca, 0x50, 0x2c, 0x92, 0xd1, 0x08, 0x2e, 0x0d, 0x88, 0x3b, 0x12, + 0x2e, 0xdf, 0x0d, 0x48, 0x37, 0x34, 0x97, 0xa4, 0x7f, 0xf7, 0x26, 0x3f, 0x41, 0x29, 0xce, 0xce, + 0x4b, 0x17, 0x86, 0x79, 0xbe, 0xad, 0x33, 0x45, 0xe5, 0x08, 0x52, 0x86, 0x15, 0xc8, 0xe8, 0x3a, + 0x2c, 0xf0, 0x00, 0x3b, 0x43, 0xea, 0xf5, 0x0f, 0x08, 0x1f, 0xf8, 0x5d, 0xf3, 0xb2, 0xf4, 0x44, + 0x81, 0x8a, 0x1c, 0x40, 0xc4, 0xc3, 0x47, 0x2e, 0xe9, 0xaa, 0x58, 0x7c, 0x7a, 0xc2, 0x48, 0x68, + 0x2e, 0xcb, 0x5d, 0xdc, 0x6a, 0x67, 0x2a, 0x54, 0xa1, 0x40, 0xb4, 0xef, 0x8e, 0xad, 0xba, 0xeb, + 0xf1, 0xe0, 0xc4, 0x2e, 0x11, 0x87, 0x86, 0x30, 0x27, 0xf6, 0x11, 0x87, 0xc2, 0x8a, 0x0c, 0x85, + 0xfb, 0x93, 0xf9, 0x68, 0x3f, 0x15, 0x68, 0x67, 0xa5, 0xa3, 0x36, 0xa0, 0x01, 0x0e, 0x0f, 0x22, + 0x97, 0x53, 0xe6, 0x12, 0x65, 0x46, 0x68, 0xae, 0x4a, 0x37, 0x95, 0xcc, 0xa0, 0x07, 0x00, 0x01, + 0xe9, 0xc5, 0x7c, 0x6b, 0x72, 0xe7, 0x37, 0xcf, 0xda, 0xb9, 0x9d, 0x70, 0xab, 0x1d, 0x67, 0x96, + 0x0b, 0xe5, 0x62, 0x1b, 0xc4, 0xe1, 0x3a, 0xdb, 0x65, 0x5a, 0x9b, 0x32, 0xc4, 0x4a, 0x66, 0x44, + 0x2c, 0x6a, 0xaa, 0x2c, 0x5a, 0x57, 0x54, 0xb4, 0x66, 0x48, 0xad, 0xbb, 0xb0, 0x76, 0x8a, 0xab, + 0x51, 0x13, 0x6a, 0x43, 0x72, 0x22, 0x4b, 0x74, 0xc3, 0x16, 0x9f, 0x68, 0x19, 0xa6, 0x8f, 0xb1, + 0x1b, 0x11, 0x59, 0x54, 0xeb, 0xb6, 0x1a, 0xdc, 0xa9, 0x7e, 0xdb, 0x68, 0xfd, 0xd6, 0x80, 0xc5, + 0x82, 0xe1, 0x25, 0xeb, 0x7f, 0x9a, 0x5d, 0x7f, 0x0e, 0x61, 0xdc, 0x7b, 0x8a, 0x83, 0x3e, 0xe1, + 0x19, 0x43, 0xac, 0x7f, 0x1a, 0x60, 0x16, 0x3c, 0xfa, 0x23, 0xca, 0x07, 0xf7, 0xa8, 0x4b, 0x42, + 0x74, 0x1b, 0x66, 0x03, 0x45, 0xd3, 0x8d, 0xe7, 0xad, 0x33, 0x0e, 0x62, 0xbf, 0x62, 0xc7, 0xdc, + 0xe8, 0x23, 0xa8, 0x8f, 0x08, 0xc7, 0x5d, 0xcc, 0xb1, 0xb6, 0x7d, 0xa3, 0x6c, 0xa5, 0xd0, 0x72, + 0xa0, 0xf9, 0xf6, 0x2b, 0x76, 0xb2, 0x06, 0xbd, 0x0f, 0xd3, 0xce, 0x20, 0xf2, 0x86, 0xb2, 0xe5, + 0xcc, 0x6d, 0xbf, 0x7d, 0xda, 0xe2, 0x5d, 0xc1, 0xb4, 0x5f, 0xb1, 0x15, 0xf7, 0xc7, 0x33, 0x30, + 0xc5, 0x70, 0xc0, 0xad, 0x7b, 0xb0, 0x5c, 0xa6, 0x42, 0xf4, 0x39, 0x67, 0x40, 0x9c, 0x61, 0x18, + 0x8d, 0xb4, 0x9b, 0x93, 0x31, 0x42, 0x30, 0x15, 0xd2, 0x17, 0xca, 0xd5, 0x35, 0x5b, 0x7e, 0x5b, + 0xdf, 0x82, 0xa5, 0x31, 0x6d, 0xe2, 0x50, 0x95, 0x6d, 0x42, 0xc2, 0xbc, 0x56, 0x6d, 0x45, 0xb0, + 0xf2, 0x54, 0xfa, 0x22, 0x29, 0xf6, 0x17, 0xd1, 0xb9, 0xad, 0x7d, 0x58, 0x2d, 0xaa, 0x0d, 0x99, + 0xef, 0x85, 0x44, 0x84, 0xbe, 0xac, 0x8e, 0x94, 0x74, 0xd3, 0x59, 0x69, 0x45, 0xdd, 0x2e, 0x99, + 0xb1, 0x7e, 0x55, 0x85, 0x55, 0x9b, 0x84, 0xbe, 0x7b, 0x4c, 0xe2, 0xd2, 0x75, 0x31, 0xe0, 0xe3, + 0x27, 0x50, 0xc3, 0x8c, 0xe9, 0x30, 0xb9, 0x7f, 0x6e, 0xed, 0xdd, 0x16, 0x52, 0xd1, 0xbb, 0xb0, + 0x84, 0x47, 0x47, 0xb4, 0x1f, 0xf9, 0x51, 0x18, 0x6f, 0x4b, 0x06, 0x55, 0xc3, 0x1e, 0x9f, 0xb0, + 0x1c, 0x58, 0x1b, 0x73, 0x81, 0x76, 0x67, 0x16, 0x22, 0x19, 0x05, 0x88, 0x54, 0xaa, 0xa4, 0x7a, + 0x9a, 0x92, 0xbf, 0x1a, 0xd0, 0x4c, 0x53, 0x47, 0x8b, 0xbf, 0x0a, 0x8d, 0x91, 0xa6, 0x85, 0xa6, + 0x21, 0xeb, 0x53, 0x4a, 0xc8, 0xa3, 0xa5, 0x6a, 0x11, 0x2d, 0xad, 0xc2, 0x8c, 0x02, 0xb3, 0x7a, + 0x63, 0x7a, 0x94, 0x33, 0x79, 0xaa, 0x60, 0xf2, 0x3a, 0x40, 0x98, 0xd4, 0x2f, 0x73, 0x46, 0xce, + 0x66, 0x28, 0xc8, 0x82, 0x79, 0xd5, 0x5b, 0x6d, 0x12, 0x46, 0x2e, 0x37, 0x67, 0x25, 0x47, 0x8e, + 0x66, 0xf9, 0xb0, 0xf8, 0x90, 0x8a, 0x3d, 0xf4, 0xc2, 0x8b, 0x09, 0xf6, 0x0f, 0x60, 0x4a, 0x28, + 0x13, 0x1b, 0x3b, 0x0a, 0xb0, 0xe7, 0x0c, 0x48, 0xec, 0xab, 0x64, 0x2c, 0xd2, 0x98, 0xe3, 0x7e, + 0x68, 0x56, 0x25, 0x5d, 0x7e, 0x5b, 0x7f, 0xac, 0x2a, 0x4b, 0x77, 0x18, 0x0b, 0xbf, 0x7a, 0x40, + 0x5d, 0xde, 0xe2, 0x6b, 0xe3, 0x2d, 0xbe, 0x60, 0xf2, 0x97, 0x69, 0xf1, 0xe7, 0xd4, 0xa6, 0xac, + 0x08, 0x66, 0x77, 0x18, 0x13, 0x86, 0xa0, 0x2d, 0x98, 0xc2, 0x8c, 0x29, 0x87, 0x17, 0x2a, 0xb2, + 0x66, 0x11, 0xff, 0x6b, 0x93, 0x24, 0x6b, 0xeb, 0x36, 0x34, 0x12, 0xd2, 0xab, 0xd4, 0x36, 0xb2, + 0x6a, 0x37, 0x00, 0x14, 0x86, 0xbd, 0xef, 0xf5, 0x7c, 0x71, 0xa4, 0x22, 0xd8, 0xf5, 0x52, 0xf9, + 0x6d, 0xdd, 0x89, 0x39, 0xa4, 0x6d, 0xef, 0xc2, 0x34, 0xe5, 0x64, 0x14, 0x1b, 0xb7, 0x9a, 0x35, + 0x2e, 0x15, 0x64, 0x2b, 0x26, 0xeb, 0x6f, 0x75, 0xb8, 0x22, 0x4e, 0xec, 0x89, 0x4c, 0x93, 0x1d, + 0xc6, 0x3e, 0x21, 0x1c, 0x53, 0x37, 0xfc, 0x7e, 0x44, 0x82, 0x93, 0x37, 0x1c, 0x18, 0x7d, 0x98, + 0x51, 0x59, 0xa6, 0xeb, 0xdd, 0xb9, 0x5f, 0x67, 0xb4, 0xf8, 0xf4, 0x0e, 0x53, 0x7b, 0x33, 0x77, + 0x98, 0xb2, 0x3b, 0xc5, 0xd4, 0x05, 0xdd, 0x29, 0x4e, 0xbf, 0x56, 0x66, 0x2e, 0xab, 0x33, 0xf9, + 0xcb, 0x6a, 0x09, 0x54, 0x9f, 0x7d, 0x5d, 0xa8, 0x5e, 0x2f, 0x85, 0xea, 0xa3, 0xd2, 0x3c, 0x6e, + 0x48, 0x77, 0x7f, 0x37, 0x1b, 0x81, 0xa7, 0xc6, 0xda, 0x24, 0xa0, 0x1d, 0xde, 0x28, 0x68, 0xff, + 0x41, 0x0e, 0x84, 0xab, 0x6b, 0xf0, 0xfb, 0xaf, 0xb7, 0xa7, 0x33, 0xe0, 0xf8, 0xd7, 0x0e, 0x3c, + 0xff, 0x46, 0x62, 0x26, 0xe6, 0xa7, 0x3e, 0x48, 0x1a, 0xba, 0xe8, 0x43, 0xa2, 0xb5, 0xea, 0xa2, + 0x25, 0xbe, 0xd1, 0x4d, 0x98, 0x12, 0x4e, 0xd6, 0xa0, 0x76, 0x2d, 0xeb, 0x4f, 0x71, 0x12, 0x3b, + 0x8c, 0x3d, 0x61, 0xc4, 0xb1, 0x25, 0x13, 0xba, 0x03, 0x8d, 0x24, 0xf0, 0x75, 0x66, 0x5d, 0xcd, + 0xae, 0x48, 0xf2, 0x24, 0x5e, 0x96, 0xb2, 0x8b, 0xb5, 0x5d, 0x1a, 0x10, 0x47, 0x42, 0xbe, 0xe9, + 0xf1, 0xb5, 0x9f, 0xc4, 0x93, 0xc9, 0xda, 0x84, 0x1d, 0x6d, 0xc1, 0x8c, 0x7a, 0x37, 0x90, 0x19, + 0x34, 0xb7, 0x7d, 0x65, 0xbc, 0x98, 0xc6, 0xab, 0x34, 0xa3, 0xf5, 0x17, 0x03, 0xde, 0x49, 0x03, + 0x22, 0xce, 0xa6, 0x18, 0x75, 0x7f, 0xf5, 0x1d, 0xf7, 0x3a, 0x2c, 0x48, 0x98, 0x9f, 0x3e, 0x1f, + 0xa8, 0x97, 0xac, 0x02, 0xd5, 0xfa, 0x83, 0x01, 0xd7, 0xc6, 0xf7, 0xb1, 0x3b, 0xc0, 0x01, 0x4f, + 0x8e, 0xf7, 0x22, 0xf6, 0x12, 0x37, 0xbc, 0x6a, 0xda, 0xf0, 0x72, 0xfb, 0xab, 0xe5, 0xf7, 0x67, + 0xfd, 0xb9, 0x0a, 0x73, 0x99, 0x00, 0x2a, 0x6b, 0x98, 0x02, 0xf0, 0xc9, 0xb8, 0x95, 0x17, 0x3b, + 0xd9, 0x14, 0x1a, 0x76, 0x86, 0x82, 0x86, 0x00, 0x0c, 0x07, 0x78, 0x44, 0x38, 0x09, 0x44, 0x25, + 0x17, 0x19, 0xff, 0x60, 0xf2, 0xea, 0x72, 0x18, 0xcb, 0xb4, 0x33, 0xe2, 0x05, 0x62, 0x95, 0xaa, + 0x43, 0x5d, 0xbf, 0xf5, 0x08, 0xfd, 0x02, 0x16, 0x7a, 0xd4, 0x25, 0x87, 0xa9, 0x21, 0x33, 0xd2, + 0x90, 0xc7, 0x93, 0x1b, 0x72, 0x2f, 0x2b, 0xd7, 0x2e, 0xa8, 0xb1, 0x6e, 0x40, 0xb3, 0x98, 0x4f, + 0xc2, 0x48, 0x3a, 0xc2, 0xfd, 0xc4, 0x5b, 0x7a, 0x64, 0x21, 0x68, 0x16, 0xf3, 0xc7, 0xfa, 0x57, + 0x15, 0x56, 0x12, 0x71, 0x3b, 0x9e, 0xe7, 0x47, 0x9e, 0x23, 0x9f, 0xe2, 0x4a, 0xcf, 0x62, 0x19, + 0xa6, 0x39, 0xe5, 0x6e, 0x02, 0x7c, 0xe4, 0x40, 0xf4, 0x2e, 0xee, 0xfb, 0x2e, 0xa7, 0x4c, 0x1f, + 0x70, 0x3c, 0x54, 0x67, 0xff, 0x3c, 0xa2, 0x01, 0xe9, 0xca, 0x4a, 0x50, 0xb7, 0x93, 0xb1, 0x98, + 0x13, 0xa8, 0x46, 0xc2, 0x78, 0xe5, 0xcc, 0x64, 0x2c, 0xe3, 0xde, 0x77, 0x5d, 0xe2, 0x08, 0x77, + 0x64, 0x80, 0x7e, 0x81, 0x2a, 0x2f, 0x10, 0x3c, 0xa0, 0x5e, 0x5f, 0xc3, 0x7c, 0x3d, 0x12, 0x76, + 0xe2, 0x20, 0xc0, 0x27, 0x66, 0x5d, 0x3a, 0x40, 0x0d, 0xd0, 0x77, 0xa0, 0x36, 0xc2, 0x4c, 0x37, + 0xba, 0x1b, 0xb9, 0xea, 0x50, 0xe6, 0x81, 0xf6, 0x01, 0x66, 0xaa, 0x13, 0x88, 0x65, 0xad, 0x0f, + 0xa0, 0x1e, 0x13, 0xbe, 0x14, 0x24, 0xfc, 0x1c, 0x2e, 0xe5, 0x8a, 0x0f, 0xfa, 0x0c, 0x56, 0xd3, + 0x88, 0xca, 0x2a, 0xd4, 0x20, 0xf0, 0x9d, 0x57, 0x5a, 0x66, 0x9f, 0x22, 0xc0, 0x7a, 0x0e, 0x4b, + 0x22, 0x64, 0x64, 0xe2, 0x5f, 0xd0, 0xd5, 0xe6, 0x43, 0x68, 0x24, 0x2a, 0x4b, 0x63, 0xa6, 0x05, + 0xf5, 0xe3, 0xf8, 0x89, 0x54, 0xdd, 0x6d, 0x92, 0xb1, 0xb5, 0x03, 0x28, 0x6b, 0xaf, 0xee, 0x40, + 0x37, 0xf3, 0xa0, 0x78, 0xa5, 0xd8, 0x6e, 0x24, 0x7b, 0x8c, 0x89, 0xff, 0x61, 0xc0, 0xe2, 0x1e, + 0x95, 0xaf, 0x1c, 0x17, 0x54, 0xe4, 0x6e, 0x40, 0x33, 0x8c, 0x8e, 0x46, 0x7e, 0x37, 0x72, 0x89, + 0x06, 0x05, 0xba, 0xd3, 0x8f, 0xd1, 0xcf, 0x2a, 0x7e, 0xc2, 0x59, 0x0c, 0xf3, 0x81, 0xbe, 0xe1, + 0xca, 0x6f, 0xeb, 0xd7, 0x06, 0x34, 0xd3, 0xdd, 0x68, 0x7f, 0xdc, 0x56, 0x71, 0xab, 0xbc, 0x71, + 0x2d, 0xeb, 0x8d, 0x22, 0xeb, 0xff, 0x1e, 0xb2, 0xf3, 0xd9, 0x90, 0xfd, 0x93, 0x01, 0x2b, 0x7b, + 0x94, 0xc7, 0xc5, 0x82, 0xfe, 0x9f, 0x79, 0xd6, 0x6a, 0xc3, 0x6a, 0xd1, 0x7c, 0xed, 0xca, 0x65, + 0x98, 0x16, 0x7e, 0x8e, 0x6f, 0xdf, 0x6a, 0xb0, 0xfd, 0x45, 0x03, 0x96, 0xd2, 0xf6, 0x29, 0xfe, + 0xa5, 0x0e, 0x41, 0x8f, 0xa1, 0xb9, 0xa7, 0x7f, 0xfd, 0x8a, 0x5f, 0x3d, 0xd0, 0x59, 0xcf, 0x88, + 0xad, 0xab, 0xe5, 0x93, 0x4a, 0xb5, 0x55, 0x41, 0x0e, 0x5c, 0x29, 0x0a, 0x4c, 0x5f, 0x2c, 0xbf, + 0x79, 0x86, 0xe4, 0x84, 0xeb, 0x55, 0x2a, 0x36, 0x0d, 0xf4, 0x19, 0x2c, 0xe4, 0xdf, 0xd5, 0x50, + 0xae, 0x9e, 0x94, 0x3e, 0xf5, 0xb5, 0xac, 0xb3, 0x58, 0x12, 0xfb, 0x9f, 0x09, 0xf0, 0x9a, 0x7b, + 0x64, 0x42, 0x56, 0x1e, 0x5a, 0x97, 0x3d, 0xc2, 0xb5, 0xbe, 0x71, 0x26, 0x4f, 0x22, 0xfd, 0x43, + 0xa8, 0xc7, 0x8f, 0x32, 0x79, 0x37, 0x17, 0x9e, 0x6a, 0x5a, 0xcd, 0xbc, 0xbc, 0x5e, 0x68, 0x55, + 0xd0, 0x47, 0x6a, 0xb1, 0xb8, 0xb4, 0x8f, 0x2f, 0xce, 0x3c, 0x45, 0xb4, 0x2e, 0x97, 0x5c, 0xff, + 0xad, 0x0a, 0xfa, 0x1e, 0xcc, 0x89, 0xaf, 0x43, 0xfd, 0xbb, 0xd3, 0x6a, 0x5b, 0xfd, 0xcc, 0xd9, + 0x8e, 0x7f, 0xe6, 0x6c, 0xdf, 0x1d, 0x31, 0x7e, 0xd2, 0x2a, 0xb9, 0x9f, 0x6b, 0x01, 0xcf, 0xe0, + 0xd2, 0x1e, 0xe1, 0x29, 0x9c, 0x46, 0xd7, 0x5e, 0xeb, 0xd2, 0xd1, 0xb2, 0x8a, 0x6c, 0xe3, 0x88, + 0xdc, 0xaa, 0xa0, 0xdf, 0x19, 0x70, 0x79, 0x8f, 0xf0, 0x22, 0x40, 0x45, 0xef, 0x95, 0x2b, 0x39, + 0x05, 0xc8, 0xb6, 0x1e, 0x4d, 0x9a, 0xaf, 0x79, 0xb1, 0x56, 0x05, 0xfd, 0xde, 0x80, 0xb5, 0x8c, + 0x61, 0x59, 0xc4, 0x89, 0xb6, 0xce, 0x36, 0xae, 0x04, 0x9d, 0xb6, 0x3e, 0x9d, 0xf0, 0xe7, 0xc4, + 0x8c, 0x48, 0xab, 0x82, 0x0e, 0xe5, 0x99, 0xa4, 0x0d, 0x06, 0xbd, 0x5d, 0xda, 0x49, 0x12, 0xed, + 0xeb, 0xa7, 0x4d, 0x27, 0xe7, 0xf0, 0x29, 0xcc, 0xed, 0x11, 0x1e, 0x57, 0xdd, 0x7c, 0xa4, 0x15, + 0x9a, 0x50, 0x3e, 0x55, 0x8b, 0x85, 0x5a, 0x46, 0xcc, 0x92, 0x92, 0x95, 0xa9, 0x53, 0xf9, 0x5c, + 0x2d, 0x2d, 0xc1, 0xf9, 0x88, 0x29, 0x2f, 0x73, 0x56, 0xe5, 0xe3, 0x9d, 0xbf, 0xbf, 0x5c, 0x37, + 0xbe, 0x78, 0xb9, 0x6e, 0xfc, 0xfb, 0xe5, 0xba, 0xf1, 0xe3, 0x5b, 0xaf, 0xf8, 0x1b, 0x80, 0xcc, + 0x9f, 0x15, 0x60, 0x46, 0x1d, 0x97, 0x12, 0x8f, 0x1f, 0xcd, 0xc8, 0xe0, 0xbf, 0xf5, 0xdf, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x38, 0x69, 0xf2, 0xff, 0x75, 0x20, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2891,6 +2911,26 @@ func (m *ManifestRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.ProjectName) > 0 { + i -= len(m.ProjectName) + copy(dAtA[i:], m.ProjectName) + i = encodeVarintRepository(dAtA, i, uint64(len(m.ProjectName))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xca + } + if len(m.ProjectSourceRepos) > 0 { + for iNdEx := len(m.ProjectSourceRepos) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ProjectSourceRepos[iNdEx]) + copy(dAtA[i:], m.ProjectSourceRepos[iNdEx]) + i = encodeVarintRepository(dAtA, i, uint64(len(m.ProjectSourceRepos[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc2 + } + } if len(m.RefSources) > 0 { for k := range m.RefSources { v := m.RefSources[k] @@ -4921,6 +4961,16 @@ func (m *ManifestRequest) Size() (n int) { n += mapEntrySize + 2 + sovRepository(uint64(mapEntrySize)) } } + if len(m.ProjectSourceRepos) > 0 { + for _, s := range m.ProjectSourceRepos { + l = len(s) + n += 2 + l + sovRepository(uint64(l)) + } + } + l = len(m.ProjectName) + if l > 0 { + n += 2 + l + sovRepository(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -6512,6 +6562,70 @@ func (m *ManifestRequest) Unmarshal(dAtA []byte) error { } m.RefSources[mapkey] = mapvalue iNdEx = postIndex + case 24: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProjectSourceRepos", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProjectSourceRepos = append(m.ProjectSourceRepos, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 25: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProjectName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + 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 ErrInvalidLengthRepository + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRepository + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProjectName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 71a6bdc876ca3..c509906a26632 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -1044,6 +1044,11 @@ func runHelmBuild(appPath string, h helm.Helm) error { return os.WriteFile(markerFile, []byte("marker"), 0644) } +func isSourcePermitted(url string, repos []string) bool { + p := v1alpha1.AppProject{Spec: v1alpha1.AppProjectSpec{SourceRepos: repos}} + return p.IsSourcePermitted(v1alpha1.ApplicationSource{RepoURL: url}) +} + func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths io.TempPaths) ([]*unstructured.Unstructured, error) { concurrencyAllowed := isConcurrencyAllowed(appPath) if !concurrencyAllowed { @@ -1140,6 +1145,20 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie if err != nil { return nil, err } + + var reposNotPermitted []string + // We do a sanity check here to give a nicer error message in case any of the Helm repositories are not permitted by + // the AppProject which the application is a part of + for _, repo := range helmRepos { + if !isSourcePermitted(repo.Repo, q.ProjectSourceRepos) { + reposNotPermitted = append(reposNotPermitted, repo.Repo) + } + } + + if len(reposNotPermitted) > 0 { + return nil, status.Errorf(codes.PermissionDenied, "helm repos %s are not permitted in project '%s'", strings.Join(reposNotPermitted, ", "), q.ProjectName) + } + h, err := helm.NewHelmApp(appPath, helmRepos, isLocal, version, proxy, passCredentials) if err != nil { return nil, err diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 685526a5b08af..b1c89e3a2282e 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -31,6 +31,10 @@ message ManifestRequest { github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.HelmOptions helmOptions = 21; bool hasMultipleSources = 22; map refSources = 23; + // This is used to surface "source not permitted" errors for Helm repositories + repeated string projectSourceRepos = 24; + // This is used to surface "source not permitted" errors for Helm repositories + string projectName = 25; } message ManifestRequestWithFiles { diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 1c5e655c571a2..8a32be75eda3d 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -152,7 +152,12 @@ func TestGenerateYamlManifestInDir(t *testing.T) { service := newService("../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src} + q := apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &src, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + } // update this value if we add/remove manifests const countOfManifests = 49 @@ -218,7 +223,8 @@ func Test_GenerateManifests_NoOutOfBoundsAccess(t *testing.T) { mustNotContain = testCaseCopy.mustNotContain } - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res, err := GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.Error(t, err) assert.NotContains(t, err.Error(), mustNotContain) @@ -233,7 +239,8 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { err := os.Symlink("/obviously/does/not/exist", path.Join(repoDir, "test.yaml")) require.NoError(t, err) - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{}, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} _, err = GenerateManifests(context.Background(), repoDir, "", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) require.NoError(t, err) } @@ -243,8 +250,11 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - KubeVersion: "v1.16.0", - Repo: &argoappv1.Repository{}, ApplicationSource: &src, + KubeVersion: "v1.16.0", + Repo: &argoappv1.Repository{}, + ApplicationSource: &src, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } cachedFakeResponse := &apiclient.ManifestResponse{Manifests: []string{"Fake"}} @@ -268,7 +278,10 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, ApplicationSource: &src, + Repo: &argoappv1.Repository{}, + ApplicationSource: &src, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } err := service.cache.SetManifests(mock.Anything, &src, q.RefSources, &q, "", "", "", "", &cache.CachedManifestResponse{ManifestResponse: nil}, nil) @@ -283,7 +296,8 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { func TestHelmManifestFromChartRepo(t *testing.T) { service := newService(".") source := &argoappv1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} - request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} response, err := service.GenerateManifest(context.Background(), request) assert.NoError(t, err) assert.NotNil(t, response) @@ -312,7 +326,8 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { }, nil) refSources, err := argo.GetRefSources(context.Background(), spec, repoDB) require.NoError(t, err) - request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true} + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} response, err := service.GenerateManifest(context.Background(), request) assert.NoError(t, err) assert.NotNil(t, response) @@ -364,7 +379,8 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Revision: "abc"} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Revision: "abc", ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res1, err := service.GenerateManifest(context.Background(), &q) assert.Nil(t, err) @@ -377,7 +393,8 @@ func TestRecurseManifestsInDir(t *testing.T) { src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res1, err := service.GenerateManifest(context.Background(), &q) assert.Nil(t, err) @@ -410,6 +427,8 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { }, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } res1, err := service.GenerateManifest(context.Background(), &q) assert.Nil(t, err) @@ -431,6 +450,8 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { }, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } res1, err := service.GenerateManifest(context.Background(), &q) assert.Nil(t, err) @@ -450,6 +471,8 @@ func TestGenerateJsonnetLibOutside(t *testing.T) { }, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } _, err := service.GenerateManifest(context.Background(), &q) require.Error(t, err) @@ -624,6 +647,8 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: ".", }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) fmt.Println("-", step, "-", res != nil, err != nil, errorExpected) @@ -792,6 +817,8 @@ func TestGenerateHelmWithValues(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) @@ -827,6 +854,8 @@ func TestHelmWithMissingValueFiles(t *testing.T) { ValueFiles: []string{"values-production.yaml", missingValuesFile}, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } // Should fail since we're passing a non-existent values file, and error should indicate that @@ -852,6 +881,8 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { ValueFiles: []string{"values-$ARGOCD_APP_NAME.yaml"}, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) @@ -887,6 +918,8 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) @@ -898,6 +931,8 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: "./my-chart", }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) } @@ -921,7 +956,12 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { ValueFiles: []string{"./my-chart-values.yaml"}, }, } - request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} + request := &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: source, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}} response, err := service.GenerateManifest(context.Background(), request) assert.NoError(t, err) assert.NotNil(t, response) @@ -960,7 +1000,8 @@ func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { ValueFiles: []string{"my-chart-link.yaml"}, }, } - request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} + request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} _, err := service.GenerateManifest(context.Background(), request) assert.NoError(t, err) }) @@ -979,7 +1020,9 @@ func TestGenerateHelmWithURL(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, - HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https"}}, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"https"}}, }) assert.NoError(t, err) } @@ -999,6 +1042,8 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Error(t, err) assert.Contains(t, err.Error(), "outside repository root") @@ -1016,6 +1061,8 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) }) @@ -1032,6 +1079,8 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) }) @@ -1048,6 +1097,8 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Error(t, err) assert.Contains(t, err.Error(), "outside repository root") @@ -1065,6 +1116,8 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { Values: `cluster: {slaveCount: 2}`, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Error(t, err) assert.Contains(t, err.Error(), "is not allowed") @@ -1081,7 +1134,9 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { ValueFiles: []string{"s3://my-bucket/my-chart-values.yaml"}, }, }, - HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"s3"}}, + HelmOptions: &argoappv1.HelmOptions{ValuesFileSchemes: []string{"s3"}}, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Error(t, err) assert.Contains(t, err.Error(), "s3://my-bucket/my-chart-values.yaml: no such file or directory") @@ -1120,12 +1175,14 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { }}, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Error(t, err) } // The requested file parameter (`../external/external-secret.txt`) is outside the app path -// (`./util/helm/testdata/redis`), however since the requested value is sill under the repo +// (`./util/helm/testdata/redis`), however since the requested value is still under the repo // directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed. It is used as a means of // providing direct content to a helm chart via a specific key. func TestGenerateHelmWithFileParameter(t *testing.T) { @@ -1147,6 +1204,8 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { }, }, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) } @@ -1156,9 +1215,11 @@ func TestGenerateNullList(t *testing.T) { t.Run("null list", func(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/null-list"}, - NoCache: true, + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/null-list"}, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Nil(t, err) assert.Equal(t, len(res1.Manifests), 1) @@ -1167,9 +1228,11 @@ func TestGenerateNullList(t *testing.T) { t.Run("empty list", func(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/empty-list"}, - NoCache: true, + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/empty-list"}, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Nil(t, err) assert.Equal(t, len(res1.Manifests), 1) @@ -1178,9 +1241,11 @@ func TestGenerateNullList(t *testing.T) { t.Run("weird list", func(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/weird-list"}, - NoCache: true, + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{Path: "./testdata/weird-list"}, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.Nil(t, err) assert.Len(t, res1.Manifests, 2) @@ -1228,6 +1293,8 @@ func TestRunCustomTool(t *testing.T) { Repo: &argoappv1.Repository{ Username: "foo", Password: "bar", }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) @@ -1246,8 +1313,10 @@ func TestRunCustomTool(t *testing.T) { func TestGenerateFromUTF16(t *testing.T) { q := apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: &argoappv1.ApplicationSource{}, + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{}, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, } res1, err := GenerateManifests(context.Background(), "./testdata/utf-16", "/", "", &q, false, &git.NoopCredsStore{}, resource.MustParse("0"), nil) assert.Nil(t, err) @@ -1425,7 +1494,13 @@ func TestGetSignatureVerificationResult(t *testing.T) { service := newServiceWithSignature("../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true} + q := apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &src, + VerifySignature: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + } res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) @@ -1436,7 +1511,8 @@ func TestGetSignatureVerificationResult(t *testing.T) { service := newServiceWithSignature("../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) @@ -1447,7 +1523,8 @@ func TestGetSignatureVerificationResult(t *testing.T) { service := newService("../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) @@ -1458,7 +1535,8 @@ func TestGetSignatureVerificationResult(t *testing.T) { service := newService("../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} - q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", + ProjectSourceRepos: []string{"*"}} res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) @@ -1617,6 +1695,8 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) resourceByKindName := make(map[string]*unstructured.Unstructured) @@ -1646,6 +1726,8 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) resourceByKindName := make(map[string]*unstructured.Unstructured) @@ -1675,7 +1757,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, - AppName: "testapp", + AppName: "testapp", + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) resourceByKindName := make(map[string]*unstructured.Unstructured) @@ -1705,7 +1789,9 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ Path: path, }, - AppName: "testapp2", + AppName: "testapp2", + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) require.NoError(t, err) resourceByKindName := make(map[string]*unstructured.Unstructured) @@ -1735,9 +1821,11 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { } sourceCopy := source.DeepCopy() // make a copy in case GenerateManifest mutates it. _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ - Repo: &argoappv1.Repository{}, - ApplicationSource: sourceCopy, - AppName: "test", + Repo: &argoappv1.Repository{}, + ApplicationSource: sourceCopy, + AppName: "test", + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }) assert.NoError(t, err) res := &cache.CachedManifestResponse{} @@ -1771,7 +1859,9 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: regularGitTagHash, }, - NoCache: true, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }, wantError: false, service: newServiceWithCommitSHA(".", regularGitTagHash), @@ -1785,7 +1875,9 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: annotatedGitTaghash, }, - NoCache: true, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }, wantError: false, service: newServiceWithCommitSHA(".", annotatedGitTaghash), @@ -1799,7 +1891,9 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ApplicationSource: &argoappv1.ApplicationSource{ TargetRevision: invalidGitTaghash, }, - NoCache: true, + NoCache: true, + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, }, wantError: true, service: newServiceWithCommitSHA(".", invalidGitTaghash), diff --git a/server/application/application.go b/server/application/application.go index c9d53a7cfffd2..93eb92df25da7 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -421,6 +421,11 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan return fmt.Errorf("error getting API resources: %w", err) } + proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) + if err != nil { + return fmt.Errorf("error getting app project: %w", err) + } + manifestInfo, err = client.GenerateManifest(ctx, &apiclient.ManifestRequest{ Repo: repo, Revision: revision, @@ -437,6 +442,8 @@ func (s *Server) GetManifests(ctx context.Context, q *application.ApplicationMan HelmOptions: helmOptions, TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, }) if err != nil { return fmt.Errorf("error generating manifests: %w", err) @@ -516,6 +523,12 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get } source := a.Spec.GetSource() + + proj, err := argo.GetAppProject(a, applisters.NewAppProjectLister(s.projInformer.GetIndexer()), s.ns, s.settingsMgr, s.db, ctx) + if err != nil { + return fmt.Errorf("error getting app project: %w", err) + } + req := &apiclient.ManifestRequest{ Repo: repo, Revision: source.TargetRevision, @@ -532,6 +545,8 @@ func (s *Server) GetManifestsWithFiles(stream application.ApplicationService_Get HelmOptions: helmOptions, TrackingMethod: string(argoutil.GetTrackingMethod(s.settingsMgr)), EnabledSourceTypes: enableGenerateManifests, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, } repoStreamClient, err := client.GenerateManifestWithFiles(stream.Context()) @@ -1106,6 +1121,7 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica } var conditions []appv1.ApplicationCondition + if validate { conditions := make([]appv1.ApplicationCondition, 0) condition, err := argo.ValidateRepo(ctx, app, s.repoClientset, s.db, plugins, s.kubectl, proj, s.settingsMgr) diff --git a/test/e2e/helm_test.go b/test/e2e/helm_test.go index a723d3a90bb30..953d208a1af9e 100644 --- a/test/e2e/helm_test.go +++ b/test/e2e/helm_test.go @@ -19,6 +19,7 @@ import ( "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" + projectFixture "github.com/argoproj/argo-cd/v2/test/e2e/fixture/project" "github.com/argoproj/argo-cd/v2/test/e2e/fixture/repos" . "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/settings" @@ -399,6 +400,45 @@ func TestHelmWithMultipleDependencies(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)) } +func TestHelmWithMultipleDependenciesPermissionDenied(t *testing.T) { + SkipOnEnv(t, "HELM") + + projName := "argo-helm-project-denied" + projectFixture. + Given(t). + Name(projName). + Destination("*,*"). + When(). + Create(). + AddSource(RepoURL(RepoURLTypeFile)) + + expectedErr := fmt.Sprintf("helm repos localhost:5000/myrepo are not permitted in project '%s'", projName) + GivenWithSameState(t). + Project(projName). + Path("helm-oci-with-dependencies"). + CustomCACertAdded(). + HelmHTTPSCredentialsUserPassAdded(). + HelmPassCredentials(). + When(). + IgnoreErrors(). + CreateApp(). + Then(). + Expect(Error("", expectedErr)) + + expectedErr = fmt.Sprintf("helm repos https://localhost:9444/argo-e2e/testdata.git/helm-repo/local, https://localhost:9444/argo-e2e/testdata.git/helm-repo/local2 are not permitted in project '%s'", projName) + GivenWithSameState(t). + Project(projName). + Path("helm-with-multiple-dependencies"). + CustomCACertAdded(). + HelmHTTPSCredentialsUserPassAdded(). + HelmPassCredentials(). + When(). + IgnoreErrors(). + CreateApp(). + Then(). + Expect(Error("", expectedErr)) +} + func TestHelmWithDependenciesLegacyRepo(t *testing.T) { SkipOnEnv(t, "HELM") testHelmWithDependencies(t, "helm-with-dependencies", true) diff --git a/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml b/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml index fc1982761746c..f7f144d20e123 100644 --- a/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml +++ b/test/e2e/testdata/helm-with-multiple-dependencies/Chart.yaml @@ -1,7 +1,11 @@ apiVersion: v2 -name: helm-with-dependencies +name: helm-with-multiple-dependencies version: v1.0.0 dependencies: - name: helm repository: "https://localhost:9444/argo-e2e/testdata.git/helm-repo/local" version: v1.0.0 + - name: helm + repository: "https://localhost:9444/argo-e2e/testdata.git/helm-repo/local2" + version: v1.0.0 + alias: helm2 \ No newline at end of file diff --git a/util/argo/argo.go b/util/argo/argo.go index a9d5a0bc9ba9d..33f8bdd7e2c6a 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -420,6 +420,7 @@ func validateRepo(ctx context.Context, helmOptions, app.Name, app.Spec.Destination, + proj, sources, repoClient, plugins, @@ -705,6 +706,7 @@ func verifyGenerateManifests( helmOptions *argoappv1.HelmOptions, name string, dest argoappv1.ApplicationDestination, + proj *argoappv1.AppProject, sources []argoappv1.ApplicationSource, repoClient apiclient.RepoServerServiceClient, plugins []*argoappv1.ConfigManagementPlugin, @@ -773,6 +775,8 @@ func verifyGenerateManifests( NoRevisionCache: true, HasMultipleSources: hasMultipleSources, RefSources: refSources, + ProjectName: proj.Name, + ProjectSourceRepos: proj.Spec.SourceRepos, } req.Repo.CopyCredentialsFromRepo(repoRes) req.Repo.CopySettingsFrom(repoRes)