From a5a3791b3c63c52cea4c8796679ee6042afb4ab1 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Sat, 4 Jan 2025 08:21:43 +0100 Subject: [PATCH] chore: enable receiver-naming from revive Signed-off-by: Matthieu MOREL --- .golangci.yaml | 1 - controller/sharding/cache.go | 24 +- .../generators/application_generator.go | 18 +- .../application/v1alpha1/app_project_types.go | 84 ++-- .../application/v1alpha1/repository_types.go | 60 +-- pkg/apis/application/v1alpha1/types.go | 290 +++++++------- server/server.go | 376 +++++++++--------- util/git/creds.go | 4 +- 8 files changed, 428 insertions(+), 429 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 0e85608e22332..eba9946125de3 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -115,7 +115,6 @@ linters-settings: - name: range # receiver names in a method should reflect the struct name (p for Person, for example) - name: receiver-naming - disabled: true # redefining built in names (true, false, append, make) can lead to bugs very difficult to detect. - name: redefines-builtin-id disabled: true diff --git a/controller/sharding/cache.go b/controller/sharding/cache.go index 454b37e4cf5fe..f421efd3c624a 100644 --- a/controller/sharding/cache.go +++ b/controller/sharding/cache.go @@ -52,20 +52,20 @@ func NewClusterSharding(_ db.ArgoDB, shard, replicas int, shardingAlgorithm stri } // IsManagedCluster returns whether or not the cluster should be processed by a given shard. -func (s *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool { - s.lock.RLock() - defer s.lock.RUnlock() +func (sharding *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool { + sharding.lock.RLock() + defer sharding.lock.RUnlock() if c == nil { // nil cluster (in-cluster) is always managed by current clusterShard return true } clusterShard := 0 - if shard, ok := s.Shards[c.Server]; ok { + if shard, ok := sharding.Shards[c.Server]; ok { clusterShard = shard } else { log.Warnf("The cluster %s has no assigned shard.", c.Server) } - log.Debugf("Checking if cluster %s with clusterShard %d should be processed by shard %d", c.Server, clusterShard, s.Shard) - return clusterShard == s.Shard + log.Debugf("Checking if cluster %s with clusterShard %d should be processed by shard %d", c.Server, clusterShard, sharding.Shard) + return clusterShard == sharding.Shard } func (sharding *ClusterSharding) Init(clusters *v1alpha1.ClusterList, apps *v1alpha1.ApplicationList) { @@ -187,11 +187,11 @@ func hasShardingUpdates(old, new *v1alpha1.Cluster) bool { } // A read lock should be acquired before calling getClusterAccessor. -func (d *ClusterSharding) getClusterAccessor() clusterAccessor { +func (sharding *ClusterSharding) getClusterAccessor() clusterAccessor { return func() []*v1alpha1.Cluster { // no need to lock, as this is only called from the updateDistribution function - clusters := make([]*v1alpha1.Cluster, 0, len(d.Clusters)) - for _, c := range d.Clusters { + clusters := make([]*v1alpha1.Cluster, 0, len(sharding.Clusters)) + for _, c := range sharding.Clusters { clusters = append(clusters, c) } return clusters @@ -199,10 +199,10 @@ func (d *ClusterSharding) getClusterAccessor() clusterAccessor { } // A read lock should be acquired before calling getAppAccessor. -func (d *ClusterSharding) getAppAccessor() appAccessor { +func (sharding *ClusterSharding) getAppAccessor() appAccessor { return func() []*v1alpha1.Application { - apps := make([]*v1alpha1.Application, 0, len(d.Apps)) - for _, a := range d.Apps { + apps := make([]*v1alpha1.Application, 0, len(sharding.Apps)) + for _, a := range sharding.Apps { apps = append(apps, a) } return apps diff --git a/hack/gen-resources/generators/application_generator.go b/hack/gen-resources/generators/application_generator.go index 8338492ac6599..1da3ce09b4f7c 100644 --- a/hack/gen-resources/generators/application_generator.go +++ b/hack/gen-resources/generators/application_generator.go @@ -29,7 +29,7 @@ func NewApplicationGenerator(argoClientSet *appclientset.Clientset, clientSet *k return &ApplicationGenerator{argoClientSet, clientSet, db} } -func (pg *ApplicationGenerator) buildRandomSource(repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { +func (ag *ApplicationGenerator) buildRandomSource(repositories []*v1alpha1.Repository) (*v1alpha1.ApplicationSource, error) { seed := rand.New(rand.NewSource(time.Now().Unix())) repoNumber := seed.Int() % len(repositories) return &v1alpha1.ApplicationSource{ @@ -47,7 +47,7 @@ func (ag *ApplicationGenerator) buildSource(opts *util.GenerateOpts, repositorie return ag.buildRandomSource(repositories) } -func (pg *ApplicationGenerator) buildRandomDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { +func (ag *ApplicationGenerator) buildRandomDestination(opts *util.GenerateOpts, clusters []v1alpha1.Cluster) (*v1alpha1.ApplicationDestination, error) { seed := rand.New(rand.NewSource(time.Now().Unix())) clusterNumber := seed.Int() % len(clusters) return &v1alpha1.ApplicationDestination{ @@ -64,25 +64,25 @@ func (ag *ApplicationGenerator) buildDestination(opts *util.GenerateOpts, cluste return ag.buildRandomDestination(opts, clusters) } -func (pg *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { - settingsMgr := settings.NewSettingsManager(context.TODO(), pg.clientSet, opts.Namespace) - repositories, err := db.NewDB(opts.Namespace, settingsMgr, pg.clientSet).ListRepositories(context.TODO()) +func (ag *ApplicationGenerator) Generate(opts *util.GenerateOpts) error { + settingsMgr := settings.NewSettingsManager(context.TODO(), ag.clientSet, opts.Namespace) + repositories, err := db.NewDB(opts.Namespace, settingsMgr, ag.clientSet).ListRepositories(context.TODO()) if err != nil { return err } - clusters, err := db.NewDB(opts.Namespace, settingsMgr, pg.clientSet).ListClusters(context.TODO()) + clusters, err := db.NewDB(opts.Namespace, settingsMgr, ag.clientSet).ListClusters(context.TODO()) if err != nil { return err } - applications := pg.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) + applications := ag.argoClientSet.ArgoprojV1alpha1().Applications(opts.Namespace) for i := 0; i < opts.ApplicationOpts.Samples; i++ { log.Printf("Generate application #%v", i) - source, err := pg.buildSource(opts, repositories) + source, err := ag.buildSource(opts, repositories) if err != nil { return err } log.Printf("Pick source %q", source) - destination, err := pg.buildDestination(opts, clusters.Items) + destination, err := ag.buildDestination(opts, clusters.Items) if err != nil { return err } diff --git a/pkg/apis/application/v1alpha1/app_project_types.go b/pkg/apis/application/v1alpha1/app_project_types.go index 436e578548e3d..081b4bb178803 100644 --- a/pkg/apis/application/v1alpha1/app_project_types.go +++ b/pkg/apis/application/v1alpha1/app_project_types.go @@ -74,19 +74,19 @@ type AppProjectStatus struct { } // GetRoleByName returns the role in a project by the name with its index -func (p *AppProject) GetRoleByName(name string) (*ProjectRole, int, error) { - for i, role := range p.Spec.Roles { +func (proj *AppProject) GetRoleByName(name string) (*ProjectRole, int, error) { + for i, role := range proj.Spec.Roles { if name == role.Name { return &role, i, nil } } - return nil, -1, fmt.Errorf("role '%s' does not exist in project '%s'", name, p.Name) + return nil, -1, fmt.Errorf("role '%s' does not exist in project '%s'", name, proj.Name) } // GetJWTTokenFromSpec looks up the index of a JWTToken in a project by id (new token), if not then by the issue at time (old token) -func (p *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { +func (proj *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { // This is for backward compatibility. In the oder version, JWTTokens are stored under spec.role - role, _, err := p.GetRoleByName(roleName) + role, _, err := proj.GetRoleByName(roleName) if err != nil { return nil, -1, err } @@ -107,14 +107,14 @@ func (p *AppProject) GetJWTTokenFromSpec(roleName string, issuedAt int64, id str } } - return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", role.Name, issuedAt, p.Name) + return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", role.Name, issuedAt, proj.Name) } // GetJWTToken looks up the index of a JWTToken in a project by id (new token), if not then by the issue at time (old token) -func (p *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { +func (proj *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) (*JWTToken, int, error) { // This is for newer version, JWTTokens are stored under status if id != "" { - for i, token := range p.Status.JWTTokensByRole[roleName].Items { + for i, token := range proj.Status.JWTTokensByRole[roleName].Items { if id == token.ID { return &token, i, nil } @@ -122,31 +122,31 @@ func (p *AppProject) GetJWTToken(roleName string, issuedAt int64, id string) (*J } if issuedAt != -1 { - for i, token := range p.Status.JWTTokensByRole[roleName].Items { + for i, token := range proj.Status.JWTTokensByRole[roleName].Items { if issuedAt == token.IssuedAt { return &token, i, nil } } } - return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", roleName, issuedAt, p.Name) + return nil, -1, fmt.Errorf("JWT token for role '%s' issued at '%d' does not exist in project '%s'", roleName, issuedAt, proj.Name) } // RemoveJWTToken removes the specified JWT from an AppProject -func (p AppProject) RemoveJWTToken(roleIndex int, issuedAt int64, id string) error { - roleName := p.Spec.Roles[roleIndex].Name +func (proj AppProject) RemoveJWTToken(roleIndex int, issuedAt int64, id string) error { + roleName := proj.Spec.Roles[roleIndex].Name // For backward compatibility - _, jwtTokenIndex, err1 := p.GetJWTTokenFromSpec(roleName, issuedAt, id) + _, jwtTokenIndex, err1 := proj.GetJWTTokenFromSpec(roleName, issuedAt, id) if err1 == nil { - p.Spec.Roles[roleIndex].JWTTokens[jwtTokenIndex] = p.Spec.Roles[roleIndex].JWTTokens[len(p.Spec.Roles[roleIndex].JWTTokens)-1] - p.Spec.Roles[roleIndex].JWTTokens = p.Spec.Roles[roleIndex].JWTTokens[:len(p.Spec.Roles[roleIndex].JWTTokens)-1] + proj.Spec.Roles[roleIndex].JWTTokens[jwtTokenIndex] = proj.Spec.Roles[roleIndex].JWTTokens[len(proj.Spec.Roles[roleIndex].JWTTokens)-1] + proj.Spec.Roles[roleIndex].JWTTokens = proj.Spec.Roles[roleIndex].JWTTokens[:len(proj.Spec.Roles[roleIndex].JWTTokens)-1] } // New location for storing JWTToken - _, jwtTokenIndex, err2 := p.GetJWTToken(roleName, issuedAt, id) + _, jwtTokenIndex, err2 := proj.GetJWTToken(roleName, issuedAt, id) if err2 == nil { - p.Status.JWTTokensByRole[roleName].Items[jwtTokenIndex] = p.Status.JWTTokensByRole[roleName].Items[len(p.Status.JWTTokensByRole[roleName].Items)-1] - p.Status.JWTTokensByRole[roleName] = JWTTokens{Items: p.Status.JWTTokensByRole[roleName].Items[:len(p.Status.JWTTokensByRole[roleName].Items)-1]} + proj.Status.JWTTokensByRole[roleName].Items[jwtTokenIndex] = proj.Status.JWTTokensByRole[roleName].Items[len(proj.Status.JWTTokensByRole[roleName].Items)-1] + proj.Status.JWTTokensByRole[roleName] = JWTTokens{Items: proj.Status.JWTTokensByRole[roleName].Items[:len(proj.Status.JWTTokensByRole[roleName].Items)-1]} } if err1 == nil || err2 == nil { @@ -159,8 +159,8 @@ func (p AppProject) RemoveJWTToken(roleIndex int, issuedAt int64, id string) err } // TODO: document this method -func (p *AppProject) ValidateJWTTokenID(roleName string, id string) error { - role, _, err := p.GetRoleByName(roleName) +func (proj *AppProject) ValidateJWTTokenID(roleName string, id string) error { + role, _, err := proj.GetRoleByName(roleName) if err != nil { return err } @@ -175,9 +175,9 @@ func (p *AppProject) ValidateJWTTokenID(roleName string, id string) error { return nil } -func (p *AppProject) ValidateProject() error { +func (proj *AppProject) ValidateProject() error { destKeys := make(map[string]bool) - for _, dest := range p.Spec.Destinations { + for _, dest := range proj.Spec.Destinations { if dest.Name == "!*" { return status.Errorf(codes.InvalidArgument, "name has an invalid format, '!*'") } @@ -202,7 +202,7 @@ func (p *AppProject) ValidateProject() error { } srcNamespaces := make(map[string]bool) - for _, ns := range p.Spec.SourceNamespaces { + for _, ns := range proj.Spec.SourceNamespaces { if _, ok := srcNamespaces[ns]; ok { return status.Errorf(codes.InvalidArgument, "source namespace '%s' already added", ns) } @@ -210,7 +210,7 @@ func (p *AppProject) ValidateProject() error { } srcRepos := make(map[string]bool) - for _, src := range p.Spec.SourceRepos { + for _, src := range proj.Spec.SourceRepos { if src == "!*" { return status.Errorf(codes.InvalidArgument, "source repository has an invalid format, '!*'") } @@ -222,7 +222,7 @@ func (p *AppProject) ValidateProject() error { } roleNames := make(map[string]bool) - for _, role := range p.Spec.Roles { + for _, role := range proj.Spec.Roles { if _, ok := roleNames[role.Name]; ok { return status.Errorf(codes.AlreadyExists, "role '%s' already exists", role.Name) } @@ -234,7 +234,7 @@ func (p *AppProject) ValidateProject() error { if _, ok := existingPolicies[policy]; ok { return status.Errorf(codes.AlreadyExists, "policy '%s' already exists for role '%s'", policy, role.Name) } - if err := validatePolicy(p.Name, role.Name, policy); err != nil { + if err := validatePolicy(proj.Name, role.Name, policy); err != nil { return err } existingPolicies[policy] = true @@ -252,9 +252,9 @@ func (p *AppProject) ValidateProject() error { roleNames[role.Name] = true } - if p.Spec.SyncWindows.HasWindows() { + if proj.Spec.SyncWindows.HasWindows() { existingWindows := make(map[string]bool) - for _, window := range p.Spec.SyncWindows { + for _, window := range proj.Spec.SyncWindows { if window == nil { continue } @@ -273,7 +273,7 @@ func (p *AppProject) ValidateProject() error { } destServiceAccts := make(map[string]bool) - for _, destServiceAcct := range p.Spec.DestinationServiceAccounts { + for _, destServiceAcct := range proj.Spec.DestinationServiceAccounts { if strings.Contains(destServiceAcct.Server, "!") { return status.Errorf(codes.InvalidArgument, "server has an invalid format, '%s'", destServiceAcct.Server) } @@ -308,8 +308,8 @@ func (p *AppProject) ValidateProject() error { } // AddGroupToRole adds an OIDC group to a role -func (p *AppProject) AddGroupToRole(roleName, group string) (bool, error) { - role, roleIndex, err := p.GetRoleByName(roleName) +func (proj *AppProject) AddGroupToRole(roleName, group string) (bool, error) { + role, roleIndex, err := proj.GetRoleByName(roleName) if err != nil { return false, err } @@ -319,20 +319,20 @@ func (p *AppProject) AddGroupToRole(roleName, group string) (bool, error) { } } role.Groups = append(role.Groups, group) - p.Spec.Roles[roleIndex] = *role + proj.Spec.Roles[roleIndex] = *role return true, nil } // RemoveGroupFromRole removes an OIDC group from a role -func (p *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { - role, roleIndex, err := p.GetRoleByName(roleName) +func (proj *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { + role, roleIndex, err := proj.GetRoleByName(roleName) if err != nil { return false, err } for i, roleGroup := range role.Groups { if group == roleGroup { role.Groups = append(role.Groups[:i], role.Groups[i+1:]...) - p.Spec.Roles[roleIndex] = *role + proj.Spec.Roles[roleIndex] = *role return true, nil } } @@ -340,17 +340,17 @@ func (p *AppProject) RemoveGroupFromRole(roleName, group string) (bool, error) { } // NormalizePolicies normalizes the policies in the project -func (p *AppProject) NormalizePolicies() { - for i, role := range p.Spec.Roles { +func (proj *AppProject) NormalizePolicies() { + for i, role := range proj.Spec.Roles { var normalizedPolicies []string for _, policy := range role.Policies { - normalizedPolicies = append(normalizedPolicies, p.normalizePolicy(policy)) + normalizedPolicies = append(normalizedPolicies, proj.normalizePolicy(policy)) } - p.Spec.Roles[i].Policies = normalizedPolicies + proj.Spec.Roles[i].Policies = normalizedPolicies } } -func (p *AppProject) normalizePolicy(policy string) string { +func (proj *AppProject) normalizePolicy(policy string) string { policyComponents := strings.Split(policy, ",") normalizedPolicy := "" for _, component := range policyComponents { @@ -597,10 +597,10 @@ func jwtTokensCombine(tokens1 []JWTToken, tokens2 []JWTToken) []JWTToken { // Applications in the installation namespace are always permitted. Also, at // application creation time, its namespace may yet be empty to indicate that // the application will be created in the controller's namespace. -func (p AppProject) IsAppNamespacePermitted(app *Application, controllerNs string) bool { +func (proj AppProject) IsAppNamespacePermitted(app *Application, controllerNs string) bool { if app.Namespace == "" || app.Namespace == controllerNs { return true } - return glob.MatchStringInList(p.Spec.SourceNamespaces, app.Namespace, glob.REGEXP) + return glob.MatchStringInList(proj.Spec.SourceNamespaces, app.Namespace, glob.REGEXP) } diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 047ae14b1ac97..8a222585ab2de 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -112,8 +112,8 @@ func (repo *Repository) IsLFSEnabled() bool { } // HasCredentials returns true when the repository has been configured with any credentials -func (m *Repository) HasCredentials() bool { - return m.Username != "" || m.Password != "" || m.SSHPrivateKey != "" || m.TLSClientCertData != "" || m.GithubAppPrivateKey != "" +func (repo *Repository) HasCredentials() bool { + return repo.Username != "" || repo.Password != "" || repo.SSHPrivateKey != "" || repo.TLSClientCertData != "" || repo.GithubAppPrivateKey != "" } // CopyCredentialsFromRepo copies all credential information from source repository to receiving repository @@ -267,49 +267,49 @@ func getCAPath(repoURL string) string { } // CopySettingsFrom copies all repository settings from source to receiver -func (m *Repository) CopySettingsFrom(source *Repository) { +func (repo *Repository) CopySettingsFrom(source *Repository) { if source != nil { - m.EnableLFS = source.EnableLFS - m.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey - m.Insecure = source.Insecure - m.InheritedCreds = source.InheritedCreds + repo.EnableLFS = source.EnableLFS + repo.InsecureIgnoreHostKey = source.InsecureIgnoreHostKey + repo.Insecure = source.Insecure + repo.InheritedCreds = source.InheritedCreds } } // StringForLogging gets a string representation of the Repository which is safe to log or return to the user. -func (m *Repository) StringForLogging() string { - if m == nil { +func (repo *Repository) StringForLogging() string { + if repo == nil { return "" } - return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", m.Repo, m.Type, m.Name, m.Project) + return fmt.Sprintf("&Repository{Repo: %q, Type: %q, Name: %q, Project: %q}", repo.Repo, repo.Type, repo.Name, repo.Project) } // Sanitized returns a copy of the Repository with sensitive information removed. -func (m *Repository) Sanitized() *Repository { +func (repo *Repository) Sanitized() *Repository { return &Repository{ - Repo: m.Repo, - Type: m.Type, - Name: m.Name, - Username: m.Username, - Insecure: m.IsInsecure(), - EnableLFS: m.EnableLFS, - EnableOCI: m.EnableOCI, - Proxy: m.Proxy, - NoProxy: m.NoProxy, - Project: m.Project, - ForceHttpBasicAuth: m.ForceHttpBasicAuth, - InheritedCreds: m.InheritedCreds, - GithubAppId: m.GithubAppId, - GithubAppInstallationId: m.GithubAppInstallationId, - GitHubAppEnterpriseBaseURL: m.GitHubAppEnterpriseBaseURL, + Repo: repo.Repo, + Type: repo.Type, + Name: repo.Name, + Username: repo.Username, + Insecure: repo.IsInsecure(), + EnableLFS: repo.EnableLFS, + EnableOCI: repo.EnableOCI, + Proxy: repo.Proxy, + NoProxy: repo.NoProxy, + Project: repo.Project, + ForceHttpBasicAuth: repo.ForceHttpBasicAuth, + InheritedCreds: repo.InheritedCreds, + GithubAppId: repo.GithubAppId, + GithubAppInstallationId: repo.GithubAppInstallationId, + GitHubAppEnterpriseBaseURL: repo.GitHubAppEnterpriseBaseURL, } } -func (m *Repository) Normalize() *Repository { - if m.Type == "" { - m.Type = common.DefaultRepoType +func (repo *Repository) Normalize() *Repository { + if repo.Type == "" { + repo.Type = common.DefaultRepoType } - return m + return repo } // Repositories defines a list of Repository configurations diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index db61be5c888ff..d62948721700f 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -202,12 +202,12 @@ type ApplicationSource struct { // ApplicationSources contains list of required information about the sources of an application type ApplicationSources []ApplicationSource -func (s ApplicationSources) Equals(other ApplicationSources) bool { - if len(s) != len(other) { +func (a ApplicationSources) Equals(other ApplicationSources) bool { + if len(a) != len(other) { return false } - for i := range s { - if !s[i].Equals(&other[i]) { + for i := range a { + if !a[i].Equals(&other[i]) { return false } } @@ -219,154 +219,154 @@ func (a ApplicationSources) IsZero() bool { return len(a) == 0 } -func (a *ApplicationSpec) GetSource() ApplicationSource { - if a.SourceHydrator != nil { - return a.SourceHydrator.GetSyncSource() +func (spec *ApplicationSpec) GetSource() ApplicationSource { + if spec.SourceHydrator != nil { + return spec.SourceHydrator.GetSyncSource() } // if Application has multiple sources, return the first source in sources - if a.HasMultipleSources() { - return a.Sources[0] + if spec.HasMultipleSources() { + return spec.Sources[0] } - if a.Source != nil { - return *a.Source + if spec.Source != nil { + return *spec.Source } return ApplicationSource{} } // GetHydrateToSource returns the hydrateTo source if it exists, otherwise returns the sync source. -func (a *ApplicationSpec) GetHydrateToSource() ApplicationSource { - if a.SourceHydrator != nil { - targetRevision := a.SourceHydrator.SyncSource.TargetBranch - if a.SourceHydrator.HydrateTo != nil { - targetRevision = a.SourceHydrator.HydrateTo.TargetBranch +func (spec *ApplicationSpec) GetHydrateToSource() ApplicationSource { + if spec.SourceHydrator != nil { + targetRevision := spec.SourceHydrator.SyncSource.TargetBranch + if spec.SourceHydrator.HydrateTo != nil { + targetRevision = spec.SourceHydrator.HydrateTo.TargetBranch } return ApplicationSource{ - RepoURL: a.SourceHydrator.DrySource.RepoURL, - Path: a.SourceHydrator.SyncSource.Path, + RepoURL: spec.SourceHydrator.DrySource.RepoURL, + Path: spec.SourceHydrator.SyncSource.Path, TargetRevision: targetRevision, } } return ApplicationSource{} } -func (a *ApplicationSpec) GetSources() ApplicationSources { - if a.SourceHydrator != nil { - return ApplicationSources{a.SourceHydrator.GetSyncSource()} +func (spec *ApplicationSpec) GetSources() ApplicationSources { + if spec.SourceHydrator != nil { + return ApplicationSources{spec.SourceHydrator.GetSyncSource()} } - if a.HasMultipleSources() { - return a.Sources + if spec.HasMultipleSources() { + return spec.Sources } - if a.Source != nil { - return ApplicationSources{*a.Source} + if spec.Source != nil { + return ApplicationSources{*spec.Source} } return ApplicationSources{} } -func (a *ApplicationSpec) HasMultipleSources() bool { - return a.SourceHydrator == nil && len(a.Sources) > 0 +func (spec *ApplicationSpec) HasMultipleSources() bool { + return spec.SourceHydrator == nil && len(spec.Sources) > 0 } -func (a *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *ApplicationSource { +func (spec *ApplicationSpec) GetSourcePtrByPosition(sourcePosition int) *ApplicationSource { // if Application has multiple sources, return the first source in sources - return a.GetSourcePtrByIndex(sourcePosition - 1) + return spec.GetSourcePtrByIndex(sourcePosition - 1) } -func (a *ApplicationSpec) GetSourcePtrByIndex(sourceIndex int) *ApplicationSource { - if a.SourceHydrator != nil { - source := a.SourceHydrator.GetSyncSource() +func (spec *ApplicationSpec) GetSourcePtrByIndex(sourceIndex int) *ApplicationSource { + if spec.SourceHydrator != nil { + source := spec.SourceHydrator.GetSyncSource() return &source } // if Application has multiple sources, return the first source in sources - if a.HasMultipleSources() { + if spec.HasMultipleSources() { if sourceIndex > 0 { - return &a.Sources[sourceIndex] + return &spec.Sources[sourceIndex] } - return &a.Sources[0] + return &spec.Sources[0] } - return a.Source + return spec.Source } // AllowsConcurrentProcessing returns true if given application source can be processed concurrently -func (a *ApplicationSource) AllowsConcurrentProcessing() bool { +func (source *ApplicationSource) AllowsConcurrentProcessing() bool { switch { // Kustomize with parameters requires changing kustomization.yaml file - case a.Kustomize != nil: - return a.Kustomize.AllowsConcurrentProcessing() + case source.Kustomize != nil: + return source.Kustomize.AllowsConcurrentProcessing() } return true } // IsRef returns true when the application source is of type Ref -func (a *ApplicationSource) IsRef() bool { - return a.Ref != "" +func (source *ApplicationSource) IsRef() bool { + return source.Ref != "" } // IsHelm returns true when the application source is of type Helm -func (a *ApplicationSource) IsHelm() bool { - return a.Chart != "" +func (source *ApplicationSource) IsHelm() bool { + return source.Chart != "" } // IsHelmOci returns true when the application source is of type Helm OCI -func (a *ApplicationSource) IsHelmOci() bool { - if a.Chart == "" { +func (source *ApplicationSource) IsHelmOci() bool { + if source.Chart == "" { return false } - return helm.IsHelmOciRepo(a.RepoURL) + return helm.IsHelmOciRepo(source.RepoURL) } // IsZero returns true if the application source is considered empty -func (a *ApplicationSource) IsZero() bool { - return a == nil || - a.RepoURL == "" && - a.Path == "" && - a.TargetRevision == "" && - a.Helm.IsZero() && - a.Kustomize.IsZero() && - a.Directory.IsZero() && - a.Plugin.IsZero() +func (source *ApplicationSource) IsZero() bool { + return source == nil || + source.RepoURL == "" && + source.Path == "" && + source.TargetRevision == "" && + source.Helm.IsZero() && + source.Kustomize.IsZero() && + source.Directory.IsZero() && + source.Plugin.IsZero() } // GetNamespaceOrDefault gets the static namespace configured in the source. If none is configured, returns the given // default. -func (a *ApplicationSource) GetNamespaceOrDefault(defaultNamespace string) string { - if a == nil { +func (source *ApplicationSource) GetNamespaceOrDefault(defaultNamespace string) string { + if source == nil { return defaultNamespace } - if a.Helm != nil && a.Helm.Namespace != "" { - return a.Helm.Namespace + if source.Helm != nil && source.Helm.Namespace != "" { + return source.Helm.Namespace } - if a.Kustomize != nil && a.Kustomize.Namespace != "" { - return a.Kustomize.Namespace + if source.Kustomize != nil && source.Kustomize.Namespace != "" { + return source.Kustomize.Namespace } return defaultNamespace } // GetKubeVersionOrDefault gets the static Kubernetes API version configured in the source. If none is configured, // returns the given default. -func (a *ApplicationSource) GetKubeVersionOrDefault(defaultKubeVersion string) string { - if a == nil { +func (source *ApplicationSource) GetKubeVersionOrDefault(defaultKubeVersion string) string { + if source == nil { return defaultKubeVersion } - if a.Helm != nil && a.Helm.KubeVersion != "" { - return a.Helm.KubeVersion + if source.Helm != nil && source.Helm.KubeVersion != "" { + return source.Helm.KubeVersion } - if a.Kustomize != nil && a.Kustomize.KubeVersion != "" { - return a.Kustomize.KubeVersion + if source.Kustomize != nil && source.Kustomize.KubeVersion != "" { + return source.Kustomize.KubeVersion } return defaultKubeVersion } // GetAPIVersionsOrDefault gets the static API versions list configured in the source. If none is configured, returns // the given default. -func (a *ApplicationSource) GetAPIVersionsOrDefault(defaultAPIVersions []string) []string { - if a == nil { +func (source *ApplicationSource) GetAPIVersionsOrDefault(defaultAPIVersions []string) []string { + if source == nil { return defaultAPIVersions } - if a.Helm != nil && len(a.Helm.APIVersions) > 0 { - return a.Helm.APIVersions + if source.Helm != nil && len(source.Helm.APIVersions) > 0 { + return source.Helm.APIVersions } - if a.Kustomize != nil && len(a.Kustomize.APIVersions) > 0 { - return a.Kustomize.APIVersions + if source.Kustomize != nil && len(source.Kustomize.APIVersions) > 0 { + return source.Kustomize.APIVersions } return defaultAPIVersions } @@ -558,39 +558,39 @@ func NewHelmFileParameter(text string) (*HelmFileParameter, error) { // AddParameter adds a HelmParameter to the application source. If a parameter with the same name already // exists, its value will be overwritten. Otherwise, the HelmParameter will be appended as a new entry. -func (in *ApplicationSourceHelm) AddParameter(p HelmParameter) { +func (ash *ApplicationSourceHelm) AddParameter(p HelmParameter) { found := false - for i, cp := range in.Parameters { + for i, cp := range ash.Parameters { if cp.Name == p.Name { found = true - in.Parameters[i] = p + ash.Parameters[i] = p break } } if !found { - in.Parameters = append(in.Parameters, p) + ash.Parameters = append(ash.Parameters, p) } } // AddFileParameter adds a HelmFileParameter to the application source. If a file parameter with the same name already // exists, its value will be overwritten. Otherwise, the HelmFileParameter will be appended as a new entry. -func (in *ApplicationSourceHelm) AddFileParameter(p HelmFileParameter) { +func (ash *ApplicationSourceHelm) AddFileParameter(p HelmFileParameter) { found := false - for i, cp := range in.FileParameters { + for i, cp := range ash.FileParameters { if cp.Name == p.Name { found = true - in.FileParameters[i] = p + ash.FileParameters[i] = p break } } if !found { - in.FileParameters = append(in.FileParameters, p) + ash.FileParameters = append(ash.FileParameters, p) } } // IsZero Returns true if the Helm options in an application source are considered zero -func (h *ApplicationSourceHelm) IsZero() bool { - return h == nil || (h.Version == "") && (h.ReleaseName == "") && len(h.ValueFiles) == 0 && len(h.Parameters) == 0 && len(h.FileParameters) == 0 && h.ValuesIsEmpty() && !h.PassCredentials && !h.IgnoreMissingValueFiles && !h.SkipCrds && !h.SkipTests && !h.SkipSchemaValidation && h.KubeVersion == "" && len(h.APIVersions) == 0 && h.Namespace == "" +func (ash *ApplicationSourceHelm) IsZero() bool { + return ash == nil || (ash.Version == "") && (ash.ReleaseName == "") && len(ash.ValueFiles) == 0 && len(ash.Parameters) == 0 && len(ash.FileParameters) == 0 && ash.ValuesIsEmpty() && !ash.PassCredentials && !ash.IgnoreMissingValueFiles && !ash.SkipCrds && !ash.SkipTests && !ash.SkipSchemaValidation && ash.KubeVersion == "" && len(ash.APIVersions) == 0 && ash.Namespace == "" } // KustomizeImage represents a Kustomize image definition in the format [old_image_name=]: @@ -1169,9 +1169,9 @@ type SourceHydratorStatus struct { CurrentOperation *HydrateOperation `json:"currentOperation,omitempty" protobuf:"bytes,2,opt,name=currentOperation"` } -func (a *ApplicationStatus) FindResource(key kube.ResourceKey) (*ResourceStatus, bool) { - for i := range a.Resources { - res := a.Resources[i] +func (status *ApplicationStatus) FindResource(key kube.ResourceKey) (*ResourceStatus, bool) { + for i := range status.Resources { + res := status.Resources[i] if kube.NewResourceKey(res.Group, res.Kind, res.Namespace, res.Name) == key { return &res, true } @@ -1221,12 +1221,12 @@ const ( // If app has multisources, it will return all corresponding revisions preserving // order from the app.spec.sources. If app has only one source, it will return a // single revision in the list. -func (a *ApplicationStatus) GetRevisions() []string { +func (status *ApplicationStatus) GetRevisions() []string { revisions := []string{} - if len(a.Sync.Revisions) > 0 { - revisions = a.Sync.Revisions - } else if a.Sync.Revision != "" { - revisions = append(revisions, a.Sync.Revision) + if len(status.Sync.Revisions) > 0 { + revisions = status.Sync.Revisions + } else if status.Sync.Revision != "" { + revisions = append(revisions, status.Sync.Revision) } return revisions } @@ -2288,20 +2288,20 @@ type ResourceOverride struct { } // TODO: describe this method -func (s *ResourceOverride) UnmarshalJSON(data []byte) error { +func (ro *ResourceOverride) UnmarshalJSON(data []byte) error { raw := &rawResourceOverride{} if err := json.Unmarshal(data, &raw); err != nil { return err } - s.KnownTypeFields = raw.KnownTypeFields - s.HealthLua = raw.HealthLua - s.UseOpenLibs = raw.UseOpenLibs - s.Actions = raw.Actions - err := yaml.Unmarshal([]byte(raw.IgnoreDifferences), &s.IgnoreDifferences) + ro.KnownTypeFields = raw.KnownTypeFields + ro.HealthLua = raw.HealthLua + ro.UseOpenLibs = raw.UseOpenLibs + ro.Actions = raw.Actions + err := yaml.Unmarshal([]byte(raw.IgnoreDifferences), &ro.IgnoreDifferences) if err != nil { return err } - err = yaml.Unmarshal([]byte(raw.IgnoreResourceUpdates), &s.IgnoreResourceUpdates) + err = yaml.Unmarshal([]byte(raw.IgnoreResourceUpdates), &ro.IgnoreResourceUpdates) if err != nil { return err } @@ -2309,23 +2309,23 @@ func (s *ResourceOverride) UnmarshalJSON(data []byte) error { } // TODO: describe this method -func (s ResourceOverride) MarshalJSON() ([]byte, error) { - ignoreDifferencesData, err := yaml.Marshal(s.IgnoreDifferences) +func (ro ResourceOverride) MarshalJSON() ([]byte, error) { + ignoreDifferencesData, err := yaml.Marshal(ro.IgnoreDifferences) if err != nil { return nil, err } - ignoreResourceUpdatesData, err := yaml.Marshal(s.IgnoreResourceUpdates) + ignoreResourceUpdatesData, err := yaml.Marshal(ro.IgnoreResourceUpdates) if err != nil { return nil, err } - raw := &rawResourceOverride{s.HealthLua, s.UseOpenLibs, s.Actions, string(ignoreDifferencesData), string(ignoreResourceUpdatesData), s.KnownTypeFields} + raw := &rawResourceOverride{ro.HealthLua, ro.UseOpenLibs, ro.Actions, string(ignoreDifferencesData), string(ignoreResourceUpdatesData), ro.KnownTypeFields} return json.Marshal(raw) } // TODO: describe this method -func (o *ResourceOverride) GetActions() (ResourceActions, error) { +func (ro *ResourceOverride) GetActions() (ResourceActions, error) { var actions ResourceActions - err := yaml.Unmarshal([]byte(o.Actions), &actions) + err := yaml.Unmarshal([]byte(ro.Actions), &actions) if err != nil { return actions, err } @@ -2565,24 +2565,24 @@ type SyncWindow struct { } // HasWindows returns true if SyncWindows has one or more SyncWindow -func (s *SyncWindows) HasWindows() bool { - return s != nil && len(*s) > 0 +func (w *SyncWindows) HasWindows() bool { + return w != nil && len(*w) > 0 } // Active returns a list of sync windows that are currently active -func (s *SyncWindows) Active() (*SyncWindows, error) { - return s.active(time.Now()) +func (w *SyncWindows) Active() (*SyncWindows, error) { + return w.active(time.Now()) } -func (s *SyncWindows) active(currentTime time.Time) (*SyncWindows, error) { +func (w *SyncWindows) active(currentTime time.Time) (*SyncWindows, error) { // If SyncWindows.Active() is called outside of a UTC locale, it should be // first converted to UTC before we scan through the SyncWindows. currentTime = currentTime.In(time.UTC) - if s.HasWindows() { + if w.HasWindows() { var active SyncWindows specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - for _, w := range *s { + for _, w := range *w { schedule, sErr := specParser.Parse(w.Schedule) if sErr != nil { return nil, fmt.Errorf("cannot parse schedule '%s': %w", w.Schedule, sErr) @@ -2609,19 +2609,19 @@ func (s *SyncWindows) active(currentTime time.Time) (*SyncWindows, error) { // InactiveAllows will iterate over the SyncWindows and return all inactive allow windows // for the current time. If the current time is in an inactive allow window, syncs will // be denied. -func (s *SyncWindows) InactiveAllows() (*SyncWindows, error) { - return s.inactiveAllows(time.Now()) +func (w *SyncWindows) InactiveAllows() (*SyncWindows, error) { + return w.inactiveAllows(time.Now()) } -func (s *SyncWindows) inactiveAllows(currentTime time.Time) (*SyncWindows, error) { +func (w *SyncWindows) inactiveAllows(currentTime time.Time) (*SyncWindows, error) { // If SyncWindows.InactiveAllows() is called outside of a UTC locale, it should be // first converted to UTC before we scan through the SyncWindows. currentTime = currentTime.In(time.UTC) - if s.HasWindows() { + if w.HasWindows() { var inactive SyncWindows specParser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) - for _, w := range *s { + for _, w := range *w { if w.Kind == "allow" { schedule, sErr := specParser.Parse(w.Schedule) if sErr != nil { @@ -2658,7 +2658,7 @@ func (w *SyncWindow) scheduleOffsetByTimeZone() time.Duration { } // AddWindow adds a sync window with the given parameters to the AppProject -func (s *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []string, ns []string, cl []string, ms bool, timeZone string) error { +func (spec *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []string, ns []string, cl []string, ms bool, timeZone string) error { if len(knd) == 0 || len(sch) == 0 || len(dur) == 0 { return errors.New("cannot create window: require kind, schedule, duration and one or more of applications, namespaces and clusters") } @@ -2686,18 +2686,18 @@ func (s *AppProjectSpec) AddWindow(knd string, sch string, dur string, app []str return err } - s.SyncWindows = append(s.SyncWindows, window) + spec.SyncWindows = append(spec.SyncWindows, window) return nil } // DeleteWindow deletes a sync window with the given id from the AppProject -func (s *AppProjectSpec) DeleteWindow(id int) error { +func (spec *AppProjectSpec) DeleteWindow(id int) error { var exists bool - for i := range s.SyncWindows { + for i := range spec.SyncWindows { if i == id { exists = true - s.SyncWindows = append(s.SyncWindows[:i], s.SyncWindows[i+1:]...) + spec.SyncWindows = append(spec.SyncWindows[:i], spec.SyncWindows[i+1:]...) break } } @@ -2921,10 +2921,10 @@ func (w *SyncWindow) Validate() error { } // DestinationClusters returns a list of cluster URLs allowed as destination in an AppProject -func (d AppProjectSpec) DestinationClusters() []string { +func (spec AppProjectSpec) DestinationClusters() []string { servers := make([]string, 0) - for _, d := range d.Destinations { + for _, d := range spec.Destinations { servers = append(servers, d.Server) } @@ -3214,12 +3214,12 @@ func (source *ApplicationSource) ExplicitType() (*ApplicationSourceType, error) } // Equals compares two instances of ApplicationDestination and returns true if instances are equal. -func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { +func (d ApplicationDestination) Equals(other ApplicationDestination) bool { // ignore destination cluster name and isServerInferred fields during comparison // since server URL is inferred from cluster name - if dest.isServerInferred { - dest.Server = "" - dest.isServerInferred = false + if d.isServerInferred { + d.Server = "" + d.isServerInferred = false } if other.isServerInferred { @@ -3227,9 +3227,9 @@ func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { other.isServerInferred = false } - if dest.isNameInferred { - dest.Name = "" - dest.isNameInferred = false + if d.isNameInferred { + d.Name = "" + d.isNameInferred = false } if other.isNameInferred { @@ -3237,7 +3237,7 @@ func (dest ApplicationDestination) Equals(other ApplicationDestination) bool { other.isNameInferred = false } - return reflect.DeepEqual(dest, other) + return reflect.DeepEqual(d, other) } // GetProject returns the application's project. This is preferred over spec.Project which may be empty @@ -3539,37 +3539,37 @@ func (d *ApplicationDestination) MarshalJSON() ([]byte, error) { // tracking values, i.e. in the format _. When the namespace // of the application is similar to the value of defaultNs, only the name of // the application is returned to keep backwards compatibility. -func (a *Application) InstanceName(defaultNs string) string { +func (app *Application) InstanceName(defaultNs string) string { // When app has no namespace set, or the namespace is the default ns, we // return just the application name - if a.Namespace == "" || a.Namespace == defaultNs { - return a.Name + if app.Namespace == "" || app.Namespace == defaultNs { + return app.Name } - return a.Namespace + "_" + a.Name + return app.Namespace + "_" + app.Name } // QualifiedName returns the full qualified name of the application, including // the name of the namespace it is created in delimited by a forward slash, // i.e. / -func (a *Application) QualifiedName() string { - if a.Namespace == "" { - return a.Name +func (app *Application) QualifiedName() string { + if app.Namespace == "" { + return app.Name } else { - return a.Namespace + "/" + a.Name + return app.Namespace + "/" + app.Name } } // RBACName returns the full qualified RBAC resource name for the application // in a backwards-compatible way. -func (a *Application) RBACName(defaultNS string) string { - return security.RBACName(defaultNS, a.Spec.GetProject(), a.Namespace, a.Name) +func (app *Application) RBACName(defaultNS string) string { + return security.RBACName(defaultNS, app.Spec.GetProject(), app.Namespace, app.Name) } // GetAnnotation returns the value of the specified annotation if it exists, // e.g., a.GetAnnotation("argocd.argoproj.io/manifest-generate-paths"). // If the annotation does not exist, it returns an empty string. -func (a *Application) GetAnnotation(annotation string) string { - v, exists := a.Annotations[annotation] +func (app *Application) GetAnnotation(annotation string) string { + v, exists := app.Annotations[annotation] if !exists { return "" } @@ -3577,8 +3577,8 @@ func (a *Application) GetAnnotation(annotation string) string { return v } -func (a *Application) IsDeletionConfirmed(since time.Time) bool { - val := a.GetAnnotation(synccommon.AnnotationDeletionApproved) +func (app *Application) IsDeletionConfirmed(since time.Time) bool { + val := app.GetAnnotation(synccommon.AnnotationDeletionApproved) if val == "" { return false } diff --git a/server/server.go b/server/server.go index c3ef5ef0ea5c4..b9c0e412dab2c 100644 --- a/server/server.go +++ b/server/server.go @@ -392,15 +392,15 @@ const ( notObjectErrMsg = "object does not implement the Object interfaces" ) -func (a *ArgoCDServer) healthCheck(r *http.Request) error { - if a.terminateRequested.Load() { +func (server *ArgoCDServer) healthCheck(r *http.Request) error { + if server.terminateRequested.Load() { return errors.New("API Server is terminating and unable to serve requests.") } - if !a.available.Load() { + if !server.available.Load() { return errors.New("API Server is not available. It either hasn't started or is restarting.") } if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" { - argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) + argoDB := db.NewDB(server.Namespace, server.settingsMgr, server.KubeClientset) _, err := argoDB.ListClusters(r.Context()) if err != nil && strings.Contains(err.Error(), notObjectErrMsg) { return err @@ -438,18 +438,18 @@ func (l *Listeners) Close() error { } // logInClusterWarnings checks the in-cluster configuration and prints out any warnings. -func (a *ArgoCDServer) logInClusterWarnings() error { +func (server *ArgoCDServer) logInClusterWarnings() error { labelSelector := labels.NewSelector() req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, []string{common.LabelValueSecretTypeCluster}) if err != nil { return fmt.Errorf("failed to construct cluster-type label selector: %w", err) } labelSelector = labelSelector.Add(*req) - secretsLister, err := a.settingsMgr.GetSecretsLister() + secretsLister, err := server.settingsMgr.GetSecretsLister() if err != nil { return fmt.Errorf("failed to get secrets lister: %w", err) } - clusterSecrets, err := secretsLister.Secrets(a.ArgoCDServerOpts.Namespace).List(labelSelector) + clusterSecrets, err := secretsLister.Secrets(server.ArgoCDServerOpts.Namespace).List(labelSelector) if err != nil { return fmt.Errorf("failed to list cluster secrets: %w", err) } @@ -465,7 +465,7 @@ func (a *ArgoCDServer) logInClusterWarnings() error { } if len(inClusterSecrets) > 0 { // Don't make this call unless we actually have in-cluster secrets, to save time. - dbSettings, err := a.settingsMgr.GetSettings() + dbSettings, err := server.settingsMgr.GetSettings() if err != nil { return fmt.Errorf("could not get DB settings: %w", err) } @@ -491,12 +491,12 @@ func startListener(host string, port int) (net.Listener, error) { return conn, realErr } -func (a *ArgoCDServer) Listen() (*Listeners, error) { - mainLn, err := startListener(a.ListenHost, a.ListenPort) +func (server *ArgoCDServer) Listen() (*Listeners, error) { + mainLn, err := startListener(server.ListenHost, server.ListenPort) if err != nil { return nil, err } - metricsLn, err := startListener(a.ListenHost, a.MetricsPort) + metricsLn, err := startListener(server.ListenHost, server.MetricsPort) if err != nil { io.Close(mainLn) return nil, err @@ -506,14 +506,14 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) { dOpts = append(dOpts, grpc.WithUserAgent(fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, common.GetVersion().Version))) dOpts = append(dOpts, grpc.WithUnaryInterceptor(grpc_util.OTELUnaryClientInterceptor())) dOpts = append(dOpts, grpc.WithStreamInterceptor(grpc_util.OTELStreamClientInterceptor())) - if a.useTLS() { + if server.useTLS() { // The following sets up the dial Options for grpc-gateway to talk to gRPC server over TLS. // grpc-gateway is just translating HTTP/HTTPS requests as gRPC requests over localhost, // so we need to supply the same certificates to establish the connections that a normal, // external gRPC client would need. - tlsConfig := a.settings.TLSConfig() - if a.TLSConfigCustomizer != nil { - a.TLSConfigCustomizer(tlsConfig) + tlsConfig := server.settings.TLSConfig() + if server.TLSConfigCustomizer != nil { + server.TLSConfigCustomizer(tlsConfig) } tlsConfig.InsecureSkipVerify = true dCreds := credentials.NewTLS(tlsConfig) @@ -522,7 +522,7 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) { dOpts = append(dOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } // nolint:staticcheck - conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", a.ListenPort), dOpts...) + conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", server.ListenPort), dOpts...) if err != nil { io.Close(mainLn) io.Close(metricsLn) @@ -532,51 +532,51 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) { } // Init starts informers used by the API server -func (a *ArgoCDServer) Init(ctx context.Context) { - go a.projInformer.Run(ctx.Done()) - go a.appInformer.Run(ctx.Done()) - go a.appsetInformer.Run(ctx.Done()) - go a.configMapInformer.Run(ctx.Done()) - go a.secretInformer.Run(ctx.Done()) +func (server *ArgoCDServer) Init(ctx context.Context) { + go server.projInformer.Run(ctx.Done()) + go server.appInformer.Run(ctx.Done()) + go server.appsetInformer.Run(ctx.Done()) + go server.configMapInformer.Run(ctx.Done()) + go server.secretInformer.Run(ctx.Done()) } // Run runs the API Server // We use k8s.io/code-generator/cmd/go-to-protobuf to generate the .proto files from the API types. // k8s.io/ go-to-protobuf uses protoc-gen-gogo, which comes from gogo/protobuf (a fork of // golang/protobuf). -func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { +func (server *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { defer func() { if r := recover(); r != nil { log.WithField("trace", string(debug.Stack())).Error("Recovered from panic: ", r) - a.terminateRequested.Store(true) - a.shutdown() + server.terminateRequested.Store(true) + server.shutdown() } }() - a.userStateStorage.Init(ctx) + server.userStateStorage.Init(ctx) - metricsServ := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) - if a.RedisClient != nil { - cacheutil.CollectMetrics(a.RedisClient, metricsServ, a.userStateStorage.GetLockObject()) + metricsServ := metrics.NewMetricsServer(server.MetricsHost, server.MetricsPort) + if server.RedisClient != nil { + cacheutil.CollectMetrics(server.RedisClient, metricsServ, server.userStateStorage.GetLockObject()) } - svcSet := newArgoCDServiceSet(a) - a.serviceSet = svcSet - grpcS, appResourceTreeFn := a.newGRPCServer() + svcSet := newArgoCDServiceSet(server) + server.serviceSet = svcSet + grpcS, appResourceTreeFn := server.newGRPCServer() grpcWebS := grpcweb.WrapServer(grpcS) var httpS *http.Server var httpsS *http.Server - if a.useTLS() { - httpS = newRedirectServer(a.ListenPort, a.RootPath) - httpsS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) + if server.useTLS() { + httpS = newRedirectServer(server.ListenPort, server.RootPath) + httpsS = server.newHTTPServer(ctx, server.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } else { - httpS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) + httpS = server.newHTTPServer(ctx, server.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } - if a.RootPath != "" { - httpS.Handler = withRootPath(httpS.Handler, a) + if server.RootPath != "" { + httpS.Handler = withRootPath(httpS.Handler, server) if httpsS != nil { - httpsS.Handler = withRootPath(httpsS.Handler, a) + httpsS.Handler = withRootPath(httpsS.Handler, server) } } httpS.Handler = &bug21955Workaround{handler: httpS.Handler} @@ -590,7 +590,7 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { var grpcL net.Listener var httpL net.Listener var httpsL net.Listener - if !a.useTLS() { + if !server.useTLS() { httpL = tcpm.Match(cmux.HTTP1Fast("PATCH")) grpcL = tcpm.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) } else { @@ -607,10 +607,10 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { NextProtos: []string{"http/1.1", "h2"}, } tlsConfig.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - return a.settings.Certificate, nil + return server.settings.Certificate, nil } - if a.TLSConfigCustomizer != nil { - a.TLSConfigCustomizer(&tlsConfig) + if server.TLSConfigCustomizer != nil { + server.TLSConfigCustomizer(&tlsConfig) } tlsl = tls.NewListener(tlsl, &tlsConfig) @@ -622,26 +622,26 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { // Start the muxed listeners for our servers log.Infof("argocd %s serving on port %d (url: %s, tls: %v, namespace: %s, sso: %v)", - common.GetVersion(), a.ListenPort, a.settings.URL, a.useTLS(), a.Namespace, a.settings.IsSSOConfigured()) - log.Infof("Enabled application namespace patterns: %s", a.allowedApplicationNamespacesAsString()) - - go func() { a.checkServeErr("grpcS", grpcS.Serve(grpcL)) }() - go func() { a.checkServeErr("httpS", httpS.Serve(httpL)) }() - if a.useTLS() { - go func() { a.checkServeErr("httpsS", httpsS.Serve(httpsL)) }() - go func() { a.checkServeErr("tlsm", tlsm.Serve()) }() - } - go a.watchSettings() - go a.rbacPolicyLoader(ctx) - go func() { a.checkServeErr("tcpm", tcpm.Serve()) }() - go func() { a.checkServeErr("metrics", metricsServ.Serve(listeners.Metrics)) }() - if !cache.WaitForCacheSync(ctx.Done(), a.projInformer.HasSynced, a.appInformer.HasSynced) { + common.GetVersion(), server.ListenPort, server.settings.URL, server.useTLS(), server.Namespace, server.settings.IsSSOConfigured()) + log.Infof("Enabled application namespace patterns: %s", server.allowedApplicationNamespacesAsString()) + + go func() { server.checkServeErr("grpcS", grpcS.Serve(grpcL)) }() + go func() { server.checkServeErr("httpS", httpS.Serve(httpL)) }() + if server.useTLS() { + go func() { server.checkServeErr("httpsS", httpsS.Serve(httpsL)) }() + go func() { server.checkServeErr("tlsm", tlsm.Serve()) }() + } + go server.watchSettings() + go server.rbacPolicyLoader(ctx) + go func() { server.checkServeErr("tcpm", tcpm.Serve()) }() + go func() { server.checkServeErr("metrics", metricsServ.Serve(listeners.Metrics)) }() + if !cache.WaitForCacheSync(ctx.Done(), server.projInformer.HasSynced, server.appInformer.HasSynced) { log.Fatal("Timed out waiting for project cache to sync") } shutdownFunc := func() { log.Info("API Server shutdown initiated. Shutting down servers...") - a.available.Store(false) + server.available.Store(false) shutdownCtx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() var wg gosync.WaitGroup @@ -656,7 +656,7 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { } }() - if a.useTLS() { + if server.useTLS() { // Shutdown https server wg.Add(1) go func() { @@ -685,7 +685,7 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { } }() - if a.useTLS() { + if server.useTLS() { // Shutdown tls server wg.Add(1) go func() { @@ -716,37 +716,37 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { log.Warn("Graceful shutdown timeout. Exiting...") } } - a.shutdown = shutdownFunc - signal.Notify(a.stopCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - a.available.Store(true) + server.shutdown = shutdownFunc + signal.Notify(server.stopCh, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + server.available.Store(true) select { - case signal := <-a.stopCh: + case signal := <-server.stopCh: log.Infof("API Server received signal: %s", signal.String()) gracefulRestartSignal := GracefulRestartSignal{} if signal != gracefulRestartSignal { - a.terminateRequested.Store(true) + server.terminateRequested.Store(true) } - a.shutdown() + server.shutdown() case <-ctx.Done(): log.Infof("API Server: %s", ctx.Err()) - a.terminateRequested.Store(true) - a.shutdown() + server.terminateRequested.Store(true) + server.shutdown() } } -func (a *ArgoCDServer) Initialized() bool { - return a.projInformer.HasSynced() && a.appInformer.HasSynced() +func (server *ArgoCDServer) Initialized() bool { + return server.projInformer.HasSynced() && server.appInformer.HasSynced() } // TerminateRequested returns whether a shutdown was initiated by a signal or context cancel // as opposed to a watch. -func (a *ArgoCDServer) TerminateRequested() bool { - return a.terminateRequested.Load() +func (server *ArgoCDServer) TerminateRequested() bool { + return server.terminateRequested.Load() } // checkServeErr checks the error from a .Serve() call to decide if it was a graceful shutdown -func (a *ArgoCDServer) checkServeErr(name string, err error) { +func (server *ArgoCDServer) checkServeErr(name string, err error) { if err != nil && !errors.Is(err, http.ErrServerClosed) { log.Errorf("Error received from server %s: %v", name, err) } else { @@ -772,81 +772,81 @@ func checkOIDCConfigChange(currentOIDCConfig *settings_util.OIDCConfig, newArgoC // watchSettings watches the configmap and secret for any setting updates that would warrant a // restart of the API server. -func (a *ArgoCDServer) watchSettings() { +func (server *ArgoCDServer) watchSettings() { updateCh := make(chan *settings_util.ArgoCDSettings, 1) - a.settingsMgr.Subscribe(updateCh) + server.settingsMgr.Subscribe(updateCh) - prevURL := a.settings.URL - prevAdditionalURLs := a.settings.AdditionalURLs - prevOIDCConfig := a.settings.OIDCConfig() - prevDexCfgBytes, err := dexutil.GenerateDexConfigYAML(a.settings, a.DexTLSConfig == nil || a.DexTLSConfig.DisableTLS) + prevURL := server.settings.URL + prevAdditionalURLs := server.settings.AdditionalURLs + prevOIDCConfig := server.settings.OIDCConfig() + prevDexCfgBytes, err := dexutil.GenerateDexConfigYAML(server.settings, server.DexTLSConfig == nil || server.DexTLSConfig.DisableTLS) errorsutil.CheckError(err) - prevGitHubSecret := a.settings.WebhookGitHubSecret - prevGitLabSecret := a.settings.WebhookGitLabSecret - prevBitbucketUUID := a.settings.WebhookBitbucketUUID - prevBitbucketServerSecret := a.settings.WebhookBitbucketServerSecret - prevGogsSecret := a.settings.WebhookGogsSecret - prevExtConfig := a.settings.ExtensionConfig + prevGitHubSecret := server.settings.WebhookGitHubSecret + prevGitLabSecret := server.settings.WebhookGitLabSecret + prevBitbucketUUID := server.settings.WebhookBitbucketUUID + prevBitbucketServerSecret := server.settings.WebhookBitbucketServerSecret + prevGogsSecret := server.settings.WebhookGogsSecret + prevExtConfig := server.settings.ExtensionConfig var prevCert, prevCertKey string - if a.settings.Certificate != nil && !a.ArgoCDServerOpts.Insecure { - prevCert, prevCertKey = tlsutil.EncodeX509KeyPairString(*a.settings.Certificate) + if server.settings.Certificate != nil && !server.ArgoCDServerOpts.Insecure { + prevCert, prevCertKey = tlsutil.EncodeX509KeyPairString(*server.settings.Certificate) } for { newSettings := <-updateCh - a.settings = newSettings - newDexCfgBytes, err := dexutil.GenerateDexConfigYAML(a.settings, a.DexTLSConfig == nil || a.DexTLSConfig.DisableTLS) + server.settings = newSettings + newDexCfgBytes, err := dexutil.GenerateDexConfigYAML(server.settings, server.DexTLSConfig == nil || server.DexTLSConfig.DisableTLS) errorsutil.CheckError(err) if string(newDexCfgBytes) != string(prevDexCfgBytes) { log.Infof("dex config modified. restarting") break } - if checkOIDCConfigChange(prevOIDCConfig, a.settings) { + if checkOIDCConfigChange(prevOIDCConfig, server.settings) { log.Infof("oidc config modified. restarting") break } - if prevURL != a.settings.URL { + if prevURL != server.settings.URL { log.Infof("url modified. restarting") break } - if !reflect.DeepEqual(prevAdditionalURLs, a.settings.AdditionalURLs) { + if !reflect.DeepEqual(prevAdditionalURLs, server.settings.AdditionalURLs) { log.Infof("additionalURLs modified. restarting") break } - if prevGitHubSecret != a.settings.WebhookGitHubSecret { + if prevGitHubSecret != server.settings.WebhookGitHubSecret { log.Infof("github secret modified. restarting") break } - if prevGitLabSecret != a.settings.WebhookGitLabSecret { + if prevGitLabSecret != server.settings.WebhookGitLabSecret { log.Infof("gitlab secret modified. restarting") break } - if prevBitbucketUUID != a.settings.WebhookBitbucketUUID { + if prevBitbucketUUID != server.settings.WebhookBitbucketUUID { log.Infof("bitbucket uuid modified. restarting") break } - if prevBitbucketServerSecret != a.settings.WebhookBitbucketServerSecret { + if prevBitbucketServerSecret != server.settings.WebhookBitbucketServerSecret { log.Infof("bitbucket server secret modified. restarting") break } - if prevGogsSecret != a.settings.WebhookGogsSecret { + if prevGogsSecret != server.settings.WebhookGogsSecret { log.Infof("gogs secret modified. restarting") break } - if !reflect.DeepEqual(prevExtConfig, a.settings.ExtensionConfig) { - prevExtConfig = a.settings.ExtensionConfig + if !reflect.DeepEqual(prevExtConfig, server.settings.ExtensionConfig) { + prevExtConfig = server.settings.ExtensionConfig log.Infof("extensions configs modified. Updating proxy registry...") - err := a.extensionManager.UpdateExtensionRegistry(a.settings) + err := server.extensionManager.UpdateExtensionRegistry(server.settings) if err != nil { log.Errorf("error updating extensions configs: %s", err) } else { log.Info("extensions configs updated successfully") } } - if !a.ArgoCDServerOpts.Insecure { + if !server.ArgoCDServerOpts.Insecure { var newCert, newCertKey string - if a.settings.Certificate != nil { - newCert, newCertKey = tlsutil.EncodeX509KeyPairString(*a.settings.Certificate) + if server.settings.Certificate != nil { + newCert, newCertKey = tlsutil.EncodeX509KeyPairString(*server.settings.Certificate) } if newCert != prevCert || newCertKey != prevCertKey { log.Infof("tls certificate modified. reloading certificate") @@ -855,14 +855,14 @@ func (a *ArgoCDServer) watchSettings() { } } log.Info("shutting down settings watch") - a.settingsMgr.Unsubscribe(updateCh) + server.settingsMgr.Unsubscribe(updateCh) close(updateCh) // Triggers server restart - a.stopCh <- GracefulRestartSignal{} + server.stopCh <- GracefulRestartSignal{} } -func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { - err := a.enf.RunPolicyLoader(ctx, func(cm *corev1.ConfigMap) error { +func (server *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { + err := server.enf.RunPolicyLoader(ctx, func(cm *corev1.ConfigMap) error { var scopes []string if scopesStr, ok := cm.Data[rbac.ConfigMapScopesKey]; len(scopesStr) > 0 && ok { scopes = make([]string, 0) @@ -872,20 +872,20 @@ func (a *ArgoCDServer) rbacPolicyLoader(ctx context.Context) { } } - a.policyEnforcer.SetScopes(scopes) + server.policyEnforcer.SetScopes(scopes) return nil }) errorsutil.CheckError(err) } -func (a *ArgoCDServer) useTLS() bool { - if a.Insecure || a.settings.Certificate == nil { +func (server *ArgoCDServer) useTLS() bool { + if server.Insecure || server.settings.Certificate == nil { return false } return true } -func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTreeFn) { +func (server *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTreeFn) { if enableGRPCTimeHistogram { grpc_prometheus.EnableHandlingTimeHistogram() } @@ -929,51 +929,51 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre // This is because TLS handshaking occurs in cmux handling sOpts = append(sOpts, grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( otelgrpc.StreamServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - grpc_logrus.StreamServerInterceptor(a.log), + grpc_logrus.StreamServerInterceptor(server.log), grpc_prometheus.StreamServerInterceptor, - grpc_auth.StreamServerInterceptor(a.Authenticate), + grpc_auth.StreamServerInterceptor(server.Authenticate), grpc_util.UserAgentStreamServerInterceptor(common.ArgoCDUserAgentName, clientConstraint), - grpc_util.PayloadStreamServerInterceptor(a.log, true, func(ctx context.Context, fullMethodName string, servingObject any) bool { + grpc_util.PayloadStreamServerInterceptor(server.log, true, func(ctx context.Context, fullMethodName string, servingObject any) bool { return !sensitiveMethods[fullMethodName] }), grpc_util.ErrorCodeK8sStreamServerInterceptor(), grpc_util.ErrorCodeGitStreamServerInterceptor(), - grpc_util.PanicLoggerStreamServerInterceptor(a.log), + grpc_util.PanicLoggerStreamServerInterceptor(server.log), ))) sOpts = append(sOpts, grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( bug21955WorkaroundInterceptor, otelgrpc.UnaryServerInterceptor(), //nolint:staticcheck // TODO: ignore SA1019 for depreciation: see https://github.com/argoproj/argo-cd/issues/18258 - grpc_logrus.UnaryServerInterceptor(a.log), + grpc_logrus.UnaryServerInterceptor(server.log), grpc_prometheus.UnaryServerInterceptor, - grpc_auth.UnaryServerInterceptor(a.Authenticate), + grpc_auth.UnaryServerInterceptor(server.Authenticate), grpc_util.UserAgentUnaryServerInterceptor(common.ArgoCDUserAgentName, clientConstraint), - grpc_util.PayloadUnaryServerInterceptor(a.log, true, func(ctx context.Context, fullMethodName string, servingObject any) bool { + grpc_util.PayloadUnaryServerInterceptor(server.log, true, func(ctx context.Context, fullMethodName string, servingObject any) bool { return !sensitiveMethods[fullMethodName] }), grpc_util.ErrorCodeK8sUnaryServerInterceptor(), grpc_util.ErrorCodeGitUnaryServerInterceptor(), - grpc_util.PanicLoggerUnaryServerInterceptor(a.log), + grpc_util.PanicLoggerUnaryServerInterceptor(server.log), ))) grpcS := grpc.NewServer(sOpts...) - versionpkg.RegisterVersionServiceServer(grpcS, a.serviceSet.VersionService) - clusterpkg.RegisterClusterServiceServer(grpcS, a.serviceSet.ClusterService) - applicationpkg.RegisterApplicationServiceServer(grpcS, a.serviceSet.ApplicationService) - applicationsetpkg.RegisterApplicationSetServiceServer(grpcS, a.serviceSet.ApplicationSetService) - notificationpkg.RegisterNotificationServiceServer(grpcS, a.serviceSet.NotificationService) - repositorypkg.RegisterRepositoryServiceServer(grpcS, a.serviceSet.RepoService) - repocredspkg.RegisterRepoCredsServiceServer(grpcS, a.serviceSet.RepoCredsService) - sessionpkg.RegisterSessionServiceServer(grpcS, a.serviceSet.SessionService) - settingspkg.RegisterSettingsServiceServer(grpcS, a.serviceSet.SettingsService) - projectpkg.RegisterProjectServiceServer(grpcS, a.serviceSet.ProjectService) - accountpkg.RegisterAccountServiceServer(grpcS, a.serviceSet.AccountService) - certificatepkg.RegisterCertificateServiceServer(grpcS, a.serviceSet.CertificateService) - gpgkeypkg.RegisterGPGKeyServiceServer(grpcS, a.serviceSet.GpgkeyService) + versionpkg.RegisterVersionServiceServer(grpcS, server.serviceSet.VersionService) + clusterpkg.RegisterClusterServiceServer(grpcS, server.serviceSet.ClusterService) + applicationpkg.RegisterApplicationServiceServer(grpcS, server.serviceSet.ApplicationService) + applicationsetpkg.RegisterApplicationSetServiceServer(grpcS, server.serviceSet.ApplicationSetService) + notificationpkg.RegisterNotificationServiceServer(grpcS, server.serviceSet.NotificationService) + repositorypkg.RegisterRepositoryServiceServer(grpcS, server.serviceSet.RepoService) + repocredspkg.RegisterRepoCredsServiceServer(grpcS, server.serviceSet.RepoCredsService) + sessionpkg.RegisterSessionServiceServer(grpcS, server.serviceSet.SessionService) + settingspkg.RegisterSettingsServiceServer(grpcS, server.serviceSet.SettingsService) + projectpkg.RegisterProjectServiceServer(grpcS, server.serviceSet.ProjectService) + accountpkg.RegisterAccountServiceServer(grpcS, server.serviceSet.AccountService) + certificatepkg.RegisterCertificateServiceServer(grpcS, server.serviceSet.CertificateService) + gpgkeypkg.RegisterGPGKeyServiceServer(grpcS, server.serviceSet.GpgkeyService) // Register reflection service on gRPC server. reflection.Register(grpcS) grpc_prometheus.Register(grpcS) - errorsutil.CheckError(a.serviceSet.ProjectService.NormalizeProjs()) - return grpcS, a.serviceSet.AppResourceTreeFn + errorsutil.CheckError(server.serviceSet.ProjectService.NormalizeProjs()) + return grpcS, server.serviceSet.AppResourceTreeFn } type ArgoCDServiceSet struct { @@ -1084,27 +1084,27 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { } // translateGrpcCookieHeader conditionally sets a cookie on the response. -func (a *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.ResponseWriter, resp golang_proto.Message) error { +func (server *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.ResponseWriter, resp golang_proto.Message) error { if sessionResp, ok := resp.(*sessionpkg.SessionResponse); ok { token := sessionResp.Token - err := a.setTokenCookie(token, w) + err := server.setTokenCookie(token, w) if err != nil { return fmt.Errorf("error setting token cookie from session response: %w", err) } } else if md, ok := runtime.ServerMetadataFromContext(ctx); ok { renewToken := md.HeaderMD[renewTokenKey] if len(renewToken) > 0 { - return a.setTokenCookie(renewToken[0], w) + return server.setTokenCookie(renewToken[0], w) } } return nil } -func (a *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error { - cookiePath := "path=/" + strings.TrimRight(strings.TrimLeft(a.ArgoCDServerOpts.BaseHRef, "/"), "/") +func (server *ArgoCDServer) setTokenCookie(token string, w http.ResponseWriter) error { + cookiePath := "path=/" + strings.TrimRight(strings.TrimLeft(server.ArgoCDServerOpts.BaseHRef, "/"), "/") flags := []string{cookiePath, "SameSite=lax", "httpOnly"} - if !a.Insecure { + if !server.Insecure { flags = append(flags, "Secure") } cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...) @@ -1142,7 +1142,7 @@ func compressHandler(handler http.Handler) http.Handler { // newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented // using grpc-gateway as a proxy to the gRPC server. -func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn, metricsReg HTTPMetricsRegistry) *http.Server { +func (server *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn, metricsReg HTTPMetricsRegistry) *http.Server { endpoint := fmt.Sprintf("localhost:%d", port) mux := http.NewServeMux() httpS := http.Server{ @@ -1150,8 +1150,8 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl Handler: &handlerSwitcher{ handler: mux, urlToHandler: map[string]http.Handler{ - "/api/badge": badge.NewHandler(a.AppClientset, a.settingsMgr, a.Namespace, a.ApplicationNamespaces), - common.LogoutEndpoint: logout.NewHandler(a.AppClientset, a.settingsMgr, a.sessionMgr, a.ArgoCDServerOpts.RootPath, a.ArgoCDServerOpts.BaseHRef, a.Namespace), + "/api/badge": badge.NewHandler(server.AppClientset, server.settingsMgr, server.Namespace, server.ApplicationNamespaces), + common.LogoutEndpoint: logout.NewHandler(server.AppClientset, server.settingsMgr, server.sessionMgr, server.ArgoCDServerOpts.RootPath, server.ArgoCDServerOpts.BaseHRef, server.Namespace), }, contentTypeToHandler: map[string]http.Handler{ "application/grpc-web+proto": grpcWebHandler, @@ -1166,34 +1166,34 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl // time.Time, but does not support custom UnmarshalJSON() and MarshalJSON() methods. Therefore // we use our own Marshaler gwMuxOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, new(grpc_util.JSONMarshaler)) - gwCookieOpts := runtime.WithForwardResponseOption(a.translateGrpcCookieHeader) + gwCookieOpts := runtime.WithForwardResponseOption(server.translateGrpcCookieHeader) gwmux := runtime.NewServeMux(gwMuxOpts, gwCookieOpts) var handler http.Handler = gwmux - if a.EnableGZip { + if server.EnableGZip { handler = compressHandler(handler) } - if len(a.ContentTypes) > 0 { - handler = enforceContentTypes(handler, a.ContentTypes) + if len(server.ContentTypes) > 0 { + handler = enforceContentTypes(handler, server.ContentTypes) } else { log.WithField(common.SecurityField, common.SecurityHigh).Warnf("Content-Type enforcement is disabled, which may make your API vulnerable to CSRF attacks") } mux.Handle("/api/", handler) - terminalOpts := application.TerminalOptions{DisableAuth: a.ArgoCDServerOpts.DisableAuth, Enf: a.enf} + terminalOpts := application.TerminalOptions{DisableAuth: server.ArgoCDServerOpts.DisableAuth, Enf: server.enf} - terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.Cache, appResourceTreeFn, a.settings.ExecShells, a.sessionMgr, &terminalOpts). - WithFeatureFlagMiddleware(a.settingsMgr.GetSettings) - th := util_session.WithAuthMiddleware(a.DisableAuth, a.sessionMgr, terminal) + terminal := application.NewHandler(server.appLister, server.Namespace, server.ApplicationNamespaces, server.db, server.Cache, appResourceTreeFn, server.settings.ExecShells, server.sessionMgr, &terminalOpts). + WithFeatureFlagMiddleware(server.settingsMgr.GetSettings) + th := util_session.WithAuthMiddleware(server.DisableAuth, server.sessionMgr, terminal) mux.Handle("/terminal", th) // Proxy extension is currently an alpha feature and is disabled // by default. - if a.EnableProxyExtension { + if server.EnableProxyExtension { // API server won't panic if extensions fail to register. In // this case an error log will be sent and no extension route // will be added in mux. - registerExtensions(mux, a, metricsReg) + registerExtensions(mux, server, metricsReg) } mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandler, ctx, gwmux, conn) @@ -1211,15 +1211,15 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl mustRegisterGWHandler(gpgkeypkg.RegisterGPGKeyServiceHandler, ctx, gwmux, conn) // Swagger UI - swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", a.RootPath) - healthz.ServeHealthCheck(mux, a.healthCheck) + swagger.ServeSwaggerUI(mux, assets.SwaggerJSON, "/swagger-ui", server.RootPath) + healthz.ServeHealthCheck(mux, server.healthCheck) // Dex reverse proxy and client app and OAuth2 login/callback - a.registerDexHandlers(mux) + server.registerDexHandlers(mux) // Webhook handler for git events (Note: cache timeouts are hardcoded because API server does not write to cache and not really using them) - argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) - acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.ArgoCDServerOpts.WebhookParallelism, a.AppClientset, a.settings, a.settingsMgr, a.RepoServerCache, a.Cache, argoDB, a.settingsMgr.GetMaxWebhookPayloadSize()) + argoDB := db.NewDB(server.Namespace, server.settingsMgr, server.KubeClientset) + acdWebhookHandler := webhook.NewHandler(server.Namespace, server.ArgoCDServerOpts.ApplicationNamespaces, server.ArgoCDServerOpts.WebhookParallelism, server.AppClientset, server.settings, server.settingsMgr, server.RepoServerCache, server.Cache, argoDB, server.settingsMgr.GetMaxWebhookPayloadSize()) mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler) @@ -1230,16 +1230,16 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl extensionsSharedPath := "/tmp/extensions/" var extensionsHandler http.Handler = http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) { - a.serveExtensions(extensionsSharedPath, writer) + server.serveExtensions(extensionsSharedPath, writer) }) - if a.ArgoCDServerOpts.EnableGZip { + if server.ArgoCDServerOpts.EnableGZip { extensionsHandler = compressHandler(extensionsHandler) } mux.Handle("/extensions.js", extensionsHandler) // Serve UI static assets - var assetsHandler http.Handler = http.HandlerFunc(a.newStaticAssetsHandler()) - if a.ArgoCDServerOpts.EnableGZip { + var assetsHandler http.Handler = http.HandlerFunc(server.newStaticAssetsHandler()) + if server.ArgoCDServerOpts.EnableGZip { assetsHandler = compressHandler(assetsHandler) } mux.Handle("/", assetsHandler) @@ -1280,7 +1280,7 @@ func registerExtensions(mux *http.ServeMux, a *ArgoCDServer, metricsReg HTTPMetr var extensionsPattern = regexp.MustCompile(`^extension(.*)\.js$`) -func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) { +func (server *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.ResponseWriter) { w.Header().Set("Content-Type", "application/javascript") err := filepath.Walk(extensionsSharedPath, func(filePath string, info os.FileInfo, err error) error { @@ -1321,17 +1321,17 @@ func (a *ArgoCDServer) serveExtensions(extensionsSharedPath string, w http.Respo } // registerDexHandlers will register dex HTTP handlers, creating the OAuth client app -func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) { - if !a.settings.IsSSOConfigured() { +func (server *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) { + if !server.settings.IsSSOConfigured() { return } // Run dex OpenID Connect Identity Provider behind a reverse proxy (served at /api/dex) var err error - mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(a.DexServerAddr, a.BaseHRef, a.DexTLSConfig)) - a.ssoClientApp, err = oidc.NewClientApp(a.settings, a.DexServerAddr, a.DexTLSConfig, a.BaseHRef, cacheutil.NewRedisCache(a.RedisClient, a.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone)) + mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(server.DexServerAddr, server.BaseHRef, server.DexTLSConfig)) + server.ssoClientApp, err = oidc.NewClientApp(server.settings, server.DexServerAddr, server.DexTLSConfig, server.BaseHRef, cacheutil.NewRedisCache(server.RedisClient, server.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone)) errorsutil.CheckError(err) - mux.HandleFunc(common.LoginEndpoint, a.ssoClientApp.HandleLogin) - mux.HandleFunc(common.CallbackEndpoint, a.ssoClientApp.HandleCallback) + mux.HandleFunc(common.LoginEndpoint, server.ssoClientApp.HandleLogin) + mux.HandleFunc(common.CallbackEndpoint, server.ssoClientApp.HandleCallback) } // newRedirectServer returns an HTTP server which does a 307 redirect to the HTTPS server @@ -1366,21 +1366,21 @@ func registerDownloadHandlers(mux *http.ServeMux, base string) { } } -func (s *ArgoCDServer) getIndexData() ([]byte, error) { - s.indexDataInit.Do(func() { +func (server *ArgoCDServer) getIndexData() ([]byte, error) { + server.indexDataInit.Do(func() { data, err := ui.Embedded.ReadFile("dist/app/index.html") if err != nil { - s.indexDataErr = err + server.indexDataErr = err return } - if s.BaseHRef == "/" || s.BaseHRef == "" { - s.indexData = data + if server.BaseHRef == "/" || server.BaseHRef == "" { + server.indexData = data } else { - s.indexData = []byte(replaceBaseHRef(string(data), fmt.Sprintf(``, strings.Trim(s.BaseHRef, "/")))) + server.indexData = []byte(replaceBaseHRef(string(data), fmt.Sprintf(``, strings.Trim(server.BaseHRef, "/")))) } }) - return s.indexData, s.indexDataErr + return server.indexData, server.indexDataErr } func (server *ArgoCDServer) uiAssetExists(filename string) bool { @@ -1470,11 +1470,11 @@ func replaceBaseHRef(data string, replaceWith string) string { } // Authenticate checks for the presence of a valid token when accessing server-side resources. -func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) { - if a.DisableAuth { +func (server *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) { + if server.DisableAuth { return ctx, nil } - claims, newToken, claimsErr := a.getClaims(ctx) + claims, newToken, claimsErr := server.getClaims(ctx) if claims != nil { // Add claims to the context to inspect for RBAC // nolint:staticcheck @@ -1494,7 +1494,7 @@ func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error } if claimsErr != nil { - argoCDSettings, err := a.settingsMgr.GetSettings() + argoCDSettings, err := server.settingsMgr.GetSettings() if err != nil { return ctx, status.Errorf(codes.Internal, "unable to load settings: %v", err) } @@ -1509,7 +1509,7 @@ func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error return ctx, nil } -func (a *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) { +func (server *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, "", ErrNoSession @@ -1518,7 +1518,7 @@ func (a *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error if tokenString == "" { return nil, "", ErrNoSession } - claims, newToken, err := a.sessionMgr.VerifyToken(tokenString) + claims, newToken, err := server.sessionMgr.VerifyToken(tokenString) if err != nil { return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err) } @@ -1534,8 +1534,8 @@ func (a *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error } } iss := jwtutil.StringField(groupClaims, "iss") - if iss != util_session.SessionManagerClaimsIssuer && a.settings.UserInfoGroupsEnabled() && a.settings.UserInfoPath() != "" { - userInfo, unauthorized, err := a.ssoClientApp.GetUserInfo(groupClaims, a.settings.IssuerURL(), a.settings.UserInfoPath()) + if iss != util_session.SessionManagerClaimsIssuer && server.settings.UserInfoGroupsEnabled() && server.settings.UserInfoPath() != "" { + userInfo, unauthorized, err := server.ssoClientApp.GetUserInfo(groupClaims, server.settings.IssuerURL(), server.settings.UserInfoPath()) if unauthorized { log.Errorf("error while quering userinfo endpoint: %v", err) return claims, "", status.Errorf(codes.Unauthenticated, "invalid session") @@ -1685,11 +1685,11 @@ func bug21955WorkaroundInterceptor(ctx context.Context, req any, _ *grpc.UnarySe // allowedApplicationNamespacesAsString returns a string containing comma-separated list // of allowed application namespaces -func (a *ArgoCDServer) allowedApplicationNamespacesAsString() string { - ns := a.Namespace - if len(a.ArgoCDServerOpts.ApplicationNamespaces) > 0 { +func (server *ArgoCDServer) allowedApplicationNamespacesAsString() string { + ns := server.Namespace + if len(server.ArgoCDServerOpts.ApplicationNamespaces) > 0 { ns += ", " - ns += strings.Join(a.ArgoCDServerOpts.ApplicationNamespaces, ", ") + ns += strings.Join(server.ArgoCDServerOpts.ApplicationNamespaces, ", ") } return ns } diff --git a/util/git/creds.go b/util/git/creds.go index aea82574934d6..a592b315e3c87 100644 --- a/util/git/creds.go +++ b/util/git/creds.go @@ -239,8 +239,8 @@ func (c HTTPSCreds) Environ() (io.Closer, []string, error) { }), env, nil } -func (g HTTPSCreds) HasClientCert() bool { - return g.clientCertData != "" && g.clientCertKey != "" +func (c HTTPSCreds) HasClientCert() bool { + return c.clientCertData != "" && c.clientCertKey != "" } func (c HTTPSCreds) GetClientCertData() string {