// Create registers the given ReplicationController. func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { controller, ok := obj.(*api.ReplicationController) if !ok { return nil, fmt.Errorf("not a replication controller: %#v", obj) } if !api.ValidNamespace(ctx, &controller.ObjectMeta) { return nil, errors.NewConflict("controller", controller.Namespace, fmt.Errorf("Controller.Namespace does not match the provided context")) } if len(controller.Name) == 0 { controller.Name = util.NewUUID().String() } if errs := validation.ValidateReplicationController(controller); len(errs) > 0 { return nil, errors.NewInvalid("replicationController", controller.Name, errs) } api.FillObjectMetaSystemFields(ctx, &controller.ObjectMeta) return apiserver.MakeAsync(func() (runtime.Object, error) { err := rs.registry.CreateController(ctx, controller) if err != nil { return nil, err } return rs.registry.GetController(ctx, controller.Name) }), nil }
// Create a Secret object func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { secret, ok := obj.(*api.Secret) if !ok { return nil, fmt.Errorf("invalid object type") } if !api.ValidNamespace(ctx, &secret.ObjectMeta) { return nil, errors.NewConflict("secret", secret.Namespace, fmt.Errorf("Secret.Namespace does not match the provided context")) } if len(secret.Name) == 0 { secret.Name = string(util.NewUUID()) } if errs := validation.ValidateSecret(secret); len(errs) > 0 { return nil, errors.NewInvalid("secret", secret.Name, errs) } api.FillObjectMetaSystemFields(ctx, &secret.ObjectMeta) err := rs.registry.CreateWithName(ctx, secret.Name, secret) if err != nil { return nil, err } return rs.registry.Get(ctx, secret.Name) }
// TestFillObjectMetaSystemFields validates that system populated fields are set on an object func TestFillObjectMetaSystemFields(t *testing.T) { ctx := api.NewDefaultContext() resource := api.ObjectMeta{} api.FillObjectMetaSystemFields(ctx, &resource) if resource.CreationTimestamp.Time.IsZero() { t.Errorf("resource.CreationTimestamp is zero") } else if len(resource.UID) == 0 { t.Errorf("resource.UID missing") } }
// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated func TestHasObjectMetaSystemFieldValues(t *testing.T) { ctx := api.NewDefaultContext() resource := api.ObjectMeta{} if api.HasObjectMetaSystemFieldValues(&resource) { t.Errorf("the resource does not have all fields yet populated, but incorrectly reports it does") } api.FillObjectMetaSystemFields(ctx, &resource) if !api.HasObjectMetaSystemFieldValues(&resource) { t.Errorf("the resource does have all fields populated, but incorrectly reports it does not") } }
// createBuild is responsible for validating build object and saving it and returning newly created object func (g *BuildGenerator) createBuild(ctx kapi.Context, build *buildapi.Build) (*buildapi.Build, error) { if !kapi.ValidNamespace(ctx, &build.ObjectMeta) { return nil, errors.NewConflict("build", build.Namespace, fmt.Errorf("Build.Namespace does not match the provided context")) } kapi.FillObjectMetaSystemFields(ctx, &build.ObjectMeta) err := g.Client.CreateBuild(ctx, build) if err != nil { return nil, err } return g.Client.GetBuild(ctx, build.Name) }
// Create registers the given Project. func (s *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { project, ok := obj.(*api.Project) if !ok { return nil, fmt.Errorf("not a project: %#v", obj) } kapi.FillObjectMetaSystemFields(ctx, &project.ObjectMeta) s.createStrategy.PrepareForCreate(obj) if errs := s.createStrategy.Validate(ctx, obj); len(errs) > 0 { return nil, kerrors.NewInvalid("project", project.Name, errs) } namespace, err := s.client.Create(convertProject(project)) if err != nil { return nil, err } return convertNamespace(namespace), nil }
// Create satisfies the RESTStorage interface. func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { endpoints, ok := obj.(*api.Endpoints) if !ok { return nil, fmt.Errorf("not an endpoints: %#v", obj) } if len(endpoints.Name) == 0 { return nil, fmt.Errorf("id is required: %#v", obj) } if !api.ValidNamespace(ctx, &endpoints.ObjectMeta) { return nil, errors.NewConflict("endpoints", endpoints.Namespace, fmt.Errorf("Endpoints.Namespace does not match the provided context")) } api.FillObjectMetaSystemFields(ctx, &endpoints.ObjectMeta) err := rs.registry.UpdateEndpoints(ctx, endpoints) if err != nil { return nil, err } return rs.registry.GetEndpoints(ctx, endpoints.Name) }
// Create satisfies the RESTStorage interface. func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { minion, ok := obj.(*api.Node) if !ok { return nil, fmt.Errorf("not a minion: %#v", obj) } if errs := validation.ValidateMinion(minion); len(errs) > 0 { return nil, kerrors.NewInvalid("minion", minion.Name, errs) } api.FillObjectMetaSystemFields(ctx, &minion.ObjectMeta) return apiserver.MakeAsync(func() (runtime.Object, error) { err := rs.registry.CreateMinion(ctx, minion) if err != nil { return nil, err } return minion, nil }), nil }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { event, ok := obj.(*api.Event) if !ok { return nil, errors.NewInternalError(fmt.Errorf("received object is not of type event: %#v", obj)) } if api.NamespaceValue(ctx) != "" { if !api.ValidNamespace(ctx, &event.ObjectMeta) { return nil, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context")) } } if errs := validation.ValidateEvent(event); len(errs) > 0 { return nil, errors.NewInvalid("event", event.Name, errs) } api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta) err := rs.registry.CreateWithName(ctx, event.Name, event) if err != nil { return nil, err } return rs.registry.Get(ctx, event.Name) }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { pod := obj.(*api.Pod) if !api.ValidNamespace(ctx, &pod.ObjectMeta) { return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context")) } api.FillObjectMetaSystemFields(ctx, &pod.ObjectMeta) if len(pod.Name) == 0 { // TODO properly handle auto-generated names. // See https://github.com/GoogleCloudPlatform/kubernetes/issues/148 170 & 1135 pod.Name = string(pod.UID) } if errs := validation.ValidatePod(pod); len(errs) > 0 { return nil, errors.NewInvalid("pod", pod.Name, errs) } return apiserver.MakeAsync(func() (runtime.Object, error) { if err := rs.registry.CreatePod(ctx, pod); err != nil { return nil, err } return rs.registry.GetPod(ctx, pod.Name) }), nil }
// BeforeCreate ensures that common operations for all resources are performed on creation. It only returns // errors that can be converted to api.Status. It invokes ResetBeforeCreate, then GenerateName, then Validate. // It returns nil if the object should be created. func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Object) error { objectMeta, kind, kerr := objectMetaAndKind(strategy, obj) if kerr != nil { return kerr } if strategy.NamespaceScoped() { if !api.ValidNamespace(ctx, objectMeta) { return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request") } } else { objectMeta.Namespace = api.NamespaceNone } strategy.ResetBeforeCreate(obj) api.FillObjectMetaSystemFields(ctx, objectMeta) api.GenerateName(strategy, objectMeta) if errs := strategy.Validate(obj); len(errs) > 0 { return errors.NewInvalid(kind, objectMeta.Name, errs) } return nil }
// Create registers a given new Route instance to rs.registry. func (rs *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) { route, ok := obj.(*api.Route) if !ok { return nil, errors.NewBadRequest(fmt.Sprintf("not a route: %#v", obj)) } if !kapi.ValidNamespace(ctx, &route.ObjectMeta) { return nil, errors.NewConflict("route", route.Namespace, fmt.Errorf("Route.Namespace does not match the provided context")) } shard, err := rs.allocator.AllocateRouterShard(route) if err != nil { return nil, errors.NewInternalError(fmt.Errorf("allocation error: %s for route: %#v", err, obj)) } if route.Annotations == nil { route.Annotations = map[string]string{} } if len(route.Host) == 0 { route.Host = rs.allocator.GenerateHostname(route, shard) route.Annotations[HostGeneratedAnnotationKey] = "true" } else { route.Annotations[HostGeneratedAnnotationKey] = "false" } if errs := validation.ValidateRoute(route); len(errs) > 0 { return nil, errors.NewInvalid("route", route.Name, errs) } if len(route.Name) == 0 { route.Name = uuid.NewUUID().String() } kapi.FillObjectMetaSystemFields(ctx, &route.ObjectMeta) err = rs.registry.CreateRoute(ctx, route) if err != nil { return nil, err } return rs.registry.GetRoute(ctx, route.Name) }
// Update replaces an existing Event instance in storage.registry, with the given instance. func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) { event, ok := obj.(*api.Event) if !ok { return nil, false, fmt.Errorf("not an event object: %#v", obj) } if api.NamespaceValue(ctx) != "" { if !api.ValidNamespace(ctx, &event.ObjectMeta) { return nil, false, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context")) } } if errs := validation.ValidateEvent(event); len(errs) > 0 { return nil, false, errors.NewInvalid("event", event.Name, errs) } api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta) err := rs.registry.UpdateWithName(ctx, event.Name, event) if err != nil { return nil, false, err } out, err := rs.registry.Get(ctx, event.Name) return out, false, err }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { event, ok := obj.(*api.Event) if !ok { return nil, fmt.Errorf("invalid object type") } if api.Namespace(ctx) != "" { if !api.ValidNamespace(ctx, &event.ObjectMeta) { return nil, errors.NewConflict("event", event.Namespace, fmt.Errorf("event.namespace does not match the provided context")) } } if errs := validation.ValidateEvent(event); len(errs) > 0 { return nil, errors.NewInvalid("event", event.Name, errs) } api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta) return apiserver.MakeAsync(func() (runtime.Object, error) { err := rs.registry.Create(ctx, event.Name, event) if err != nil { return nil, err } return rs.registry.Get(ctx, event.Name) }), nil }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { minion, ok := obj.(*api.Minion) if !ok { return nil, fmt.Errorf("not a minion: %#v", obj) } if errs := validation.ValidateMinion(minion); len(errs) > 0 { return nil, kerrors.NewInvalid("minion", minion.Name, errs) } api.FillObjectMetaSystemFields(ctx, &minion.ObjectMeta) return apiserver.MakeAsync(func() (runtime.Object, error) { // TODO: Need to fill in any server-set fields (uid, timestamp, etc) before // returning minion. Can't do it properly at the moment because the registry // healthchecking, which might cause it to not return the minion at all. Fix // this after we move the healthchecking out of the minion registry. err := rs.registry.CreateMinion(ctx, minion) if err != nil { return nil, err } return minion, nil }), nil }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { service := obj.(*api.Service) if !api.ValidNamespace(ctx, &service.ObjectMeta) { return nil, errors.NewConflict("service", service.Namespace, fmt.Errorf("Service.Namespace does not match the provided context")) } if errs := validation.ValidateService(service, rs.registry, ctx); len(errs) > 0 { return nil, errors.NewInvalid("service", service.Name, errs) } api.FillObjectMetaSystemFields(ctx, &service.ObjectMeta) if service.Spec.PortalIP == "" { // Allocate next available. if ip, err := rs.portalMgr.AllocateNext(); err != nil { return nil, err } else { service.Spec.PortalIP = ip.String() } } else { // Try to respect the requested IP. if err := rs.portalMgr.Allocate(net.ParseIP(service.Spec.PortalIP)); err != nil { el := errors.ValidationErrorList{errors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, err.Error())} return nil, errors.NewInvalid("service", service.Name, el) } } return apiserver.MakeAsync(func() (runtime.Object, error) { // TODO: Consider moving this to a rectification loop, so that we make/remove external load balancers // correctly no matter what http operations happen. // TODO: Get rid of ProxyPort. service.Spec.ProxyPort = 0 if service.Spec.CreateExternalLoadBalancer { if rs.cloud == nil { return nil, fmt.Errorf("requested an external service, but no cloud provider supplied.") } balancer, ok := rs.cloud.TCPLoadBalancer() if !ok { return nil, fmt.Errorf("the cloud provider does not support external TCP load balancers.") } zones, ok := rs.cloud.Zones() if !ok { return nil, fmt.Errorf("the cloud provider does not support zone enumeration.") } hosts, err := rs.machines.ListMinions(ctx) if err != nil { return nil, err } zone, err := zones.GetZone() if err != nil { return nil, err } var ip net.IP if len(service.Spec.PublicIPs) > 0 { for _, publicIP := range service.Spec.PublicIPs { ip, err = balancer.CreateTCPLoadBalancer(service.Name, zone.Region, net.ParseIP(publicIP), service.Spec.Port, hostsFromMinionList(hosts)) if err != nil { break } } } else { ip, err = balancer.CreateTCPLoadBalancer(service.Name, zone.Region, nil, service.Spec.Port, hostsFromMinionList(hosts)) } if err != nil { return nil, err } service.Spec.PublicIPs = []string{ip.String()} } err := rs.registry.CreateService(ctx, service) if err != nil { return nil, err } return rs.registry.GetService(ctx, service.Name) }), nil }