github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/specgen/generate/kube/seccomp.go (about)

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