func (p *provision) Admit(a admission.Attributes) (err error) { defaultVersion, kind, err := api.RESTMapper.VersionAndKindForResource(a.GetResource()) if err != nil { return admission.NewForbidden(a, err) } mapping, err := api.RESTMapper.RESTMapping(kind, defaultVersion) if err != nil { return admission.NewForbidden(a, err) } if mapping.Scope.Name() != meta.RESTScopeNameNamespace { return nil } namespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: a.GetNamespace(), Namespace: "", }, Status: api.NamespaceStatus{}, } _, exists, err := p.store.Get(namespace) if err != nil { return admission.NewForbidden(a, err) } if exists { return nil } _, err = p.client.Namespaces().Create(namespace) if err != nil && !errors.IsAlreadyExists(err) { return admission.NewForbidden(a, err) } return nil }
// CreateMasterServiceIfNeeded will create the specified service if it // doesn't already exist. func (c *Controller) CreateMasterServiceIfNeeded(serviceName string, serviceIP net.IP, servicePort int) error { ctx := api.NewDefaultContext() if _, err := c.ServiceRegistry.GetService(ctx, serviceName); err == nil { // The service already exists. return nil } svc := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: serviceName, Namespace: api.NamespaceDefault, Labels: map[string]string{"provider": "kubernetes", "component": "apiserver"}, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{Port: servicePort, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(servicePort)}}, // maintained by this code, not by the pod selector Selector: nil, ClusterIP: serviceIP.String(), SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, }, } if err := rest.BeforeCreate(rest.Services, ctx, svc); err != nil { return err } _, err := c.ServiceRegistry.CreateService(ctx, svc) if err != nil && errors.IsAlreadyExists(err) { err = nil } return err }
// createSchedulerServiceIfNeeded will create the specified service if it // doesn't already exist. func (m *SchedulerServer) createSchedulerServiceIfNeeded(serviceName string, servicePort int) error { ctx := api.NewDefaultContext() if _, err := m.client.Services(api.NamespaceValue(ctx)).Get(serviceName); err == nil { // The service already exists. return nil } svc := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: serviceName, Namespace: api.NamespaceDefault, Labels: map[string]string{"provider": "k8sm", "component": "scheduler"}, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{Port: servicePort, Protocol: api.ProtocolTCP}}, // maintained by this code, not by the pod selector Selector: nil, SessionAffinity: api.ServiceAffinityNone, }, } if m.ServiceAddress != nil { svc.Spec.ClusterIP = m.ServiceAddress.String() } _, err := m.client.Services(api.NamespaceValue(ctx)).Create(svc) if err != nil && errors.IsAlreadyExists(err) { err = nil } return err }
func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, setFn SetFunc) { ctx := t.TestContext() foo := copyOrDie(obj) t.setObjectMeta(foo, "foo1") if err := setFn(ctx, foo); err != nil { t.Errorf("unexpected error: %v", err) } _, err := t.storage.(rest.Creater).Create(ctx, foo) if !errors.IsAlreadyExists(err) { t.Errorf("expected already exists err, got %v", err) } }
// CheckGeneratedNameError checks whether an error that occurred creating a resource is due // to generation being unable to pick a valid name. func CheckGeneratedNameError(strategy RESTCreateStrategy, err error, obj runtime.Object) error { if !errors.IsAlreadyExists(err) { return err } objectMeta, kind, kerr := objectMetaAndKind(strategy, obj) if kerr != nil { return kerr } if len(objectMeta.GenerateName) == 0 { return err } return errors.NewServerTimeout(kind, "POST", 0) }
// CreateNamespaceIfNeeded will create the namespace that contains the master services if it doesn't already exist func (c *Controller) CreateNamespaceIfNeeded(ns string) error { ctx := api.NewContext() if _, err := c.NamespaceRegistry.GetNamespace(ctx, api.NamespaceDefault); err == nil { // the namespace already exists return nil } newNs := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: ns, Namespace: "", }, } err := c.NamespaceRegistry.CreateNamespace(ctx, newNs) if err != nil && errors.IsAlreadyExists(err) { err = nil } return err }
// recordEvent attempts to write event to a sink. It returns true if the event // was successfully recorded or discarded, false if it should be retried. // If updateExistingEvent is false, it creates a new event, otherwise it updates // existing event. func recordEvent(sink EventSink, event *api.Event, updateExistingEvent bool, eventCache *historyCache) bool { var newEvent *api.Event var err error if updateExistingEvent { newEvent, err = sink.Update(event) } // Update can fail because the event may have been removed and it no longer exists. if !updateExistingEvent || (updateExistingEvent && isKeyNotFoundError(err)) { // Making sure that ResourceVersion is empty on creation event.ResourceVersion = "" newEvent, err = sink.Create(event) } if err == nil { eventCache.addOrUpdateEvent(newEvent) return true } // If we can't contact the server, then hold everything while we keep trying. // Otherwise, something about the event is malformed and we should abandon it. switch err.(type) { case *client.RequestConstructionError: // We will construct the request the same next time, so don't keep trying. glog.Errorf("Unable to construct event '%#v': '%v' (will not retry!)", event, err) return true case *errors.StatusError: if errors.IsAlreadyExists(err) { glog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err) } else { glog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err) } return true case *errors.UnexpectedObjectError: // We don't expect this; it implies the server's response didn't match a // known pattern. Go ahead and retry. default: // This case includes actual http transport errors. Go ahead and retry. } glog.Errorf("Unable to write event: '%v' (may retry after sleeping)", err) return false }
func TestServiceAccountTokenAuthentication(t *testing.T) { c, config, stopFunc := startServiceAccountTestServer(t) defer stopFunc() myns := "auth-ns" otherns := "other-ns" // Create "my" namespace _, err := c.Namespaces().Create(&api.Namespace{ObjectMeta: api.ObjectMeta{Name: myns}}) if err != nil && !errors.IsAlreadyExists(err) { t.Fatalf("could not create namespace: %v", err) } // Create "other" namespace _, err = c.Namespaces().Create(&api.Namespace{ObjectMeta: api.ObjectMeta{Name: otherns}}) if err != nil && !errors.IsAlreadyExists(err) { t.Fatalf("could not create namespace: %v", err) } // Create "ro" user in myns _, err = c.ServiceAccounts(myns).Create(&api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: readOnlyServiceAccountName}}) if err != nil { t.Fatalf("Service Account not created: %v", err) } roTokenName, roToken, err := getReferencedServiceAccountToken(c, myns, readOnlyServiceAccountName, true) if err != nil { t.Fatal(err) } roClientConfig := config roClientConfig.BearerToken = roToken roClient := client.NewOrDie(&roClientConfig) doServiceAccountAPIRequests(t, roClient, myns, true, true, false) doServiceAccountAPIRequests(t, roClient, otherns, true, false, false) err = c.Secrets(myns).Delete(roTokenName) if err != nil { t.Fatalf("could not delete token: %v", err) } doServiceAccountAPIRequests(t, roClient, myns, false, false, false) // Create "rw" user in myns _, err = c.ServiceAccounts(myns).Create(&api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: readWriteServiceAccountName}}) if err != nil { t.Fatalf("Service Account not created: %v", err) } _, rwToken, err := getReferencedServiceAccountToken(c, myns, readWriteServiceAccountName, true) if err != nil { t.Fatal(err) } rwClientConfig := config rwClientConfig.BearerToken = rwToken rwClient := client.NewOrDie(&rwClientConfig) doServiceAccountAPIRequests(t, rwClient, myns, true, true, true) doServiceAccountAPIRequests(t, rwClient, otherns, true, false, false) // Get default user and token which should have been automatically created _, defaultToken, err := getReferencedServiceAccountToken(c, myns, "default", true) if err != nil { t.Fatalf("could not get default user and token: %v", err) } defaultClientConfig := config defaultClientConfig.BearerToken = defaultToken defaultClient := client.NewOrDie(&defaultClientConfig) doServiceAccountAPIRequests(t, defaultClient, myns, true, false, false) }
func TestServiceAccountTokenAutoMount(t *testing.T) { c, _, stopFunc := startServiceAccountTestServer(t) defer stopFunc() ns := "auto-mount-ns" // Create "my" namespace _, err := c.Namespaces().Create(&api.Namespace{ObjectMeta: api.ObjectMeta{Name: ns}}) if err != nil && !errors.IsAlreadyExists(err) { t.Fatalf("could not create namespace: %v", err) } // Get default token defaultTokenName, _, err := getReferencedServiceAccountToken(c, ns, serviceaccountadmission.DefaultServiceAccountName, true) if err != nil { t.Fatal(err) } // Pod to create protoPod := api.Pod{ ObjectMeta: api.ObjectMeta{Name: "protopod"}, Spec: api.PodSpec{ Containers: []api.Container{ { Name: "container-1", Image: "container-1-image", }, { Name: "container-2", Image: "container-2-image", VolumeMounts: []api.VolumeMount{ {Name: "empty-dir", MountPath: serviceaccountadmission.DefaultAPITokenMountPath}, }, }, }, Volumes: []api.Volume{ { Name: "empty-dir", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}, }, }, }, } // Pod we expect to get created expectedServiceAccount := serviceaccountadmission.DefaultServiceAccountName expectedVolumes := append(protoPod.Spec.Volumes, api.Volume{ Name: defaultTokenName, VolumeSource: api.VolumeSource{ Secret: &api.SecretVolumeSource{ SecretName: defaultTokenName, }, }, }) expectedContainer1VolumeMounts := []api.VolumeMount{ {Name: defaultTokenName, MountPath: serviceaccountadmission.DefaultAPITokenMountPath, ReadOnly: true}, } expectedContainer2VolumeMounts := protoPod.Spec.Containers[1].VolumeMounts createdPod, err := c.Pods(ns).Create(&protoPod) if err != nil { t.Fatal(err) } if createdPod.Spec.ServiceAccountName != expectedServiceAccount { t.Fatalf("Expected %s, got %s", expectedServiceAccount, createdPod.Spec.ServiceAccountName) } if !api.Semantic.DeepEqual(&expectedVolumes, &createdPod.Spec.Volumes) { t.Fatalf("Expected\n\t%#v\n\tgot\n\t%#v", expectedVolumes, createdPod.Spec.Volumes) } if !api.Semantic.DeepEqual(&expectedContainer1VolumeMounts, &createdPod.Spec.Containers[0].VolumeMounts) { t.Fatalf("Expected\n\t%#v\n\tgot\n\t%#v", expectedContainer1VolumeMounts, createdPod.Spec.Containers[0].VolumeMounts) } if !api.Semantic.DeepEqual(&expectedContainer2VolumeMounts, &createdPod.Spec.Containers[1].VolumeMounts) { t.Fatalf("Expected\n\t%#v\n\tgot\n\t%#v", expectedContainer2VolumeMounts, createdPod.Spec.Containers[1].VolumeMounts) } }