Skip to content

Commit

Permalink
Merge branch 'master' into 20897-switch-default-logging-to-json
Browse files Browse the repository at this point in the history
  • Loading branch information
teddy-wahle authored Jan 31, 2025
2 parents c63d1e9 + b4a63ae commit ea57d38
Show file tree
Hide file tree
Showing 69 changed files with 1,989 additions and 546 deletions.
23 changes: 12 additions & 11 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ linters:
- importas
- ineffassign
- misspell
- nolintlint
# Disabled because of https://github.com/argoproj/argo-cd/issues/21705
# - nolintlint
- perfsprint
- revive
- staticcheck
Expand All @@ -29,12 +30,12 @@ linters:
- unparam
- unused
- usestdlibvars
- whitespace
- whitespace
linters-settings:
gocritic:
disabled-checks:
- appendAssign
- assignOp # Keep it disabled for readability
- assignOp # Keep it disabled for readability
- exitAfterDefer
- mapKey
- typeSwitchVar
Expand All @@ -49,23 +50,23 @@ linters-settings:
- github.com/imdario/mergo:
recommendations:
- dario.cat/mergo
reason: "`github.com/imdario/mergo` has been renamed."
reason: '`github.com/imdario/mergo` has been renamed.'
- github.com/pkg/errors:
recommendations:
- errors
importas:
alias:
- alias: jwtgo
- alias: jwtgo
pkg: github.com/golang-jwt/jwt/v5
- alias: appsv1
pkg: k8s.io/api/apps/v1
- alias: corev1
pkg: k8s.io/api/core/v1
- alias: rbacv1
pkg: k8s.io/api/rbac/v1
- alias: apierrors
- alias: apierrors
pkg: k8s.io/apimachinery/pkg/api/errors
- alias: metav1
- alias: metav1
pkg: k8s.io/apimachinery/pkg/apis/meta/v1
- alias: informersv1
pkg: k8s.io/client-go/informers/core/v1
Expand All @@ -92,15 +93,15 @@ linters-settings:
disabled: true
- name: context-as-argument
arguments:
- allowTypesBefore: "*testing.T,testing.TB"
- allowTypesBefore: '*testing.T,testing.TB'
- name: context-keys-type
disabled: true
- name: dot-imports
disabled: true
- name: duplicated-imports
- name: early-return
arguments:
- "preserveScope"
- 'preserveScope'
- name: empty-block
disabled: true
- name: error-naming
Expand All @@ -114,7 +115,7 @@ linters-settings:
- name: increment-decrement
- name: indent-error-flow
arguments:
- "preserveScope"
- 'preserveScope'
- name: modifies-parameter
- name: optimize-operands-order
- name: range
Expand All @@ -124,7 +125,7 @@ linters-settings:
- name: redundant-import-alias
- name: superfluous-else
arguments:
- "preserveScope"
- 'preserveScope'
- name: time-equal
- name: time-naming
disabled: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func NewCommand() *cobra.Command {
metricsCacheExpiration time.Duration
metricsAplicationLabels []string
metricsAplicationConditions []string
metricsClusterLabels []string
kubectlParallelismLimit int64
cacheSource func() (*appstatecache.Cache, error)
redisClient *redis.Client
Expand Down Expand Up @@ -202,6 +203,7 @@ func NewCommand() *cobra.Command {
metricsCacheExpiration,
metricsAplicationLabels,
metricsAplicationConditions,
metricsClusterLabels,
kubectlParallelismLimit,
persistResourceHealth,
clusterSharding,
Expand Down Expand Up @@ -272,6 +274,7 @@ func NewCommand() *cobra.Command {
command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server")
command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric")
command.Flags().StringSliceVar(&metricsAplicationConditions, "metrics-application-conditions", []string{}, "List of Application conditions that will be added to the argocd_application_conditions metric")
command.Flags().StringSliceVar(&metricsClusterLabels, "metrics-cluster-labels", []string{}, "List of Cluster labels that will be added to the argocd_cluster_labels metric")
command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to")
command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode")
command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)")
Expand Down
21 changes: 13 additions & 8 deletions cmd/argocd/commands/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import (
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
sessionpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/session"
settingspkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/settings"
claimsutil "github.com/argoproj/argo-cd/v3/util/claims"
"github.com/argoproj/argo-cd/v3/util/cli"
"github.com/argoproj/argo-cd/v3/util/errors"
grpc_util "github.com/argoproj/argo-cd/v3/util/grpc"
"github.com/argoproj/argo-cd/v3/util/io"
jwtutil "github.com/argoproj/argo-cd/v3/util/jwt"
"github.com/argoproj/argo-cd/v3/util/localconfig"
oidcutil "github.com/argoproj/argo-cd/v3/util/oidc"
"github.com/argoproj/argo-cd/v3/util/rand"
Expand Down Expand Up @@ -143,7 +143,9 @@ argocd login cd.argoproj.io --core`,
claims := jwt.MapClaims{}
_, _, err := parser.ParseUnverified(tokenString, &claims)
errors.CheckError(err)
fmt.Printf("'%s' logged in successfully\n", userDisplayName(claims))
argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims)
errors.CheckError(err)
fmt.Printf("'%s' logged in successfully\n", userDisplayName(argoClaims))
}

// login successful. Persist the config
Expand Down Expand Up @@ -190,14 +192,17 @@ argocd login cd.argoproj.io --core`,
return command
}

func userDisplayName(claims jwt.MapClaims) string {
if email := jwtutil.StringField(claims, "email"); email != "" {
return email
func userDisplayName(claims *claimsutil.ArgoClaims) string {
if claims == nil {
return ""
}
if claims.Email != "" {
return claims.Email
}
if name := jwtutil.StringField(claims, "name"); name != "" {
return name
if claims.Name != "" {
return claims.Name
}
return jwtutil.StringField(claims, "sub")
return claims.GetUserIdentifier()
}

// oauth2Login opens a browser, runs a temporary HTTP server to delegate OAuth2 login flow and
Expand Down
27 changes: 24 additions & 3 deletions cmd/argocd/commands/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"os"
"testing"

claimsutil "github.com/argoproj/argo-cd/v3/util/claims"
utils "github.com/argoproj/argo-cd/v3/util/io"

"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func captureStdout(callback func()) (string, error) {
Expand All @@ -35,26 +37,45 @@ func captureStdout(callback func()) (string, error) {
}

func Test_userDisplayName_email(t *testing.T) {
claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "[email protected]", "groups": []string{"baz"}}
claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "email": "[email protected]", "groups": []string{"baz"}})
require.NoError(t, err)
actualName := userDisplayName(claims)
expectedName := "[email protected]"
assert.Equal(t, expectedName, actualName)
}

func Test_userDisplayName_name(t *testing.T) {
claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "name": "Firstname Lastname", "groups": []string{"baz"}}
claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "name": "Firstname Lastname", "groups": []string{"baz"}})
require.NoError(t, err)
actualName := userDisplayName(claims)
expectedName := "Firstname Lastname"
assert.Equal(t, expectedName, actualName)
}

func Test_userDisplayName_sub(t *testing.T) {
claims := jwt.MapClaims{"iss": "qux", "sub": "foo", "groups": []string{"baz"}}
claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{"iss": "qux", "sub": "foo", "groups": []string{"baz"}})
require.NoError(t, err)
actualName := userDisplayName(claims)
expectedName := "foo"
assert.Equal(t, expectedName, actualName)
}

func Test_userDisplayName_federatedClaims(t *testing.T) {
claims, err := claimsutil.MapClaimsToArgoClaims(jwt.MapClaims{
"iss": "qux",
"sub": "foo",
"groups": []string{"baz"},
"federated_claims": map[string]any{
"connector_id": "dex",
"user_id": "ldap-123",
},
})
require.NoError(t, err)
actualName := userDisplayName(claims)
expectedName := "ldap-123"
assert.Equal(t, expectedName, actualName)
}

func Test_ssoAuthFlow_ssoLaunchBrowser_false(t *testing.T) {
out, _ := captureStdout(func() {
ssoAuthFlow("http://test-sso-browser-flow.com", false)
Expand Down
21 changes: 14 additions & 7 deletions cmd/argocd/commands/project_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
projectpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/project"
"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
claimsutil "github.com/argoproj/argo-cd/v3/util/claims"
"github.com/argoproj/argo-cd/v3/util/errors"
"github.com/argoproj/argo-cd/v3/util/io"
"github.com/argoproj/argo-cd/v3/util/jwt"
Expand Down Expand Up @@ -191,7 +192,7 @@ func NewProjectRoleCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.
command := &cobra.Command{
Use: "create PROJECT ROLE-NAME",
Short: "Create a project role",
Example: templates.Examples(`
Example: templates.Examples(`
# Create a project role in the "my-project" project with the name "my-role".
argocd proj role create my-project my-role --description "My project role description"
`),
Expand Down Expand Up @@ -321,18 +322,24 @@ Create token succeeded for proj:test-project:test-role.
})
errors.CheckError(err)

token, err := jwtgo.Parse(tokenResponse.Token, nil)
if token == nil {
var claims jwtgo.MapClaims
_, _, err = jwtgo.NewParser().ParseUnverified(tokenResponse.Token, &claims)
if err != nil {
err = fmt.Errorf("received malformed token %w", err)
errors.CheckError(err)
return
}

claims := token.Claims.(jwtgo.MapClaims)
argoClaims, err := claimsutil.MapClaimsToArgoClaims(claims)
if err != nil {
errors.CheckError(fmt.Errorf("invalid argo claims: %w", err))
return
}

issuedAt, _ := jwt.IssuedAt(claims)
expiresAt := int64(jwt.Float64Field(claims, "exp"))
id := jwt.StringField(claims, "jti")
subject := jwt.StringField(claims, "sub")
id := argoClaims.ID
subject := argoClaims.GetUserIdentifier()

if !outputTokenOnly {
fmt.Printf("Create token succeeded for %s.\n", subject)
Expand Down Expand Up @@ -496,7 +503,7 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co
command := &cobra.Command{
Use: "list PROJECT",
Short: "List all the roles in a project",
Example: templates.Examples(`
Example: templates.Examples(`
# This command will list all the roles in argocd-project in a default table format.
argocd proj role list PROJECT
Expand Down
2 changes: 2 additions & 0 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ const (
ArgoCDCLIClientAppName = "Argo CD CLI"
// ArgoCDCLIClientAppID is the Oauth client ID we will use when registering our CLI to dex
ArgoCDCLIClientAppID = "argo-cd-cli"
// DexFederatedScope allows to receive the federated_claims from Dex. https://dexidp.io/docs/configuration/custom-scopes-claims-clients/
DexFederatedScope = "federated:id"
)

// Resource metadata labels and annotations (keys and values) used by Argo CD components
Expand Down
5 changes: 4 additions & 1 deletion controller/appcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ type ApplicationController struct {
refreshRequestedApps map[string]CompareWith
refreshRequestedAppsMutex *sync.Mutex
metricsServer *metrics.MetricsServer
metricsClusterLabels []string
kubectlSemaphore *semaphore.Weighted
clusterSharding sharding.ClusterShardingCache
projByNameCache sync.Map
Expand Down Expand Up @@ -173,6 +174,7 @@ func NewApplicationController(
metricsCacheExpiration time.Duration,
metricsApplicationLabels []string,
metricsApplicationConditions []string,
metricsClusterLabels []string,
kubectlParallelismLimit int64,
persistResourceHealth bool,
clusterSharding sharding.ClusterShardingCache,
Expand Down Expand Up @@ -218,6 +220,7 @@ func NewApplicationController(
applicationNamespaces: applicationNamespaces,
dynamicClusterDistributionEnabled: dynamicClusterDistributionEnabled,
ignoreNormalizerOpts: ignoreNormalizerOpts,
metricsClusterLabels: metricsClusterLabels,
}
if hydratorEnabled {
ctrl.hydrator = hydrator.NewHydrator(&ctrl, appResyncPeriod, commitClientset)
Expand Down Expand Up @@ -857,8 +860,8 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int
defer ctrl.appHydrateQueue.ShutDown()
defer ctrl.hydrationQueue.ShutDown()

ctrl.metricsServer.RegisterClustersInfoSource(ctx, ctrl.stateCache)
ctrl.RegisterClusterSecretUpdater(ctx)
ctrl.metricsServer.RegisterClustersInfoSource(ctx, ctrl.stateCache, ctrl.db, ctrl.metricsClusterLabels)

go ctrl.appInformer.Run(ctx.Done())
go ctrl.projInformer.Run(ctx.Done())
Expand Down
1 change: 1 addition & 0 deletions controller/appcontroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func newFakeControllerWithResync(data *fakeData, appResyncPeriod time.Duration,
data.metricsCacheExpiration,
[]string{},
[]string{},
[]string{},
0,
true,
nil,
Expand Down
Loading

0 comments on commit ea57d38

Please sign in to comment.