Skip to content

Commit

Permalink
feat: Add support for Service Account Impersonation. (#445)
Browse files Browse the repository at this point in the history
Now users can configure the proxy's --service-account-impersonation parameter.

Fixes #392
  • Loading branch information
hessjcg authored Oct 24, 2023
1 parent 1eaf019 commit 4d8e277
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ spec:
minimum: 1
type: integer
type: object
authentication:
description: Authentication specifies the config for how the proxy authenticates itself to the Google Cloud API.
properties:
impersonationChain:
description: ImpersonationChain is a list of one or more service accounts. The first entry in the chain is the impersonation target. Any additional service accounts after the target are delegates. The roles/iam.serviceAccountTokenCreator must be configured for each account that will be impersonated. This sets the --impersonate-service-account flag on the proxy.
items:
type: string
type: array
type: object
container:
description: Container is debugging parameter that when specified will override the proxy container with a completely custom Container spec.
properties:
Expand Down
15 changes: 15 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ _Appears in:_
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#resourcerequirements-v1-core)_ | Resources specifies the resources required for the proxy pod. |
| `telemetry` _[TelemetrySpec](#telemetryspec)_ | Telemetry specifies how the proxy should expose telemetry. Optional, by default |
| `adminServer` _[AdminServerSpec](#adminserverspec)_ | AdminServer specifies the config for the proxy's admin service which is available to other containers in the same pod. |
| `authentication` _[AuthenticationSpec](#authenticationspec)_ | Authentication specifies the config for how the proxy authenticates itself to the Google Cloud API. |
| `maxConnections` _integer_ | MaxConnections limits the number of connections. Default value is no limit. This sets the proxy container's CLI argument `--max-connections` |
| `maxSigtermDelay` _integer_ | MaxSigtermDelay is the maximum number of seconds to wait for connections to close after receiving a TERM signal. This sets the proxy container's CLI argument `--max-sigterm-delay` and configures `terminationGracePeriodSeconds` on the workload's PodSpec. |
| `sqlAdminAPIEndpoint` _string_ | SQLAdminAPIEndpoint is a debugging parameter that when specified will change the Google Cloud api endpoint used by the proxy. |
Expand Down Expand Up @@ -87,6 +88,20 @@ _Appears in:_
| `authProxyContainer` _[AuthProxyContainerSpec](#authproxycontainerspec)_ | AuthProxyContainer describes the resources and config for the Auth Proxy container. |


#### AuthenticationSpec



AuthenticationSpec specifies how the proxy is authenticated with the Google Cloud SQL Admin API. This configures proxy's --impersonate-service-account flag.

_Appears in:_
- [AuthProxyContainerSpec](#authproxycontainerspec)

| Field | Description |
| --- | --- |
| `impersonationChain` _string array_ | ImpersonationChain is a list of one or more service accounts. The first entry in the chain is the impersonation target. Any additional service accounts after the target are delegates. The roles/iam.serviceAccountTokenCreator must be configured for each account that will be impersonated. This sets the --impersonate-service-account flag on the proxy. |


#### InstanceSpec


Expand Down
9 changes: 9 additions & 0 deletions installer/cloud-sql-proxy-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ spec:
minimum: 1
type: integer
type: object
authentication:
description: Authentication specifies the config for how the proxy authenticates itself to the Google Cloud API.
properties:
impersonationChain:
description: ImpersonationChain is a list of one or more service accounts. The first entry in the chain is the impersonation target. Any additional service accounts after the target are delegates. The roles/iam.serviceAccountTokenCreator must be configured for each account that will be impersonated. This sets the --impersonate-service-account flag on the proxy.
items:
type: string
type: array
type: object
container:
description: Container is debugging parameter that when specified will override the proxy container with a completely custom Container spec.
properties:
Expand Down
9 changes: 9 additions & 0 deletions internal/api/v1/authproxyworkload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ func TestAuthProxyWorkload_ValidateCreate_AuthProxyContainerSpec(t *testing.T) {
},
wantValid: true,
},
{
desc: "Valid, ImpersonationChain set",
spec: cloudsqlapi.AuthProxyContainerSpec{
Authentication: &cloudsqlapi.AuthenticationSpec{
ImpersonationChain: []string{"[email protected]", "[email protected]"},
},
},
wantValid: true,
},
{
desc: "Invalid, Debug set without AdminPort",
spec: cloudsqlapi.AuthProxyContainerSpec{
Expand Down
17 changes: 17 additions & 0 deletions internal/api/v1/authproxyworkload_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ type AuthProxyContainerSpec struct {
// available to other containers in the same pod.
AdminServer *AdminServerSpec `json:"adminServer,omitempty"`

// Authentication specifies the config for how the proxy authenticates itself
// to the Google Cloud API.
Authentication *AuthenticationSpec `json:"authentication,omitempty"`

// MaxConnections limits the number of connections. Default value is no limit.
// This sets the proxy container's CLI argument `--max-connections`
//+kubebuilder:validation:Optional
Expand Down Expand Up @@ -231,6 +235,19 @@ type AdminServerSpec struct {
EnableAPIs []string `json:"enableAPIs,omitempty"`
}

// AuthenticationSpec specifies how the proxy is authenticated with the
// Google Cloud SQL Admin API. This configures proxy's
// --impersonate-service-account flag.
type AuthenticationSpec struct {
// ImpersonationChain is a list of one or more service
// accounts. The first entry in the chain is the impersonation target. Any
// additional service accounts after the target are delegates. The
// roles/iam.serviceAccountTokenCreator must be configured for each account
// that will be impersonated. This sets the --impersonate-service-account
// flag on the proxy.
ImpersonationChain []string `json:"impersonationChain,omitempty"`
}

// TelemetrySpec specifies how the proxy container will expose telemetry.
type TelemetrySpec struct {
// QuotaProject Specifies the project to use for Cloud SQL Admin API quota tracking.
Expand Down
25 changes: 25 additions & 0 deletions internal/api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions internal/workload/podspec_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,9 @@ func (s *updateState) updateContainer(p *cloudsqlapi.AuthProxyWorkload, c *corev
// enable the proxy's admin service
s.addAdminServer(p)

// configure container authentication
s.addAuthentication(p)

// add the user agent
s.addProxyContainerEnvVar(p, "CSQL_PROXY_USER_AGENT", s.updater.userAgent)

Expand Down Expand Up @@ -892,6 +895,17 @@ func (s *updateState) addAdminServer(p *cloudsqlapi.AuthProxyWorkload) {

}

func (s *updateState) addAuthentication(p *cloudsqlapi.AuthProxyWorkload) {
if p.Spec.AuthProxyContainer == nil || p.Spec.AuthProxyContainer.Authentication == nil {
return
}
as := p.Spec.AuthProxyContainer.Authentication
if len(as.ImpersonationChain) > 0 {
s.addProxyContainerEnvVar(p, "CSQL_PROXY_IMPERSONATE_SERVICE_ACCOUNT", strings.Join(as.ImpersonationChain, ","))
}

}

func (s *updateState) addVolumeMount(p *cloudsqlapi.AuthProxyWorkload, is *cloudsqlapi.InstanceSpec, m corev1.VolumeMount, v corev1.Volume) {
key := proxyInstanceID{
AuthProxyWorkload: types.NamespacedName{
Expand Down
40 changes: 22 additions & 18 deletions internal/workload/podspec_updates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ func TestProxyCLIArgs(t *testing.T) {
EnableAPIs: []string{"Debug", "QuitQuitQuit"},
Port: int32(9091),
},
Authentication: &cloudsqlapi.AuthenticationSpec{
ImpersonationChain: []string{"[email protected]", "[email protected]"},
},
MaxConnections: ptr(int64(10)),
MaxSigtermDelay: ptr(int64(20)),
Quiet: true,
Expand All @@ -677,24 +680,25 @@ func TestProxyCLIArgs(t *testing.T) {
fmt.Sprintf("hello:world:one?port=%d", workload.DefaultFirstPort),
},
wantWorkloadEnv: map[string]string{
"CSQL_PROXY_SQLADMIN_API_ENDPOINT": "https://example.com",
"CSQL_PROXY_TELEMETRY_SAMPLE_RATE": "200",
"CSQL_PROXY_PROMETHEUS_NAMESPACE": "hello",
"CSQL_PROXY_TELEMETRY_PROJECT": "telproject",
"CSQL_PROXY_TELEMETRY_PREFIX": "telprefix",
"CSQL_PROXY_HTTP_PORT": "9092",
"CSQL_PROXY_ADMIN_PORT": "9091",
"CSQL_PROXY_DEBUG": "true",
"CSQL_PROXY_QUITQUITQUIT": "true",
"CSQL_PROXY_HEALTH_CHECK": "true",
"CSQL_PROXY_DISABLE_TRACES": "true",
"CSQL_PROXY_DISABLE_METRICS": "true",
"CSQL_PROXY_PROMETHEUS": "true",
"CSQL_PROXY_QUOTA_PROJECT": "qp",
"CSQL_PROXY_MAX_CONNECTIONS": "10",
"CSQL_PROXY_MAX_SIGTERM_DELAY": "20",
"CSQL_PROXY_QUIET": "true",
"CSQL_PROXY_STRUCTURED_LOGS": "true",
"CSQL_PROXY_SQLADMIN_API_ENDPOINT": "https://example.com",
"CSQL_PROXY_TELEMETRY_SAMPLE_RATE": "200",
"CSQL_PROXY_PROMETHEUS_NAMESPACE": "hello",
"CSQL_PROXY_TELEMETRY_PROJECT": "telproject",
"CSQL_PROXY_TELEMETRY_PREFIX": "telprefix",
"CSQL_PROXY_HTTP_PORT": "9092",
"CSQL_PROXY_ADMIN_PORT": "9091",
"CSQL_PROXY_DEBUG": "true",
"CSQL_PROXY_QUITQUITQUIT": "true",
"CSQL_PROXY_HEALTH_CHECK": "true",
"CSQL_PROXY_DISABLE_TRACES": "true",
"CSQL_PROXY_DISABLE_METRICS": "true",
"CSQL_PROXY_PROMETHEUS": "true",
"CSQL_PROXY_QUOTA_PROJECT": "qp",
"CSQL_PROXY_MAX_CONNECTIONS": "10",
"CSQL_PROXY_MAX_SIGTERM_DELAY": "20",
"CSQL_PROXY_IMPERSONATE_SERVICE_ACCOUNT": "[email protected],[email protected]",
"CSQL_PROXY_QUIET": "true",
"CSQL_PROXY_STRUCTURED_LOGS": "true",
},
},
{
Expand Down

0 comments on commit 4d8e277

Please sign in to comment.