// NewContainer creates a new Entity for the provided kube.Container. Container must be valid. func NewContainer(container kube.Container, defaults kube.ObjectMeta, source string, objects ...deploy.KubeObject) (*Container, error) { err := validateContainer(container) if err != nil { return nil, fmt.Errorf("could not create Container from `%s`: %v", source, err) } base, err := newBase(EntityContainer, defaults, source, objects) if err != nil { return nil, err } newContainer := Container{base: base} if len(container.Image) != 0 { image, err := image.FromString(container.Image) if err != nil { return nil, err } newContainer.image, err = NewImage(image, defaults, source) if err != nil { return nil, err } container.Image = "placeholder" } newContainer.container = container return &newContainer, nil }
func admissionTestPod() *kapi.Pod { pod := &kapi.Pod{} pod.Name = "test-pod" container := kapi.Container{} container.Name = "foo" container.Image = "openshift/hello-openshift" pod.Spec.Containers = []kapi.Container{container} return pod }
// ToAPIPod converts Pod to api.Pod. Note that if a field in api.Pod has no // corresponding field in Pod, the field would not be populated. func (p *Pod) ToAPIPod() *api.Pod { var pod api.Pod pod.UID = p.ID pod.Name = p.Name pod.Namespace = p.Namespace for _, c := range p.Containers { var container api.Container container.Name = c.Name container.Image = c.Image pod.Spec.Containers = append(pod.Spec.Containers, container) } return &pod }
func convert_v1beta3_Container_To_api_Container(in *Container, out *api.Container, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*Container))(in) } out.Name = in.Name out.Image = in.Image if in.Command != nil { out.Command = make([]string, len(in.Command)) for i := range in.Command { out.Command[i] = in.Command[i] } } if in.Args != nil { out.Args = make([]string, len(in.Args)) for i := range in.Args { out.Args[i] = in.Args[i] } } out.WorkingDir = in.WorkingDir if in.Ports != nil { out.Ports = make([]api.ContainerPort, len(in.Ports)) for i := range in.Ports { if err := convert_v1beta3_ContainerPort_To_api_ContainerPort(&in.Ports[i], &out.Ports[i], s); err != nil { return err } } } if in.Env != nil { out.Env = make([]api.EnvVar, len(in.Env)) for i := range in.Env { if err := convert_v1beta3_EnvVar_To_api_EnvVar(&in.Env[i], &out.Env[i], s); err != nil { return err } } } if err := s.Convert(&in.Resources, &out.Resources, 0); err != nil { return err } if in.VolumeMounts != nil { out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) for i := range in.VolumeMounts { if err := convert_v1beta3_VolumeMount_To_api_VolumeMount(&in.VolumeMounts[i], &out.VolumeMounts[i], s); err != nil { return err } } } if in.LivenessProbe != nil { out.LivenessProbe = new(api.Probe) if err := convert_v1beta3_Probe_To_api_Probe(in.LivenessProbe, out.LivenessProbe, s); err != nil { return err } } else { out.LivenessProbe = nil } if in.ReadinessProbe != nil { out.ReadinessProbe = new(api.Probe) if err := convert_v1beta3_Probe_To_api_Probe(in.ReadinessProbe, out.ReadinessProbe, s); err != nil { return err } } else { out.ReadinessProbe = nil } if in.Lifecycle != nil { out.Lifecycle = new(api.Lifecycle) if err := convert_v1beta3_Lifecycle_To_api_Lifecycle(in.Lifecycle, out.Lifecycle, s); err != nil { return err } } else { out.Lifecycle = nil } out.TerminationMessagePath = in.TerminationMessagePath out.ImagePullPolicy = api.PullPolicy(in.ImagePullPolicy) if in.SecurityContext != nil { if in.SecurityContext.Capabilities != nil { if !reflect.DeepEqual(in.SecurityContext.Capabilities.Add, in.Capabilities.Add) || !reflect.DeepEqual(in.SecurityContext.Capabilities.Drop, in.Capabilities.Drop) { return fmt.Errorf("container capability settings do not match security context settings, cannot convert") } } if in.SecurityContext.Privileged != nil { if in.Privileged != *in.SecurityContext.Privileged { return fmt.Errorf("container privileged settings do not match security context settings, cannot convert") } } } if in.SecurityContext != nil { out.SecurityContext = new(api.SecurityContext) if err := convert_v1beta3_SecurityContext_To_api_SecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { return err } } else { out.SecurityContext = nil } out.Stdin = in.Stdin out.TTY = in.TTY return nil }
func deepCopy_api_Container(in api.Container, out *api.Container, c *conversion.Cloner) error { out.Name = in.Name out.Image = in.Image if in.Command != nil { out.Command = make([]string, len(in.Command)) for i := range in.Command { out.Command[i] = in.Command[i] } } else { out.Command = nil } if in.Args != nil { out.Args = make([]string, len(in.Args)) for i := range in.Args { out.Args[i] = in.Args[i] } } else { out.Args = nil } out.WorkingDir = in.WorkingDir if in.Ports != nil { out.Ports = make([]api.ContainerPort, len(in.Ports)) for i := range in.Ports { if err := deepCopy_api_ContainerPort(in.Ports[i], &out.Ports[i], c); err != nil { return err } } } else { out.Ports = nil } if in.Env != nil { out.Env = make([]api.EnvVar, len(in.Env)) for i := range in.Env { if err := deepCopy_api_EnvVar(in.Env[i], &out.Env[i], c); err != nil { return err } } } else { out.Env = nil } if err := deepCopy_api_ResourceRequirements(in.Resources, &out.Resources, c); err != nil { return err } if in.VolumeMounts != nil { out.VolumeMounts = make([]api.VolumeMount, len(in.VolumeMounts)) for i := range in.VolumeMounts { if err := deepCopy_api_VolumeMount(in.VolumeMounts[i], &out.VolumeMounts[i], c); err != nil { return err } } } else { out.VolumeMounts = nil } if in.LivenessProbe != nil { out.LivenessProbe = new(api.Probe) if err := deepCopy_api_Probe(*in.LivenessProbe, out.LivenessProbe, c); err != nil { return err } } else { out.LivenessProbe = nil } if in.ReadinessProbe != nil { out.ReadinessProbe = new(api.Probe) if err := deepCopy_api_Probe(*in.ReadinessProbe, out.ReadinessProbe, c); err != nil { return err } } else { out.ReadinessProbe = nil } if in.Lifecycle != nil { out.Lifecycle = new(api.Lifecycle) if err := deepCopy_api_Lifecycle(*in.Lifecycle, out.Lifecycle, c); err != nil { return err } } else { out.Lifecycle = nil } out.TerminationMessagePath = in.TerminationMessagePath out.ImagePullPolicy = in.ImagePullPolicy if in.SecurityContext != nil { out.SecurityContext = new(api.SecurityContext) if err := deepCopy_api_SecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil { return err } } else { out.SecurityContext = nil } out.Stdin = in.Stdin out.TTY = in.TTY return nil }
func TestEnforcingServiceAccount(t *testing.T) { masterConfig, err := testserver.DefaultMasterOptions() masterConfig.ServiceAccountConfig.LimitSecretReferences = false if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminConfig, err := testserver.StartConfiguredMaster(masterConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } // Get a service account token saToken, err := waitForServiceAccountToken(clusterAdminKubeClient, api.NamespaceDefault, serviceaccountadmission.DefaultServiceAccountName, 20, time.Second) if err != nil { t.Errorf("unexpected error: %v", err) } if len(saToken) == 0 { t.Errorf("token was not created") } pod := &api.Pod{} pod.Name = "foo" pod.Namespace = api.NamespaceDefault pod.Spec.ServiceAccountName = serviceaccountadmission.DefaultServiceAccountName container := api.Container{} container.Name = "foo" container.Image = "openshift/hello-openshift" pod.Spec.Containers = []api.Container{container} secretVolume := api.Volume{} secretVolume.Name = "bar-vol" secretVolume.Secret = &api.SecretVolumeSource{} secretVolume.Secret.SecretName = "bar" pod.Spec.Volumes = []api.Volume{secretVolume} err = wait.Poll(100*time.Millisecond, 5*time.Second, func() (bool, error) { if _, err := clusterAdminKubeClient.Pods(api.NamespaceDefault).Create(pod); err != nil { // The SA admission controller cache seems to take forever to update. This check comes after the limit check, so until we get it sorted out // check if we're getting this particular error if strings.Contains(err.Error(), "no API token found for service account") { return true, nil } t.Log(err) return false, nil } return true, nil }) if err != nil { t.Errorf("unexpected error: %v", err) } clusterAdminKubeClient.Pods(api.NamespaceDefault).Delete(pod.Name, nil) sa, err := clusterAdminKubeClient.ServiceAccounts(api.NamespaceDefault).Get(bootstrappolicy.DeployerServiceAccountName) if err != nil { t.Fatalf("unexpected error: %v", err) } if sa.Annotations == nil { sa.Annotations = map[string]string{} } sa.Annotations[serviceaccountadmission.EnforceMountableSecretsAnnotation] = "true" time.Sleep(5) _, err = clusterAdminKubeClient.ServiceAccounts(api.NamespaceDefault).Update(sa) if err != nil { t.Fatalf("unexpected error: %v", err) } expectedMessage := "is not allowed because service account deployer does not reference that secret" pod.Spec.ServiceAccountName = bootstrappolicy.DeployerServiceAccountName err = wait.Poll(100*time.Millisecond, 5*time.Second, func() (bool, error) { if _, err := clusterAdminKubeClient.Pods(api.NamespaceDefault).Create(pod); err == nil || !strings.Contains(err.Error(), expectedMessage) { clusterAdminKubeClient.Pods(api.NamespaceDefault).Delete(pod.Name, nil) return false, nil } return true, nil }) if err != nil { t.Errorf("unexpected error: %v", err) } }
func writePodContainer(m map[string]interface{}, item *api.Container) error { if x, ok := m["name"].(string); ok { item.Name = x } if x, ok := m["image"].(string); ok { item.Image = x } if x, ok := m["image_pull_policy"].(string); ok { item.ImagePullPolicy = api.PullPolicy(x) } if x, ok := m["termination_message_path"].(string); ok { item.TerminationMessagePath = x } if x, ok := m["working_dir"].(string); ok { item.WorkingDir = x } if x, ok := m["command"].([]interface{}); ok { for _, y := range x { item.Command = append(item.Command, y.(string)) } } if x, ok := m["args"].([]interface{}); ok { for _, y := range x { item.Args = append(item.Args, y.(string)) } } if x, ok := m["port"].([]interface{}); ok { for _, y := range x { ref := api.ContainerPort{} writeContainerPort(y.(map[string]interface{}), &ref) item.Ports = append(item.Ports, ref) } } if x, ok := m["env"].([]interface{}); ok { for _, y := range x { ref := api.EnvVar{} writeEnvVar(y.(map[string]interface{}), &ref) item.Env = append(item.Env, ref) } } if x, ok := m["volume_mount"].([]interface{}); ok { for _, y := range x { ref := api.VolumeMount{} writeVolumeMount(y.(map[string]interface{}), &ref) item.VolumeMounts = append(item.VolumeMounts, ref) } } if n, ok := extractSingleMap(m["liveness_probe"]); ok { item.LivenessProbe = &api.Probe{} writeProbe(n, item.LivenessProbe) } if n, ok := extractSingleMap(m["readiness_probe"]); ok { item.ReadinessProbe = &api.Probe{} writeProbe(n, item.ReadinessProbe) } if n, ok := extractSingleMap(m["resources"]); ok { if o, ok := extractSingleMap(n["limits"]); ok { item.Resources.Limits = make(api.ResourceList) if x, ok := o["cpu"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Limits[api.ResourceCPU] = *q } if x, ok := o["memory"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Limits[api.ResourceMemory] = *q } } if o, ok := extractSingleMap(n["requests"]); ok { item.Resources.Requests = make(api.ResourceList) if x, ok := o["cpu"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Requests[api.ResourceCPU] = *q } if x, ok := o["memory"].(string); ok && x != "" { q, err := resource.ParseQuantity(x) if err != nil { return fmt.Errorf("%s for %q", err, x) } item.Resources.Requests[api.ResourceMemory] = *q } } } return nil }