github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/specgen/generate/kube/seccomp.go (about)

     1  package kube
     2  
     3  import (
     4  	"path/filepath"
     5  	"strings"
     6  
     7  	"github.com/containers/podman/v2/libpod"
     8  	"github.com/pkg/errors"
     9  	v1 "k8s.io/api/core/v1"
    10  )
    11  
    12  // KubeSeccompPaths holds information about a pod YAML's seccomp configuration
    13  // it holds both container and pod seccomp paths
    14  type KubeSeccompPaths struct {
    15  	containerPaths map[string]string
    16  	podPath        string
    17  }
    18  
    19  // FindForContainer checks whether a container has a seccomp path configured for it
    20  // if not, it returns the podPath, which should always have a value
    21  func (k *KubeSeccompPaths) FindForContainer(ctrName string) string {
    22  	if path, ok := k.containerPaths[ctrName]; ok {
    23  		return path
    24  	}
    25  	return k.podPath
    26  }
    27  
    28  // InitializeSeccompPaths takes annotations from the pod object metadata and finds annotations pertaining to seccomp
    29  // it parses both pod and container level
    30  // if the annotation is of the form "localhost/%s", the seccomp profile will be set to profileRoot/%s
    31  func InitializeSeccompPaths(annotations map[string]string, profileRoot string) (*KubeSeccompPaths, error) {
    32  	seccompPaths := &KubeSeccompPaths{containerPaths: make(map[string]string)}
    33  	var err error
    34  	if annotations != nil {
    35  		for annKeyValue, seccomp := range annotations {
    36  			// check if it is prefaced with container.seccomp.security.alpha.kubernetes.io/
    37  			prefixAndCtr := strings.Split(annKeyValue, "/")
    38  			if prefixAndCtr[0]+"/" != v1.SeccompContainerAnnotationKeyPrefix {
    39  				continue
    40  			} else if len(prefixAndCtr) != 2 {
    41  				// this could be caused by a user inputting either of
    42  				// container.seccomp.security.alpha.kubernetes.io{,/}
    43  				// both of which are invalid
    44  				return nil, errors.Errorf("Invalid seccomp path: %s", prefixAndCtr[0])
    45  			}
    46  
    47  			path, err := verifySeccompPath(seccomp, profileRoot)
    48  			if err != nil {
    49  				return nil, err
    50  			}
    51  			seccompPaths.containerPaths[prefixAndCtr[1]] = path
    52  		}
    53  
    54  		podSeccomp, ok := annotations[v1.SeccompPodAnnotationKey]
    55  		if ok {
    56  			seccompPaths.podPath, err = verifySeccompPath(podSeccomp, profileRoot)
    57  		} else {
    58  			seccompPaths.podPath, err = libpod.DefaultSeccompPath()
    59  		}
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  	}
    64  	return seccompPaths, nil
    65  }
    66  
    67  // verifySeccompPath takes a path and checks whether it is a default, unconfined, or a path
    68  // the available options are parsed as defined in https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp
    69  func verifySeccompPath(path string, profileRoot string) (string, error) {
    70  	switch path {
    71  	case v1.DeprecatedSeccompProfileDockerDefault:
    72  		fallthrough
    73  	case v1.SeccompProfileRuntimeDefault:
    74  		return libpod.DefaultSeccompPath()
    75  	case "unconfined":
    76  		return path, nil
    77  	default:
    78  		parts := strings.Split(path, "/")
    79  		if parts[0] == "localhost" {
    80  			return filepath.Join(profileRoot, parts[1]), nil
    81  		}
    82  		return "", errors.Errorf("invalid seccomp path: %s", path)
    83  	}
    84  }