Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SA lookup grace period pod annotations #240

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ bin
/certs/
SAMToolkit.*
coverage.out
# Devenv
.devenv*
devenv.*

# direnv
.direnv

# pre-commit
.pre-commit-config.yaml
66 changes: 34 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ certificates API.
# optional: Defaults to 86400, or value specified in ServiceAccount
# annotation as shown in previous step, for expirationSeconds if not set
eks.amazonaws.com/token-expiration: "86400"
# optional: Allow time for the SA cache to sync, in milliseconds. Defaults to 0 (disabled).
eks.amazonaws.com/service-account-lookup-grace-period: "250"
spec:
serviceAccountName: my-serviceaccount
initContainers:
Expand Down Expand Up @@ -143,38 +145,38 @@ When running a container with a non-root user, you need to give the container ac

```
Usage of amazon-eks-pod-identity-webhook:
--add_dir_header If true, adds the file directory to the header
--alsologtostderr log to standard error as well as files
--annotation-prefix string The Service Account annotation to look for (default "eks.amazonaws.com")
--aws-default-region string If set, AWS_DEFAULT_REGION and AWS_REGION will be set to this value in mutated containers
--enable-debugging-handlers Enable debugging handlers. Currently /debug/alpha/cache is supported
--in-cluster Use in-cluster authentication and certificate request API (default true)
--kube-api string (out-of-cluster) The url to the API server
--kubeconfig string (out-of-cluster) Absolute path to the API server kubeconfig file
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--metrics-port int Port to listen on for metrics (http) (default 9999)
--namespace string (in-cluster) The namespace name this webhook, the TLS secret, and configmap resides in (default "eks")
--port int Port to listen on (default 443)
--service-name string (in-cluster) The service name fronting this webhook (default "pod-identity-webhook")
--service-account-lookup-grace-period The grace period for service account to be available in cache before not mutating a pod. Set to 0 to deactivate waiting. Carefully use higher values as it may have significant impact on Kubernetes' pod scheduling performance. (default 100ms)
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--sts-regional-endpoint false Whether to inject the AWS_STS_REGIONAL_ENDPOINTS=regional env var in mutated pods. Defaults to false.
--tls-cert string (out-of-cluster) TLS certificate file path (default "/etc/webhook/certs/tls.crt")
--tls-key string (out-of-cluster) TLS key file path (default "/etc/webhook/certs/tls.key")
--tls-secret string (in-cluster) The secret name for storing the TLS serving cert (default "pod-identity-webhook")
--token-audience string The default audience for tokens. Can be overridden by annotation (default "sts.amazonaws.com")
--token-expiration int The token expiration (default 86400)
--token-mount-path string The path to mount tokens (default "/var/run/secrets/eks.amazonaws.com/serviceaccount")
-v, --v Level number for the log level verbosity
--version Display the version and exit
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
--watch-config-map Enables watching serviceaccounts that are configured through the pod-identity-webhook configmap instead of using annotations
--add_dir_header If true, adds the file directory to the header
--alsologtostderr log to standard error as well as files
--annotation-prefix string The Service Account annotation to look for (default "eks.amazonaws.com")
--aws-default-region string If set, AWS_DEFAULT_REGION and AWS_REGION will be set to this value in mutated containers
--enable-debugging-handlers Enable debugging handlers. Currently /debug/alpha/cache is supported
--in-cluster Use in-cluster authentication and certificate request API (default true)
--kube-api string (out-of-cluster) The url to the API server
--kubeconfig string (out-of-cluster) Absolute path to the API server kubeconfig file
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--metrics-port int Port to listen on for metrics (http) (default 9999)
--namespace string (in-cluster) The namespace name this webhook, the TLS secret, and configmap resides in (default "eks")
--port int Port to listen on (default 443)
--service-account-lookup-grace-period int The grace period, in milliseconds, for service account to be available in cache before not mutating a pod. Set to 0 to deactivate waiting. Carefully use higher values as it may have significant impact on Kubernetes' pod scheduling performance. (default 0)
--service-name string (in-cluster) The service name fronting this webhook (default "pod-identity-webhook")
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--sts-regional-endpoint false Whether to inject the AWS_STS_REGIONAL_ENDPOINTS=regional env var in mutated pods. Defaults to false.
--tls-cert string (out-of-cluster) TLS certificate file path (default "/etc/webhook/certs/tls.crt")
--tls-key string (out-of-cluster) TLS key file path (default "/etc/webhook/certs/tls.key")
--tls-secret string (in-cluster) The secret name for storing the TLS serving cert (default "pod-identity-webhook")
--token-audience string The default audience for tokens. Can be overridden by annotation (default "sts.amazonaws.com")
--token-expiration int The token expiration, in seconds (default 86400)
--token-mount-path string The path to mount tokens (default "/var/run/secrets/eks.amazonaws.com/serviceaccount")
-v, --v Level number for the log level verbosity
--version Display the version and exit
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
--watch-config-map Enables watching serviceaccounts that are configured through the pod-identity-webhook configmap instead of using annotations
```

### AWS_DEFAULT_REGION Injection
Expand Down
29 changes: 0 additions & 29 deletions pkg/annotations.go

This file was deleted.

35 changes: 35 additions & 0 deletions pkg/annotations/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright 2010 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at

http://www.apache.org/licenses/LICENSE-2.0

or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
*/
package annotations

const (
// The audience annotation
AudienceAnnotation = "audience"
// Role ARN annotation
RoleARNAnnotation = "role-arn"
// A true/false value to add AWS_STS_REGIONAL_ENDPOINTS. Overrides any setting on the webhook
UseRegionalSTSAnnotation = "sts-regional-endpoints"
// Expiration in seconds for serviceAccountToken annotation
TokenExpirationAnnotation = "token-expiration"

// A comma-separated list of container names to skip adding environment variables and volumes to. Applies to `initContainers` and `containers`
SkipContainersAnnotation = "skip-containers"

// The grace period, in milliseconds, for service account to be available in
// cache before not mutating a pod. Set to 0 to deactivate waiting.
// Carefully use higher values as it may have significant impact on
// Kubernetes' pod scheduling performance. (default 0)
SALookupGracePeriod = "service-account-lookup-grace-period"
)
123 changes: 123 additions & 0 deletions pkg/annotations/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at

http://www.apache.org/licenses/LICENSE-2.0

or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
*/

package annotations

import (
"encoding/csv"
"strconv"
"strings"
"time"

"github.com/aws/amazon-eks-pod-identity-webhook/pkg"
corev1 "k8s.io/api/core/v1"
"k8s.io/klog/v2"
)

type PodAnnotations struct {
tokenExpiration *int64
containersToSkip map[string]bool
saLookupGracePeriod *time.Duration
}

func (a *PodAnnotations) GetContainersToSkip() map[string]bool {
return a.containersToSkip
}

func (a *PodAnnotations) GetTokenExpiration(fallback int64) int64 {
if a.tokenExpiration == nil {
return fallback
} else {
return *a.tokenExpiration
}
}

func (a *PodAnnotations) GetSALookupGracePeriod(fallback time.Duration) time.Duration {
if a.saLookupGracePeriod == nil {
return fallback
} else {
return *a.saLookupGracePeriod
}
}

// parsePodAnnotations parses the pod annotations that can influence mutation:
// - tokenExpiration. Overrides the given service account annotation/flag-level
// setting.
// - containersToSkip. A Pod specific setting since certain containers within a
// specific pod might need to be opted-out of mutation
func ParsePodAnnotations(pod *corev1.Pod, annotationDomain string) *PodAnnotations {
return &PodAnnotations{
tokenExpiration: parseTokenExpiration(annotationDomain, pod),
containersToSkip: parseContainersToSkip(annotationDomain, pod),
saLookupGracePeriod: parseSALookupGracePeriod(annotationDomain, pod),
}
}

// parseContainersToSkip returns the containers of a pod to skip mutating
func parseContainersToSkip(annotationDomain string, pod *corev1.Pod) map[string]bool {
skippedNames := map[string]bool{}
skipContainersKey := annotationDomain + "/" + SkipContainersAnnotation

value, ok := pod.Annotations[skipContainersKey]
if !ok {
return nil
}
r := csv.NewReader(strings.NewReader(value))
// error means we don't skip any
podNames, err := r.Read()
if err != nil {
klog.Infof("Could not parse skip containers annotation on pod %s/%s: %v", pod.Namespace, pod.Name, err)
return nil
}
for _, name := range podNames {
skippedNames[name] = true
}
return skippedNames
}

func parseTokenExpiration(annotationDomain string, pod *corev1.Pod) *int64 {
expirationKey := annotationDomain + "/" + TokenExpirationAnnotation
expirationStr, ok := pod.Annotations[expirationKey]
if !ok {
return nil
}

expiration, err := strconv.ParseInt(expirationStr, 10, 64)
if err != nil {
klog.V(4).Infof("Found invalid value for token expiration on the pod annotation: %s, falling back to the default: %v", expirationStr, err)
return nil
}

val := pkg.ValidateMinTokenExpiration(expiration)
return &val
}

func parseSALookupGracePeriod(annotationDomain string, pod *corev1.Pod) *time.Duration {
gracePeriodKey := annotationDomain + "/" + SALookupGracePeriod

gracePeriodStr, ok := pod.Annotations[gracePeriodKey]
if !ok {
return nil
}

gracePeriod, err := strconv.ParseInt(gracePeriodStr, 10, 64)
if err != nil {
klog.V(4).Infof("Found invalid value for SA lookup grace period on the pod annotation: %s, falling back to the default: %v", gracePeriodStr, err)
return nil
}

val := time.Duration(gracePeriod) * time.Millisecond
return &val
}
Loading
Loading