github.com/argoproj/argo-cd/v3@v3.2.1/common/common.go (about)

     1  package common
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/redis/go-redis/v9"
    13  	"github.com/sirupsen/logrus"
    14  	"google.golang.org/grpc/codes"
    15  	"google.golang.org/grpc/status"
    16  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    17  	"k8s.io/client-go/kubernetes"
    18  )
    19  
    20  // Component names
    21  const (
    22  	ApplicationController    = "argocd-application-controller"
    23  	ApplicationSetController = "argocd-applicationset-controller"
    24  )
    25  
    26  // Default service addresses and URLS of Argo CD internal services
    27  const (
    28  	// DefaultRepoServerAddr is the gRPC address of the Argo CD repo server
    29  	DefaultRepoServerAddr = "argocd-repo-server:8081"
    30  	// DefaultCommitServerAddr is the gRPC address of the Argo CD commit server
    31  	DefaultCommitServerAddr = "argocd-commit-server:8086"
    32  	// DefaultDexServerAddr is the HTTP address of the Dex OIDC server, which we run a reverse proxy against
    33  	DefaultDexServerAddr = "argocd-dex-server:5556"
    34  	// DefaultRedisAddr is the default redis address
    35  	DefaultRedisAddr = "argocd-redis:6379"
    36  )
    37  
    38  // Kubernetes ConfigMap and Secret resource names which hold Argo CD settings
    39  const (
    40  	ArgoCDConfigMapName              = "argocd-cm"
    41  	ArgoCDSecretName                 = "argocd-secret"
    42  	ArgoCDNotificationsConfigMapName = "argocd-notifications-cm"
    43  	ArgoCDNotificationsSecretName    = "argocd-notifications-secret"
    44  	ArgoCDRBACConfigMapName          = "argocd-rbac-cm"
    45  	// ArgoCDKnownHostsConfigMapName contains SSH known hosts data for connecting repositories. Will get mounted as volume to pods
    46  	ArgoCDKnownHostsConfigMapName = "argocd-ssh-known-hosts-cm"
    47  	// ArgoCDTLSCertsConfigMapName contains TLS certificate data for connecting repositories. Will get mounted as volume to pods
    48  	ArgoCDTLSCertsConfigMapName = "argocd-tls-certs-cm"
    49  	ArgoCDGPGKeysConfigMapName  = "argocd-gpg-keys-cm"
    50  	// ArgoCDAppControllerShardConfigMapName contains the application controller to shard mapping
    51  	ArgoCDAppControllerShardConfigMapName = "argocd-app-controller-shard-cm"
    52  	ArgoCDCmdParamsConfigMapName          = "argocd-cmd-params-cm"
    53  )
    54  
    55  // Some default configurables
    56  const (
    57  	DefaultSystemNamespace = "kube-system"
    58  	DefaultRepoType        = "git"
    59  )
    60  
    61  // Default listener ports for ArgoCD components
    62  const (
    63  	DefaultPortAPIServer              = 8080
    64  	DefaultPortRepoServer             = 8081
    65  	DefaultPortArgoCDMetrics          = 8082
    66  	DefaultPortArgoCDAPIServerMetrics = 8083
    67  	DefaultPortRepoServerMetrics      = 8084
    68  	DefaultPortCommitServer           = 8086
    69  	DefaultPortCommitServerMetrics    = 8087
    70  )
    71  
    72  // DefaultAddressAPIServer for ArgoCD components
    73  const (
    74  	DefaultAddressAdminDashboard      = "localhost"
    75  	DefaultAddressAPIServer           = "0.0.0.0"
    76  	DefaultAddressAPIServerMetrics    = "0.0.0.0"
    77  	DefaultAddressRepoServer          = "0.0.0.0"
    78  	DefaultAddressRepoServerMetrics   = "0.0.0.0"
    79  	DefaultAddressCommitServer        = "0.0.0.0"
    80  	DefaultAddressCommitServerMetrics = "0.0.0.0"
    81  )
    82  
    83  // Default paths on the pod's file system
    84  const (
    85  	// DefaultPathTLSConfig is the default path where TLS certificates for repositories are located
    86  	DefaultPathTLSConfig = "/app/config/tls"
    87  	// DefaultPathSSHConfig is the default path where SSH known hosts are stored
    88  	DefaultPathSSHConfig = "/app/config/ssh"
    89  	// DefaultSSHKnownHostsName is the Default name for the SSH known hosts file
    90  	DefaultSSHKnownHostsName = "ssh_known_hosts"
    91  	// DefaultGnuPgHomePath is the Default path to GnuPG home directory
    92  	DefaultGnuPgHomePath = "/app/config/gpg/keys"
    93  	// DefaultAppConfigPath is the Default path to repo server TLS endpoint config
    94  	DefaultAppConfigPath = "/app/config"
    95  	// DefaultPluginSockFilePath is the Default path to cmp server plugin socket file
    96  	DefaultPluginSockFilePath = "/home/argocd/cmp-server/plugins"
    97  	// DefaultPluginConfigFilePath is the Default path to cmp server plugin configuration file
    98  	DefaultPluginConfigFilePath = "/home/argocd/cmp-server/config"
    99  	// PluginConfigFileName is the Plugin Config File is a ConfigManagementPlugin manifest located inside the plugin container
   100  	PluginConfigFileName = "plugin.yaml"
   101  )
   102  
   103  // consts for podrequests metrics in cache/info
   104  const (
   105  	PodRequestsCPU = "cpu"
   106  	PodRequestsMEM = "memory"
   107  )
   108  
   109  // Argo CD application related constants
   110  const (
   111  
   112  	// ArgoCDAdminUsername is the username of the 'admin' user
   113  	ArgoCDAdminUsername = "admin"
   114  	// ArgoCDUserAgentName is the default user-agent name used by the gRPC API client library and grpc-gateway
   115  	ArgoCDUserAgentName = "argocd-client"
   116  	// ArgoCDSSAManager is the default argocd manager name used by server-side apply syncs
   117  	ArgoCDSSAManager = "argocd-controller"
   118  	// AuthCookieName is the HTTP cookie name where we store our auth token
   119  	AuthCookieName = "argocd.token"
   120  	// StateCookieName is the HTTP cookie name that holds temporary nonce tokens for CSRF protection
   121  	StateCookieName = "argocd.oauthstate"
   122  	// StateCookieMaxAge is the maximum age of the oauth state cookie
   123  	StateCookieMaxAge = time.Minute * 5
   124  
   125  	// ChangePasswordSSOTokenMaxAge is the max token age for password change operation
   126  	ChangePasswordSSOTokenMaxAge = time.Minute * 5
   127  	// GithubAppCredsExpirationDuration is the default time used to cache the GitHub app credentials
   128  	GithubAppCredsExpirationDuration = time.Minute * 60
   129  
   130  	// PasswordPatten is the default password patten
   131  	PasswordPatten = `^.{8,32}$`
   132  
   133  	// LegacyShardingAlgorithm is the default value for Sharding Algorithm it uses an `uid` based distribution (non-uniform)
   134  	LegacyShardingAlgorithm = "legacy"
   135  	// RoundRobinShardingAlgorithm is a flag value that can be opted for Sharding Algorithm it uses an equal distribution across all shards
   136  	RoundRobinShardingAlgorithm = "round-robin"
   137  	// AppControllerHeartbeatUpdateRetryCount is the retry count for updating the Shard Mapping to the Shard Mapping ConfigMap used by Application Controller
   138  	AppControllerHeartbeatUpdateRetryCount = 3
   139  
   140  	// ConsistentHashingWithBoundedLoadsAlgorithm uses an algorithm that tries to use an equal distribution across
   141  	// all shards but is optimised to handle sharding and/or cluster addition or removal. In case of sharding or
   142  	// cluster changes, this algorithm minimises the changes between shard and clusters assignments.
   143  	ConsistentHashingWithBoundedLoadsAlgorithm = "consistent-hashing"
   144  
   145  	DefaultShardingAlgorithm = LegacyShardingAlgorithm
   146  )
   147  
   148  // Dex related constants
   149  const (
   150  	// DexAPIEndpoint is the endpoint where we serve the Dex API server
   151  	DexAPIEndpoint = "/api/dex"
   152  	// LoginEndpoint is Argo CD's shorthand login endpoint which redirects to dex's OAuth 2.0 provider's consent page
   153  	LoginEndpoint = "/auth/login"
   154  	// LogoutEndpoint is Argo CD's shorthand logout endpoint which invalidates OIDC session after logout
   155  	LogoutEndpoint = "/auth/logout"
   156  	// CallbackEndpoint is Argo CD's final callback endpoint we reach after OAuth 2.0 login flow has been completed
   157  	CallbackEndpoint = "/auth/callback"
   158  	// DexCallbackEndpoint is Argo CD's final callback endpoint when Dex is configured
   159  	DexCallbackEndpoint = "/api/dex/callback"
   160  	// ArgoCDClientAppName is name of the Oauth client app used when registering our web app to dex
   161  	ArgoCDClientAppName = "Argo CD"
   162  	// ArgoCDClientAppID is the Oauth client ID we will use when registering our app to dex
   163  	ArgoCDClientAppID = "argo-cd"
   164  	// ArgoCDCLIClientAppName is name of the Oauth client app used when registering our CLI to dex
   165  	ArgoCDCLIClientAppName = "Argo CD CLI"
   166  	// ArgoCDCLIClientAppID is the Oauth client ID we will use when registering our CLI to dex
   167  	ArgoCDCLIClientAppID = "argo-cd-cli"
   168  	// DexFederatedScope allows to receive the federated_claims from Dex. https://dexidp.io/docs/configuration/custom-scopes-claims-clients/
   169  	DexFederatedScope = "federated:id"
   170  )
   171  
   172  // Resource metadata labels and annotations (keys and values) used by Argo CD components
   173  const (
   174  	// LabelKeyAppInstance is the label key to use to uniquely identify the instance of an application
   175  	// The Argo CD application name is used as the instance name
   176  	LabelKeyAppInstance = "app.kubernetes.io/instance"
   177  	// LabelKeyAppName is the label key to use to uniquely identify the name of the Kubernetes application
   178  	LabelKeyAppName = "app.kubernetes.io/name"
   179  	// LabelKeyAutoLabelClusterInfo if set to true will automatically add extra labels from the cluster info (currently it only adds a k8s version label)
   180  	LabelKeyAutoLabelClusterInfo = "argocd.argoproj.io/auto-label-cluster-info"
   181  	// LabelKeyLegacyApplicationName is the legacy label (v0.10 and below) and is superseded by 'app.kubernetes.io/instance'
   182  	LabelKeyLegacyApplicationName = "applications.argoproj.io/app-name"
   183  	// LabelKeySecretType contains the type of argocd secret (currently: 'cluster', 'repository', 'repo-config' or 'repo-creds')
   184  	LabelKeySecretType = "argocd.argoproj.io/secret-type"
   185  	// LabelKeyClusterKubernetesVersion contains the kubernetes version of the cluster secret if it has been enabled
   186  	LabelKeyClusterKubernetesVersion = "argocd.argoproj.io/kubernetes-version"
   187  	// LabelValueSecretTypeCluster indicates a secret type of cluster
   188  	LabelValueSecretTypeCluster = "cluster"
   189  	// LabelValueSecretTypeRepository indicates a secret type of repository
   190  	LabelValueSecretTypeRepository = "repository"
   191  	// LabelValueSecretTypeRepoCreds indicates a secret type of repository credentials
   192  	LabelValueSecretTypeRepoCreds = "repo-creds"
   193  	// LabelValueSecretTypeRepositoryWrite indicates a secret type of repository credentials for writing
   194  	LabelValueSecretTypeRepositoryWrite = "repository-write"
   195  	// LabelValueSecretTypeRepoCredsWrite indicates a secret type of repository credentials for writing for templating
   196  	LabelValueSecretTypeRepoCredsWrite = "repo-write-creds"
   197  	// LabelValueSecretTypeSCMCreds indicates a secret type of SCM credentials
   198  	LabelValueSecretTypeSCMCreds = "scm-creds"
   199  
   200  	// AnnotationKeyAppInstance is the Argo CD application name is used as the instance name
   201  	AnnotationKeyAppInstance = "argocd.argoproj.io/tracking-id"
   202  	AnnotationInstallationID = "argocd.argoproj.io/installation-id"
   203  
   204  	// AnnotationCompareOptions is a comma-separated list of options for comparison
   205  	AnnotationCompareOptions = "argocd.argoproj.io/compare-options"
   206  
   207  	// AnnotationClientSideApplyMigrationManager specifies a custom field manager for client-side apply migration
   208  	AnnotationClientSideApplyMigrationManager = "argocd.argoproj.io/client-side-apply-migration-manager"
   209  
   210  	// AnnotationIgnoreHealthCheck when set on an Application's immediate child indicates that its health check
   211  	// can be disregarded.
   212  	AnnotationIgnoreHealthCheck = "argocd.argoproj.io/ignore-healthcheck"
   213  
   214  	// AnnotationKeyManagedBy is annotation name which indicates that k8s resource is managed by an application.
   215  	AnnotationKeyManagedBy = "managed-by"
   216  	// AnnotationValueManagedByArgoCD is a 'managed-by' annotation value for resources managed by Argo CD
   217  	AnnotationValueManagedByArgoCD = "argocd.argoproj.io"
   218  
   219  	// AnnotationKeyLinkPrefix tells the UI to add an external link icon to the application node
   220  	// that links to the value given in the annotation.
   221  	// The annotation key must be followed by a unique identifier. Ex: link.argocd.argoproj.io/dashboard
   222  	// It's valid to have multiple annotations that match the prefix.
   223  	// Values can simply be a url or they can have
   224  	// an optional link title separated by a "|"
   225  	// Ex: "http://grafana.example.com/d/yu5UH4MMz/deployments"
   226  	// Ex: "Go to Dashboard|http://grafana.example.com/d/yu5UH4MMz/deployments"
   227  	AnnotationKeyLinkPrefix = "link.argocd.argoproj.io/"
   228  
   229  	// AnnotationKeyAppSkipReconcile tells the Application to skip the Application controller reconcile.
   230  	// Skip reconcile when the value is "true" or any other string values that can be strconv.ParseBool() to be true.
   231  	AnnotationKeyAppSkipReconcile = "argocd.argoproj.io/skip-reconcile"
   232  	// LabelKeyComponentRepoServer is the label key to identify the component as repo-server
   233  	LabelKeyComponentRepoServer = "app.kubernetes.io/component"
   234  	// LabelValueComponentRepoServer is the label value for the repo-server component
   235  	LabelValueComponentRepoServer = "repo-server"
   236  )
   237  
   238  // Environment variables for tuning and debugging Argo CD
   239  const (
   240  	// EnvVarSSODebug is an environment variable to enable additional OAuth debugging in the API server
   241  	EnvVarSSODebug = "ARGOCD_SSO_DEBUG"
   242  	// EnvVarRBACDebug is an environment variable to enable additional RBAC debugging in the API server
   243  	EnvVarRBACDebug = "ARGOCD_RBAC_DEBUG"
   244  	// EnvVarSSHDataPath overrides the location where SSH known hosts for repo access data is stored
   245  	EnvVarSSHDataPath = "ARGOCD_SSH_DATA_PATH"
   246  	// EnvVarTLSDataPath overrides the location where TLS certificate for repo access data is stored
   247  	EnvVarTLSDataPath = "ARGOCD_TLS_DATA_PATH"
   248  	// EnvGitAttemptsCount specifies number of git remote operations attempts count
   249  	EnvGitAttemptsCount = "ARGOCD_GIT_ATTEMPTS_COUNT"
   250  	// EnvGitRetryMaxDuration specifies max duration of git remote operation retry
   251  	EnvGitRetryMaxDuration = "ARGOCD_GIT_RETRY_MAX_DURATION"
   252  	// EnvGitRetryDuration specifies duration of git remote operation retry
   253  	EnvGitRetryDuration = "ARGOCD_GIT_RETRY_DURATION"
   254  	// EnvGitRetryFactor specifies factor of git remote operation retry
   255  	EnvGitRetryFactor = "ARGOCD_GIT_RETRY_FACTOR"
   256  	// EnvGitSubmoduleEnabled overrides git submodule support, true by default
   257  	EnvGitSubmoduleEnabled = "ARGOCD_GIT_MODULES_ENABLED"
   258  	// EnvGnuPGHome is the path to ArgoCD's GnuPG keyring for signature verification
   259  	EnvGnuPGHome = "ARGOCD_GNUPGHOME"
   260  	// EnvWatchAPIBufferSize is the buffer size used to transfer K8S watch events to watch API consumer
   261  	EnvWatchAPIBufferSize = "ARGOCD_WATCH_API_BUFFER_SIZE"
   262  	// EnvPauseGenerationAfterFailedAttempts will pause manifest generation after the specified number of failed generation attempts
   263  	EnvPauseGenerationAfterFailedAttempts = "ARGOCD_PAUSE_GEN_AFTER_FAILED_ATTEMPTS"
   264  	// EnvPauseGenerationMinutes pauses manifest generation for the specified number of minutes, after sufficient manifest generation failures
   265  	EnvPauseGenerationMinutes = "ARGOCD_PAUSE_GEN_MINUTES"
   266  	// EnvPauseGenerationRequests pauses manifest generation for the specified number of requests, after sufficient manifest generation failures
   267  	EnvPauseGenerationRequests = "ARGOCD_PAUSE_GEN_REQUESTS"
   268  	// EnvControllerReplicas is the number of controller replicas
   269  	EnvControllerReplicas = "ARGOCD_CONTROLLER_REPLICAS"
   270  	// EnvControllerHeartbeatTime will update the heartbeat for application controller to claim shard
   271  	EnvControllerHeartbeatTime = "ARGOCD_CONTROLLER_HEARTBEAT_TIME"
   272  	// EnvControllerShard is the shard number that should be handled by controller
   273  	EnvControllerShard = "ARGOCD_CONTROLLER_SHARD"
   274  	// EnvControllerShardingAlgorithm is the distribution sharding algorithm to be used: legacy or round-robin
   275  	EnvControllerShardingAlgorithm = "ARGOCD_CONTROLLER_SHARDING_ALGORITHM"
   276  	// EnvEnableDynamicClusterDistribution enables dynamic sharding (ALPHA)
   277  	EnvEnableDynamicClusterDistribution = "ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION"
   278  	// EnvEnableGRPCTimeHistogramEnv enables gRPC metrics collection
   279  	EnvEnableGRPCTimeHistogramEnv = "ARGOCD_ENABLE_GRPC_TIME_HISTOGRAM"
   280  	// EnvGithubAppCredsExpirationDuration controls the caching of Github app credentials. This value is in minutes (default: 60)
   281  	EnvGithubAppCredsExpirationDuration = "ARGOCD_GITHUB_APP_CREDS_EXPIRATION_DURATION"
   282  	// EnvHelmIndexCacheDuration controls how the helm repository index file is cached for (default: 0)
   283  	EnvHelmIndexCacheDuration = "ARGOCD_HELM_INDEX_CACHE_DURATION"
   284  	// EnvAppConfigPath allows to override the configuration path for repo server
   285  	EnvAppConfigPath = "ARGOCD_APP_CONF_PATH"
   286  	// EnvAuthToken is the environment variable name for the auth token used by the CLI
   287  	EnvAuthToken = "ARGOCD_AUTH_TOKEN"
   288  	// EnvLogFormat log format that is defined by `--logformat` option
   289  	EnvLogFormat = "ARGOCD_LOG_FORMAT"
   290  	// EnvLogLevel log level that is defined by `--loglevel` option
   291  	EnvLogLevel = "ARGOCD_LOG_LEVEL"
   292  	// EnvLogFormatEnableFullTimestamp enables the FullTimestamp option in logs
   293  	EnvLogFormatEnableFullTimestamp = "ARGOCD_LOG_FORMAT_ENABLE_FULL_TIMESTAMP"
   294  	// EnvLogFormatTimestamp is the timestamp format used in logs
   295  	EnvLogFormatTimestamp = "ARGOCD_LOG_FORMAT_TIMESTAMP"
   296  	// EnvMaxCookieNumber max number of chunks a cookie can be broken into
   297  	EnvMaxCookieNumber = "ARGOCD_MAX_COOKIE_NUMBER"
   298  	// EnvPluginSockFilePath allows to override the pluginSockFilePath for repo server and cmp server
   299  	EnvPluginSockFilePath = "ARGOCD_PLUGINSOCKFILEPATH"
   300  	// EnvCMPChunkSize defines the chunk size in bytes used when sending files to the cmp server
   301  	EnvCMPChunkSize = "ARGOCD_CMP_CHUNK_SIZE"
   302  	// EnvCMPWorkDir defines the full path of the work directory used by the CMP server
   303  	EnvCMPWorkDir = "ARGOCD_CMP_WORKDIR"
   304  	// EnvGPGDataPath overrides the location where GPG keyring for signature verification is stored
   305  	EnvGPGDataPath = "ARGOCD_GPG_DATA_PATH"
   306  	// EnvServer is the server address of the Argo CD API server.
   307  	EnvServer = "ARGOCD_SERVER"
   308  	// EnvServerName is the name of the Argo CD server component, as specified by the value under the LabelKeyAppName label key.
   309  	EnvServerName = "ARGOCD_SERVER_NAME"
   310  	// EnvRepoServerName is the name of the Argo CD repo server component, as specified by the value under the LabelKeyAppName label key.
   311  	EnvRepoServerName = "ARGOCD_REPO_SERVER_NAME"
   312  	// EnvAppControllerName is the name of the Argo CD application controller component, as specified by the value under the LabelKeyAppName label key.
   313  	EnvAppControllerName = "ARGOCD_APPLICATION_CONTROLLER_NAME"
   314  	// EnvRedisName is the name of the Argo CD redis component, as specified by the value under the LabelKeyAppName label key.
   315  	EnvRedisName = "ARGOCD_REDIS_NAME"
   316  	// EnvRedisHaProxyName is the name of the Argo CD Redis HA proxy component, as specified by the value under the LabelKeyAppName label key.
   317  	EnvRedisHaProxyName = "ARGOCD_REDIS_HAPROXY_NAME"
   318  	// EnvGRPCKeepAliveMin defines the GRPCKeepAliveEnforcementMinimum, used in the grpc.KeepaliveEnforcementPolicy. Expects a "Duration" format (e.g. 10s).
   319  	EnvGRPCKeepAliveMin = "ARGOCD_GRPC_KEEP_ALIVE_MIN"
   320  	// EnvServerSideDiff defines the env var used to enable ServerSide Diff feature.
   321  	// If defined, value must be "true" or "false".
   322  	EnvServerSideDiff = "ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF"
   323  	// EnvGRPCMaxSizeMB is the environment variable to look for a max GRPC message size
   324  	EnvGRPCMaxSizeMB = "ARGOCD_GRPC_MAX_SIZE_MB"
   325  )
   326  
   327  // Config Management Plugin related constants
   328  const (
   329  	// DefaultCMPChunkSize defines chunk size in bytes used when sending files to the cmp server
   330  	DefaultCMPChunkSize = 1024
   331  
   332  	// DefaultCMPWorkDirName defines the work directory name used by the cmp-server
   333  	DefaultCMPWorkDirName = "_cmp_server"
   334  
   335  	ConfigMapPluginDeprecationWarning = "argocd-cm plugins are deprecated, and support will be removed in v2.7. Upgrade your plugin to be installed via sidecar. https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/"
   336  )
   337  
   338  const (
   339  	// MinClientVersion is the minimum client version that can interface with this API server.
   340  	// When introducing breaking changes to the API or datastructures, this number should be bumped.
   341  	// The value here may be lower than the current value in VERSION
   342  	MinClientVersion = "1.4.0"
   343  	// CacheVersion is a objects version cached using util/cache/cache.go.
   344  	// Number should be bumped in case of backward incompatible change to make sure cache is invalidated after upgrade.
   345  	CacheVersion = "1.8.3"
   346  )
   347  
   348  // Constants used by util/clusterauth package
   349  const (
   350  	ClusterAuthRequestTimeout = 10 * time.Second
   351  )
   352  
   353  const (
   354  	BearerTokenTimeout = 30 * time.Second
   355  )
   356  
   357  const (
   358  	DefaultGitRetryMaxDuration time.Duration = time.Second * 5        // 5s
   359  	DefaultGitRetryDuration    time.Duration = time.Millisecond * 250 // 0.25s
   360  	DefaultGitRetryFactor                    = int64(2)
   361  )
   362  
   363  // Constants represent the pod selector labels of the Argo CD component names. These values are determined by the
   364  // installation manifests.
   365  const (
   366  	DefaultServerName                = "argocd-server"
   367  	DefaultRepoServerName            = "argocd-repo-server"
   368  	DefaultApplicationControllerName = "argocd-application-controller"
   369  	DefaultRedisName                 = "argocd-redis"
   370  	DefaultRedisHaProxyName          = "argocd-redis-ha-haproxy"
   371  )
   372  
   373  // GetGnuPGHomePath retrieves the path to use for GnuPG home directory, which is either taken from GNUPGHOME environment or a default value
   374  func GetGnuPGHomePath() string {
   375  	gnuPgHome := os.Getenv(EnvGnuPGHome)
   376  	if gnuPgHome == "" {
   377  		return DefaultGnuPgHomePath
   378  	}
   379  	return gnuPgHome
   380  }
   381  
   382  // GetPluginSockFilePath retrieves the path of plugin sock file, which is either taken from PluginSockFilePath environment or a default value
   383  func GetPluginSockFilePath() string {
   384  	pluginSockFilePath := os.Getenv(EnvPluginSockFilePath)
   385  	if pluginSockFilePath == "" {
   386  		return DefaultPluginSockFilePath
   387  	}
   388  	return pluginSockFilePath
   389  }
   390  
   391  // GetCMPChunkSize will return the env var EnvCMPChunkSize value if defined or DefaultCMPChunkSize otherwise.
   392  // If EnvCMPChunkSize is defined but not a valid int, DefaultCMPChunkSize will be returned
   393  func GetCMPChunkSize() int {
   394  	if chunkSizeStr := os.Getenv(EnvCMPChunkSize); chunkSizeStr != "" {
   395  		chunkSize, err := strconv.Atoi(chunkSizeStr)
   396  		if err != nil {
   397  			logrus.Warnf("invalid env var value for %s: not a valid int: %s. Default value will be used.", EnvCMPChunkSize, err)
   398  			return DefaultCMPChunkSize
   399  		}
   400  		return chunkSize
   401  	}
   402  	return DefaultCMPChunkSize
   403  }
   404  
   405  // GetCMPWorkDir will return the full path of the work directory used by the CMP server.
   406  // This directory and all it's contents will be deleted during CMP bootstrap.
   407  func GetCMPWorkDir() string {
   408  	if workDir := os.Getenv(EnvCMPWorkDir); workDir != "" {
   409  		return filepath.Join(workDir, DefaultCMPWorkDirName)
   410  	}
   411  	return filepath.Join(os.TempDir(), DefaultCMPWorkDirName)
   412  }
   413  
   414  const (
   415  	// AnnotationApplicationSetRefresh is an annotation that is added when an ApplicationSet is requested to be refreshed by a webhook. The ApplicationSet controller will remove this annotation at the end of reconciliation.
   416  	AnnotationApplicationSetRefresh = "argocd.argoproj.io/application-set-refresh"
   417  )
   418  
   419  // gRPC settings
   420  const (
   421  	defaultGRPCKeepAliveEnforcementMinimum = 10 * time.Second
   422  )
   423  
   424  func GetGRPCKeepAliveEnforcementMinimum() time.Duration {
   425  	if GRPCKeepAliveMinStr := os.Getenv(EnvGRPCKeepAliveMin); GRPCKeepAliveMinStr != "" {
   426  		GRPCKeepAliveMin, err := time.ParseDuration(GRPCKeepAliveMinStr)
   427  		if err != nil {
   428  			logrus.Warnf("invalid env var value for %s: cannot parse: %s. Default value %s will be used.", EnvGRPCKeepAliveMin, err, defaultGRPCKeepAliveEnforcementMinimum)
   429  			return defaultGRPCKeepAliveEnforcementMinimum
   430  		}
   431  		return GRPCKeepAliveMin
   432  	}
   433  	return defaultGRPCKeepAliveEnforcementMinimum
   434  }
   435  
   436  func GetGRPCKeepAliveTime() time.Duration {
   437  	// GRPCKeepAliveTime is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors
   438  	return 2 * GetGRPCKeepAliveEnforcementMinimum()
   439  }
   440  
   441  // Security severity logging
   442  const (
   443  	SecurityField = "security"
   444  	// SecurityCWEField is the logs field for the CWE associated with a log line. CWE stands for Common Weakness Enumeration. See https://cwe.mitre.org/
   445  	SecurityCWEField                          = "CWE"
   446  	SecurityCWEIncompleteCleanup              = 459
   447  	SecurityCWEMissingReleaseOfFileDescriptor = 775
   448  	SecurityEmergency                         = 5 // Indicates unmistakably malicious events that should NEVER occur accidentally and indicates an active attack (i.e. brute forcing, DoS)
   449  	SecurityCritical                          = 4 // Indicates any malicious or exploitable event that had a side effect (i.e. secrets being left behind on the filesystem)
   450  	SecurityHigh                              = 3 // Indicates likely malicious events but one that had no side effects or was blocked (i.e. out of bounds symlinks in repos)
   451  	SecurityMedium                            = 2 // Could indicate malicious events, but has a high likelihood of being user/system error (i.e. access denied)
   452  	SecurityLow                               = 1 // Unexceptional entries (i.e. successful access logs)
   453  )
   454  
   455  // TokenVerificationError is a generic error message for a failure to verify a JWT
   456  const TokenVerificationError = "failed to verify the token"
   457  
   458  var ErrTokenVerification = errors.New(TokenVerificationError)
   459  
   460  var PermissionDeniedAPIError = status.Error(codes.PermissionDenied, "permission denied")
   461  
   462  // Redis password consts
   463  const (
   464  	// RedisInitialCredentials is the name for the argocd kubernetes secret which will have the redis password
   465  	RedisInitialCredentials = "argocd-redis"
   466  	// RedisInitialCredentialsKey is the key for the argocd kubernetes secret that maps to the redis password
   467  	RedisInitialCredentialsKey = "auth"
   468  )
   469  
   470  /*
   471  SetOptionalRedisPasswordFromKubeConfig sets the optional Redis password if it exists in the k8s namespace's secrets.
   472  
   473  We specify kubeClient as kubernetes.Interface to allow for mocking in tests, but this should be treated as a kubernetes.Clientset param.
   474  */
   475  func SetOptionalRedisPasswordFromKubeConfig(ctx context.Context, kubeClient kubernetes.Interface, namespace string, redisOptions *redis.Options) error {
   476  	secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, RedisInitialCredentials, metav1.GetOptions{})
   477  	if err != nil {
   478  		return fmt.Errorf("failed to get secret %s/%s: %w", namespace, RedisInitialCredentials, err)
   479  	}
   480  	if secret == nil {
   481  		return fmt.Errorf("failed to get secret %s/%s: secret is nil", namespace, RedisInitialCredentials)
   482  	}
   483  	_, ok := secret.Data[RedisInitialCredentialsKey]
   484  	if !ok {
   485  		return fmt.Errorf("secret %s/%s does not contain key %s", namespace, RedisInitialCredentials, RedisInitialCredentialsKey)
   486  	}
   487  	redisOptions.Password = string(secret.Data[RedisInitialCredentialsKey])
   488  	return nil
   489  }