// ScaleRC scales the given rc to the given replicas. func ScaleRC(name, ns string, replicas int, restClient *client.Client) (*api.ReplicationController, error) { scaler, err := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(restClient)) if err != nil { return nil, err } retry := &kubectl.RetryParams{Interval: 50 * time.Millisecond, Timeout: DefaultTimeout} waitForReplicas := &kubectl.RetryParams{Interval: 50 * time.Millisecond, Timeout: DefaultTimeout} err = scaler.Scale(ns, name, uint(replicas), nil, retry, waitForReplicas) if err != nil { return nil, err } scaled, err := restClient.ReplicationControllers(ns).Get(name) if err != nil { return nil, err } return scaled, nil }
// NewRecreateDeploymentStrategy makes a RecreateDeploymentStrategy backed by // a real HookExecutor and client. func NewRecreateDeploymentStrategy(client kclient.Interface, codec runtime.Codec) *RecreateDeploymentStrategy { scaler, _ := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(client)) return &RecreateDeploymentStrategy{ getReplicationController: func(namespace, name string) (*kapi.ReplicationController, error) { return client.ReplicationControllers(namespace).Get(name) }, scaler: scaler, codec: codec, hookExecutor: &stratsupport.HookExecutor{ PodClient: &stratsupport.HookExecutorPodClientImpl{ CreatePodFunc: func(namespace string, pod *kapi.Pod) (*kapi.Pod, error) { return client.Pods(namespace).Create(pod) }, PodWatchFunc: func(namespace, name, resourceVersion string, stopChannel chan struct{}) func() *kapi.Pod { return stratsupport.NewPodWatch(client, namespace, name, resourceVersion, stopChannel) }, }, }, retryTimeout: 120 * time.Second, retryPeriod: 1 * time.Second, } }
// NewDeployer makes a new Deployer from a kube client. func NewDeployer(client kclient.Interface) *Deployer { scaler, _ := kubectl.ScalerFor("ReplicationController", kubectl.NewScalerClient(client)) return &Deployer{ getDeployment: func(namespace, name string) (*kapi.ReplicationController, error) { return client.ReplicationControllers(namespace).Get(name) }, getDeployments: func(namespace, configName string) (*kapi.ReplicationControllerList, error) { return client.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName)) }, scaler: scaler, strategyFor: func(config *deployapi.DeploymentConfig) (strategy.DeploymentStrategy, error) { switch config.Template.Strategy.Type { case deployapi.DeploymentStrategyTypeRecreate: return recreate.NewRecreateDeploymentStrategy(client, latest.Codec), nil case deployapi.DeploymentStrategyTypeRolling: recreate := recreate.NewRecreateDeploymentStrategy(client, latest.Codec) return rolling.NewRollingDeploymentStrategy(config.Namespace, client, latest.Codec, recreate), nil default: return nil, fmt.Errorf("unsupported strategy type: %s", config.Template.Strategy.Type) } }, } }
// NewFactory creates a factory with the default Kubernetes resources defined // if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig. // if optionalClientConfig is not nil, then this factory will make use of it. func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := kubectl.ShortcutExpander{RESTMapper: api.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) flags.SetNormalizeFunc(util.WarnWordSepNormalizeFunc) // Warn for "_" flags generators := map[string]kubectl.Generator{ "run/v1": kubectl.BasicReplicationController{}, "run-pod/v1": kubectl.BasicPod{}, "service/v1": kubectl.ServiceGeneratorV1{}, "service/v2": kubectl.ServiceGeneratorV2{}, } clientConfig := optionalClientConfig if optionalClientConfig == nil { clientConfig = DefaultClientConfig(flags) } clients := NewClientCache(clientConfig) expClients := NewExperimentalClientCache(clientConfig) noClientErr := errors.New("could not get client") getBothClients := func(group string, version string) (*client.Client, *client.ExperimentalClient, error) { switch group { case "api": client, err := clients.ClientForVersion(version) return client, nil, err case "experimental": client, err := clients.ClientForVersion(version) if err != nil { return nil, nil, err } expClient, err := expClients.Client() if err != nil { return nil, nil, err } return client, expClient, err } return nil, nil, noClientErr } return &Factory{ clients: clients, flags: flags, generators: generators, Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() CheckErr(err) cmdApiVersion := cfg.Version return kubectl.OutputVersionMapper{RESTMapper: mapper, OutputVersion: cmdApiVersion}, api.Scheme }, Client: func() (*client.Client, error) { return clients.ClientForVersion("") }, ExperimentalClient: func() (*client.ExperimentalClient, error) { return expClients.Client() }, ClientConfig: func() (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { group, err := api.RESTMapper.GroupForResource(mapping.Resource) if err != nil { return nil, err } switch group { case "api": client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil case "experimental": client, err := expClients.Client() if err != nil { return nil, err } return client.RESTClient, nil } return nil, fmt.Errorf("unable to get RESTClient for resource '%s'", mapping.Resource) }, Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) { group, err := api.RESTMapper.GroupForResource(mapping.Resource) if err != nil { return nil, err } client, expClient, err := getBothClients(group, mapping.APIVersion) if err != nil { return nil, err } if describer, ok := kubectl.DescriberFor(mapping.Kind, client, expClient); ok { return describer, nil } return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) }, Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, wide bool, showAll bool, columnLabels []string) (kubectl.ResourcePrinter, error) { return kubectl.NewHumanReadablePrinter(noHeaders, withNamespace, wide, showAll, columnLabels), nil }, PodSelectorForObject: func(object runtime.Object) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return kubectl.MakeLabels(t.Spec.Selector), nil case *api.Pod: if len(t.Labels) == 0 { return "", fmt.Errorf("the pod has no labels and cannot be exposed") } return kubectl.MakeLabels(t.Labels), nil case *api.Service: if t.Spec.Selector == nil { return "", fmt.Errorf("the service has no pod selector set") } return kubectl.MakeLabels(t.Spec.Selector), nil default: _, kind, err := api.Scheme.ObjectVersionAndKind(object) if err != nil { return "", err } return "", fmt.Errorf("cannot extract pod selector from %s", kind) } }, PortsForObject: func(object runtime.Object) ([]string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return getPorts(t.Spec.Template.Spec), nil case *api.Pod: return getPorts(t.Spec), nil case *api.Service: return getServicePorts(t.Spec), nil default: _, kind, err := api.Scheme.ObjectVersionAndKind(object) if err != nil { return nil, err } return nil, fmt.Errorf("cannot extract ports from %s", kind) } }, LabelsForObject: func(object runtime.Object) (map[string]string, error) { return meta.NewAccessor().Labels(object) }, Scaler: func(mapping *meta.RESTMapping) (kubectl.Scaler, error) { group, err := api.RESTMapper.GroupForResource(mapping.Resource) if err != nil { return nil, err } client, _, err := getBothClients(group, mapping.APIVersion) if err != nil { return nil, err } return kubectl.ScalerFor(mapping.Kind, kubectl.NewScalerClient(client)) }, Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) { group, err := api.RESTMapper.GroupForResource(mapping.Resource) if err != nil { return nil, err } client, expClient, err := getBothClients(group, mapping.APIVersion) if err != nil { return nil, err } return kubectl.ReaperFor(mapping.Kind, client, expClient) }, Validator: func(validate bool) (validation.Schema, error) { if validate { client, err := clients.ClientForVersion("") if err != nil { return nil, err } expClient, _ := expClients.Client() return &clientSwaggerSchema{client, expClient, api.Scheme}, nil } return validation.NullSchema{}, nil }, DefaultNamespace: func() (string, bool, error) { return clientConfig.Namespace() }, Generator: func(name string) (kubectl.Generator, bool) { generator, ok := generators[name] return generator, ok }, } }