mirror of https://github.com/k3s-io/k3s
Add embedded service load balancer
parent
24463d4985
commit
e832588662
10
README.md
10
README.md
|
@ -231,6 +231,16 @@ CoreDNS is deployed on start of the agent, to disable add `--no-deploy coredns`
|
||||||
|
|
||||||
If you don't install CoreDNS you will need to install a cluster DNS provider yourself.
|
If you don't install CoreDNS you will need to install a cluster DNS provider yourself.
|
||||||
|
|
||||||
|
Service Load Balancer
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
k3s includes a basic service load balancer that uses available host ports. If you try to create
|
||||||
|
a load balancer that listens on port 80, for example, it will try to find a free host in the cluster
|
||||||
|
for port 80. If no port is available the load balancer will stay in Pending.
|
||||||
|
|
||||||
|
To disable the embedded service load balancer (if you wish to use a different implementation like
|
||||||
|
MetalLB) just add `--no-deploy=servicelb` to the server on startup.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
Currently broken or stuff that needs to be done for this to be considered production quality.
|
Currently broken or stuff that needs to be done for this to be considered production quality.
|
||||||
|
|
|
@ -66,7 +66,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
Name: "no-deploy",
|
Name: "no-deploy",
|
||||||
Usage: "Do not deploy packaged manifests (example: coredns)",
|
Usage: "Do not deploy packaged components (valid items: coredns, servicelb)",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "write-kubeconfig,o",
|
Name: "write-kubeconfig,o",
|
||||||
|
|
|
@ -77,6 +77,11 @@ func run(app *cli.Context, cfg *cmds.Server) error {
|
||||||
serverConfig.ControlConfig.NoLeaderElect = true
|
serverConfig.ControlConfig.NoLeaderElect = true
|
||||||
|
|
||||||
for _, noDeploy := range app.StringSlice("no-deploy") {
|
for _, noDeploy := range app.StringSlice("no-deploy") {
|
||||||
|
if noDeploy == "servicelb" {
|
||||||
|
serverConfig.DisableServiceLB = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasSuffix(noDeploy, ".yaml") {
|
if !strings.HasSuffix(noDeploy, ".yaml") {
|
||||||
noDeploy = noDeploy + ".yaml"
|
noDeploy = noDeploy + ".yaml"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,10 @@ import (
|
||||||
"github.com/rancher/k3s/pkg/daemons/config"
|
"github.com/rancher/k3s/pkg/daemons/config"
|
||||||
"github.com/rancher/k3s/pkg/daemons/control"
|
"github.com/rancher/k3s/pkg/daemons/control"
|
||||||
"github.com/rancher/k3s/pkg/deploy"
|
"github.com/rancher/k3s/pkg/deploy"
|
||||||
|
"github.com/rancher/k3s/pkg/servicelb"
|
||||||
"github.com/rancher/k3s/pkg/tls"
|
"github.com/rancher/k3s/pkg/tls"
|
||||||
|
appsv1 "github.com/rancher/k3s/types/apis/apps/v1"
|
||||||
|
corev1 "github.com/rancher/k3s/types/apis/core/v1"
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
||||||
"github.com/rancher/norman"
|
"github.com/rancher/norman"
|
||||||
"github.com/rancher/norman/pkg/clientaccess"
|
"github.com/rancher/norman/pkg/clientaccess"
|
||||||
|
@ -50,7 +53,7 @@ func StartServer(ctx context.Context, config *Config) (string, error) {
|
||||||
return "", errors.Wrap(err, "starting kubernetes")
|
return "", errors.Wrap(err, "starting kubernetes")
|
||||||
}
|
}
|
||||||
|
|
||||||
certs, err := startNorman(ctx, &config.TLSConfig, &config.ControlConfig)
|
certs, err := startNorman(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "starting tls server")
|
return "", errors.Wrap(err, "starting tls server")
|
||||||
}
|
}
|
||||||
|
@ -66,13 +69,15 @@ func StartServer(ctx context.Context, config *Config) (string, error) {
|
||||||
return certs, nil
|
return certs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startNorman(ctx context.Context, tlsConfig *dynamiclistener.UserConfig, config *config.Control) (string, error) {
|
func startNorman(ctx context.Context, config *Config) (string, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
tlsServer dynamiclistener.ServerInterface
|
tlsServer dynamiclistener.ServerInterface
|
||||||
|
tlsConfig = &config.TLSConfig
|
||||||
|
controlConfig = &config.ControlConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
tlsConfig.Handler = router(config, config.Runtime.Tunnel, func() (string, error) {
|
tlsConfig.Handler = router(controlConfig, controlConfig.Runtime.Tunnel, func() (string, error) {
|
||||||
if tlsServer == nil {
|
if tlsServer == nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
@ -81,9 +86,11 @@ func startNorman(ctx context.Context, tlsConfig *dynamiclistener.UserConfig, con
|
||||||
|
|
||||||
normanConfig := &norman.Config{
|
normanConfig := &norman.Config{
|
||||||
Name: "k3s",
|
Name: "k3s",
|
||||||
KubeConfig: config.Runtime.KubeConfigSystem,
|
KubeConfig: controlConfig.Runtime.KubeConfigSystem,
|
||||||
Clients: []norman.ClientFactory{
|
Clients: []norman.ClientFactory{
|
||||||
v1.Factory,
|
v1.Factory,
|
||||||
|
appsv1.Factory,
|
||||||
|
corev1.Factory,
|
||||||
},
|
},
|
||||||
Schemas: []*types.Schemas{
|
Schemas: []*types.Schemas{
|
||||||
v1.Schemas,
|
v1.Schemas,
|
||||||
|
@ -102,11 +109,14 @@ func startNorman(ctx context.Context, tlsConfig *dynamiclistener.UserConfig, con
|
||||||
DisableLeaderElection: true,
|
DisableLeaderElection: true,
|
||||||
MasterControllers: []norman.ControllerRegister{
|
MasterControllers: []norman.ControllerRegister{
|
||||||
func(ctx context.Context) error {
|
func(ctx context.Context) error {
|
||||||
dataDir := filepath.Join(config.DataDir, "manifests")
|
return servicelb.Register(ctx, norman.GetServer(ctx).K8sClient, !config.DisableServiceLB)
|
||||||
|
},
|
||||||
|
func(ctx context.Context) error {
|
||||||
|
dataDir := filepath.Join(controlConfig.DataDir, "manifests")
|
||||||
if err := deploy.Stage(dataDir); err != nil {
|
if err := deploy.Stage(dataDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := deploy.WatchFiles(ctx, config.Skips, dataDir); err != nil {
|
if err := deploy.WatchFiles(ctx, controlConfig.Skips, dataDir); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DisableAgent bool
|
DisableAgent bool
|
||||||
|
DisableServiceLB bool
|
||||||
TLSConfig dynamiclistener.UserConfig
|
TLSConfig dynamiclistener.UserConfig
|
||||||
ControlConfig config.Control
|
ControlConfig config.Control
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
package servicelb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
appclient "github.com/rancher/k3s/types/apis/apps/v1"
|
||||||
|
coreclient "github.com/rancher/k3s/types/apis/core/v1"
|
||||||
|
"github.com/rancher/norman/condition"
|
||||||
|
"github.com/rancher/norman/pkg/changeset"
|
||||||
|
"github.com/rancher/norman/pkg/objectset"
|
||||||
|
"github.com/rancher/norman/types/slice"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
apps "k8s.io/api/apps/v1"
|
||||||
|
core "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
coregetter "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
image = "rancher/klipper-lb:v0.1.1"
|
||||||
|
svcNameLabel = "svccontroller.k3s.cattle.io/svcname"
|
||||||
|
Ready = condition.Cond("Ready")
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
trueVal = true
|
||||||
|
)
|
||||||
|
|
||||||
|
func Register(ctx context.Context, kubernetes kubernetes.Interface, enabled bool) error {
|
||||||
|
clients := coreclient.ClientsFrom(ctx)
|
||||||
|
appClients := appclient.ClientsFrom(ctx)
|
||||||
|
|
||||||
|
h := &handler{
|
||||||
|
enabled: enabled,
|
||||||
|
nodeCache: clients.Node.Cache(),
|
||||||
|
podCache: clients.Pod.Cache(),
|
||||||
|
processor: objectset.NewProcessor("svccontroller").
|
||||||
|
Client(appClients.Deployment),
|
||||||
|
serviceCache: clients.Service.Cache(),
|
||||||
|
services: kubernetes.CoreV1(),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.Service.OnChange(ctx, "svccontroller", h.onChange)
|
||||||
|
changeset.Watch(ctx, "svccontroller-watcher",
|
||||||
|
h.onPodChange,
|
||||||
|
clients.Service,
|
||||||
|
clients.Pod)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type handler struct {
|
||||||
|
enabled bool
|
||||||
|
nodeCache coreclient.NodeClientCache
|
||||||
|
podCache coreclient.PodClientCache
|
||||||
|
processor *objectset.Processor
|
||||||
|
serviceCache coreclient.ServiceClientCache
|
||||||
|
services coregetter.ServicesGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) onPodChange(name, namespace string, obj runtime.Object) ([]changeset.Key, error) {
|
||||||
|
pod, ok := obj.(*core.Pod)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName := pod.Labels[svcNameLabel]
|
||||||
|
if serviceName == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if pod.Status.PodIP == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return []changeset.Key{
|
||||||
|
{
|
||||||
|
Name: serviceName,
|
||||||
|
Namespace: pod.Namespace,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) onChange(svc *core.Service) (runtime.Object, error) {
|
||||||
|
if svc.Spec.Type != core.ServiceTypeLoadBalancer || svc.Spec.ClusterIP == "" ||
|
||||||
|
svc.Spec.ClusterIP == "None" {
|
||||||
|
return svc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.deployPod(svc); err != nil {
|
||||||
|
return svc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.updateService(svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) updateService(svc *core.Service) (runtime.Object, error) {
|
||||||
|
pods, err := h.podCache.List(svc.Namespace, labels.SelectorFromSet(map[string]string{
|
||||||
|
svcNameLabel: svc.Name,
|
||||||
|
}))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return svc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
existingIPs := serviceIPs(svc)
|
||||||
|
expectedIPs, err := h.podIPs(pods)
|
||||||
|
if err != nil {
|
||||||
|
return svc, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(expectedIPs)
|
||||||
|
sort.Strings(existingIPs)
|
||||||
|
|
||||||
|
if slice.StringsEqual(expectedIPs, existingIPs) {
|
||||||
|
return svc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
svc = svc.DeepCopy()
|
||||||
|
svc.Status.LoadBalancer.Ingress = nil
|
||||||
|
for _, ip := range expectedIPs {
|
||||||
|
svc.Status.LoadBalancer.Ingress = append(svc.Status.LoadBalancer.Ingress, core.LoadBalancerIngress{
|
||||||
|
IP: ip,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Debugf("Setting service loadbalancer %s/%s to IPs %v", svc.Namespace, svc.Name, expectedIPs)
|
||||||
|
return h.services.Services(svc.Namespace).UpdateStatus(svc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func serviceIPs(svc *core.Service) []string {
|
||||||
|
var ips []string
|
||||||
|
|
||||||
|
for _, ingress := range svc.Status.LoadBalancer.Ingress {
|
||||||
|
if ingress.IP != "" {
|
||||||
|
ips = append(ips, ingress.IP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ips
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) podIPs(pods []*core.Pod) ([]string, error) {
|
||||||
|
ips := map[string]bool{}
|
||||||
|
|
||||||
|
for _, pod := range pods {
|
||||||
|
if pod.Spec.NodeName == "" || pod.Status.PodIP == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !Ready.IsTrue(pod) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := h.nodeCache.Get("", pod.Spec.NodeName)
|
||||||
|
if errors.IsNotFound(err) {
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range node.Status.Addresses {
|
||||||
|
if addr.Type == core.NodeInternalIP {
|
||||||
|
ips[addr.Address] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ipList []string
|
||||||
|
for k := range ips {
|
||||||
|
ipList = append(ipList, k)
|
||||||
|
}
|
||||||
|
return ipList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) deployPod(svc *core.Service) error {
|
||||||
|
objs := objectset.NewObjectSet()
|
||||||
|
if !h.enabled {
|
||||||
|
return h.processor.NewDesiredSet(svc, objs).Apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
dep, err := h.newDeployment(svc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dep != nil {
|
||||||
|
objs.Add(dep)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.processor.NewDesiredSet(svc, objs).Apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) resolvePort(svc *core.Service, targetPort core.ServicePort) (int32, error) {
|
||||||
|
if len(svc.Spec.Selector) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if targetPort.TargetPort.IntVal != 0 {
|
||||||
|
return targetPort.TargetPort.IntVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pods, err := h.podCache.List(svc.Namespace, labels.SelectorFromSet(svc.Spec.Selector))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pod := range pods {
|
||||||
|
if !Ready.IsTrue(pod) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, container := range pod.Spec.Containers {
|
||||||
|
for _, port := range container.Ports {
|
||||||
|
if port.Name == targetPort.TargetPort.StrVal {
|
||||||
|
return port.ContainerPort, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) newDeployment(svc *core.Service) (*apps.Deployment, error) {
|
||||||
|
name := fmt.Sprintf("svclb-%s", svc.Name)
|
||||||
|
zero := intstr.FromInt(0)
|
||||||
|
one := intstr.FromInt(1)
|
||||||
|
two := int32(2)
|
||||||
|
|
||||||
|
dep := &apps.Deployment{
|
||||||
|
ObjectMeta: meta.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: svc.Namespace,
|
||||||
|
OwnerReferences: []meta.OwnerReference{
|
||||||
|
{
|
||||||
|
Name: svc.Name,
|
||||||
|
APIVersion: "v1",
|
||||||
|
Kind: "Service",
|
||||||
|
UID: svc.UID,
|
||||||
|
Controller: &trueVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TypeMeta: meta.TypeMeta{
|
||||||
|
Kind: "Deployment",
|
||||||
|
APIVersion: "apps/v1",
|
||||||
|
},
|
||||||
|
Spec: apps.DeploymentSpec{
|
||||||
|
Replicas: &two,
|
||||||
|
Selector: &meta.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"app": name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Template: core.PodTemplateSpec{
|
||||||
|
ObjectMeta: meta.ObjectMeta{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"app": name,
|
||||||
|
svcNameLabel: svc.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Strategy: apps.DeploymentStrategy{
|
||||||
|
Type: apps.RollingUpdateDeploymentStrategyType,
|
||||||
|
RollingUpdate: &apps.RollingUpdateDeployment{
|
||||||
|
MaxSurge: &zero,
|
||||||
|
MaxUnavailable: &one,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, port := range svc.Spec.Ports {
|
||||||
|
targetPort, err := h.resolvePort(svc, port)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
container := core.Container{
|
||||||
|
Name: fmt.Sprintf("port-%s", port.Name),
|
||||||
|
Image: image,
|
||||||
|
ImagePullPolicy: core.PullIfNotPresent,
|
||||||
|
Ports: []core.ContainerPort{
|
||||||
|
{
|
||||||
|
Name: port.Name,
|
||||||
|
ContainerPort: port.Port,
|
||||||
|
HostPort: port.Port,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Env: []core.EnvVar{
|
||||||
|
{
|
||||||
|
Name: "SRC_PORT",
|
||||||
|
Value: strconv.Itoa(int(port.Port)),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DEST_PROTO",
|
||||||
|
Value: string(port.Protocol),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DEST_PORT",
|
||||||
|
Value: strconv.Itoa(int(targetPort)),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "DEST_IP",
|
||||||
|
Value: svc.Spec.ClusterIP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SecurityContext: &core.SecurityContext{
|
||||||
|
Capabilities: &core.Capabilities{
|
||||||
|
Add: []core.Capability{
|
||||||
|
"NET_ADMIN",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
dep.Spec.Template.Spec.Containers = append(dep.Spec.Template.Spec.Containers, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dep, nil
|
||||||
|
}
|
|
@ -5,4 +5,4 @@ mkdir -p $(dirname $0)/../bin
|
||||||
cd $(dirname $0)/../bin
|
cd $(dirname $0)/../bin
|
||||||
|
|
||||||
echo Running
|
echo Running
|
||||||
go run -tags "apparmor" ../main.go --debug server --disable-agent
|
go run -tags "apparmor" ../main.go --debug server --disable-agent "$@"
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *DeploymentList) DeepCopyInto(out *DeploymentList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
out.ListMeta = in.ListMeta
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]appsv1.Deployment, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentList.
|
||||||
|
func (in *DeploymentList) DeepCopy() *DeploymentList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(DeploymentList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *DeploymentList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,441 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
v1 "k8s.io/api/apps/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DeploymentGroupVersionKind = schema.GroupVersionKind{
|
||||||
|
Version: Version,
|
||||||
|
Group: GroupName,
|
||||||
|
Kind: "Deployment",
|
||||||
|
}
|
||||||
|
DeploymentResource = metav1.APIResource{
|
||||||
|
Name: "deployments",
|
||||||
|
SingularName: "deployment",
|
||||||
|
Namespaced: true,
|
||||||
|
|
||||||
|
Kind: DeploymentGroupVersionKind.Kind,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewDeployment(namespace, name string, obj v1.Deployment) *v1.Deployment {
|
||||||
|
obj.APIVersion, obj.Kind = DeploymentGroupVersionKind.ToAPIVersionAndKind()
|
||||||
|
obj.Name = name
|
||||||
|
obj.Namespace = namespace
|
||||||
|
return &obj
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []v1.Deployment
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentHandlerFunc func(key string, obj *v1.Deployment) (runtime.Object, error)
|
||||||
|
|
||||||
|
type DeploymentChangeHandlerFunc func(obj *v1.Deployment) (runtime.Object, error)
|
||||||
|
|
||||||
|
type DeploymentLister interface {
|
||||||
|
List(namespace string, selector labels.Selector) (ret []*v1.Deployment, err error)
|
||||||
|
Get(namespace, name string) (*v1.Deployment, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentController interface {
|
||||||
|
Generic() controller.GenericController
|
||||||
|
Informer() cache.SharedIndexInformer
|
||||||
|
Lister() DeploymentLister
|
||||||
|
AddHandler(ctx context.Context, name string, handler DeploymentHandlerFunc)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler DeploymentHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
Sync(ctx context.Context) error
|
||||||
|
Start(ctx context.Context, threadiness int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentInterface interface {
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Create(*v1.Deployment) (*v1.Deployment, error)
|
||||||
|
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error)
|
||||||
|
Get(name string, opts metav1.GetOptions) (*v1.Deployment, error)
|
||||||
|
Update(*v1.Deployment) (*v1.Deployment, error)
|
||||||
|
Delete(name string, options *metav1.DeleteOptions) error
|
||||||
|
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(opts metav1.ListOptions) (*DeploymentList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
Controller() DeploymentController
|
||||||
|
AddHandler(ctx context.Context, name string, sync DeploymentHandlerFunc)
|
||||||
|
AddLifecycle(ctx context.Context, name string, lifecycle DeploymentLifecycle)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DeploymentHandlerFunc)
|
||||||
|
AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DeploymentLifecycle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentLister struct {
|
||||||
|
controller *deploymentController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *deploymentLister) List(namespace string, selector labels.Selector) (ret []*v1.Deployment, err error) {
|
||||||
|
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
|
||||||
|
ret = append(ret, obj.(*v1.Deployment))
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *deploymentLister) Get(namespace, name string) (*v1.Deployment, error) {
|
||||||
|
var key string
|
||||||
|
if namespace != "" {
|
||||||
|
key = namespace + "/" + name
|
||||||
|
} else {
|
||||||
|
key = name
|
||||||
|
}
|
||||||
|
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(schema.GroupResource{
|
||||||
|
Group: DeploymentGroupVersionKind.Group,
|
||||||
|
Resource: "deployment",
|
||||||
|
}, key)
|
||||||
|
}
|
||||||
|
return obj.(*v1.Deployment), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentController struct {
|
||||||
|
controller.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *deploymentController) Generic() controller.GenericController {
|
||||||
|
return c.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *deploymentController) Lister() DeploymentLister {
|
||||||
|
return &deploymentLister{
|
||||||
|
controller: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *deploymentController) AddHandler(ctx context.Context, name string, handler DeploymentHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Deployment); ok {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *deploymentController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler DeploymentHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Deployment); ok && controller.ObjectInCluster(cluster, obj) {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentFactory struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c deploymentFactory) Object() runtime.Object {
|
||||||
|
return &v1.Deployment{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c deploymentFactory) List() runtime.Object {
|
||||||
|
return &DeploymentList{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Controller() DeploymentController {
|
||||||
|
s.client.Lock()
|
||||||
|
defer s.client.Unlock()
|
||||||
|
|
||||||
|
c, ok := s.client.deploymentControllers[s.ns]
|
||||||
|
if ok {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
genericController := controller.NewGenericController(DeploymentGroupVersionKind.Kind+"Controller",
|
||||||
|
s.objectClient)
|
||||||
|
|
||||||
|
c = &deploymentController{
|
||||||
|
GenericController: genericController,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.client.deploymentControllers[s.ns] = c
|
||||||
|
s.client.starters = append(s.client.starters, c)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentClient struct {
|
||||||
|
client *Client
|
||||||
|
ns string
|
||||||
|
objectClient *objectclient.ObjectClient
|
||||||
|
controller DeploymentController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return s.objectClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Create(o *v1.Deployment) (*v1.Deployment, error) {
|
||||||
|
obj, err := s.objectClient.Create(o)
|
||||||
|
return obj.(*v1.Deployment), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Get(name string, opts metav1.GetOptions) (*v1.Deployment, error) {
|
||||||
|
obj, err := s.objectClient.Get(name, opts)
|
||||||
|
return obj.(*v1.Deployment), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error) {
|
||||||
|
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
|
||||||
|
return obj.(*v1.Deployment), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Update(o *v1.Deployment) (*v1.Deployment, error) {
|
||||||
|
obj, err := s.objectClient.Update(o.Name, o)
|
||||||
|
return obj.(*v1.Deployment), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Delete(name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.Delete(name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) List(opts metav1.ListOptions) (*DeploymentList, error) {
|
||||||
|
obj, err := s.objectClient.List(opts)
|
||||||
|
return obj.(*DeploymentList), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return s.objectClient.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched deployment.
|
||||||
|
func (s *deploymentClient) Patch(o *v1.Deployment, patchType types.PatchType, data []byte, subresources ...string) (*v1.Deployment, error) {
|
||||||
|
obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...)
|
||||||
|
return obj.(*v1.Deployment), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) AddHandler(ctx context.Context, name string, sync DeploymentHandlerFunc) {
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) AddLifecycle(ctx context.Context, name string, lifecycle DeploymentLifecycle) {
|
||||||
|
sync := NewDeploymentLifecycleAdapter(name, false, s, lifecycle)
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DeploymentHandlerFunc) {
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *deploymentClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DeploymentLifecycle) {
|
||||||
|
sync := NewDeploymentLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentIndexer func(obj *v1.Deployment) ([]string, error)
|
||||||
|
|
||||||
|
type DeploymentClientCache interface {
|
||||||
|
Get(namespace, name string) (*v1.Deployment, error)
|
||||||
|
List(namespace string, selector labels.Selector) ([]*v1.Deployment, error)
|
||||||
|
|
||||||
|
Index(name string, indexer DeploymentIndexer)
|
||||||
|
GetIndexed(name, key string) ([]*v1.Deployment, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentClient interface {
|
||||||
|
Create(*v1.Deployment) (*v1.Deployment, error)
|
||||||
|
Get(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error)
|
||||||
|
Update(*v1.Deployment) (*v1.Deployment, error)
|
||||||
|
Delete(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(namespace string, opts metav1.ListOptions) (*DeploymentList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
|
||||||
|
Cache() DeploymentClientCache
|
||||||
|
|
||||||
|
OnCreate(ctx context.Context, name string, sync DeploymentChangeHandlerFunc)
|
||||||
|
OnChange(ctx context.Context, name string, sync DeploymentChangeHandlerFunc)
|
||||||
|
OnRemove(ctx context.Context, name string, sync DeploymentChangeHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
|
||||||
|
Generic() controller.GenericController
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Interface() DeploymentInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentClientCache struct {
|
||||||
|
client *deploymentClient2
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentClient2 struct {
|
||||||
|
iface DeploymentInterface
|
||||||
|
controller DeploymentController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Interface() DeploymentInterface {
|
||||||
|
return n.iface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Generic() controller.GenericController {
|
||||||
|
return n.iface.Controller().Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return n.Interface().ObjectClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Enqueue(namespace, name string) {
|
||||||
|
n.iface.Controller().Enqueue(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Create(obj *v1.Deployment) (*v1.Deployment, error) {
|
||||||
|
return n.iface.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Get(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error) {
|
||||||
|
return n.iface.GetNamespaced(namespace, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Update(obj *v1.Deployment) (*v1.Deployment, error) {
|
||||||
|
return n.iface.Update(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Delete(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return n.iface.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) List(namespace string, opts metav1.ListOptions) (*DeploymentList, error) {
|
||||||
|
return n.iface.List(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return n.iface.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClientCache) Get(namespace, name string) (*v1.Deployment, error) {
|
||||||
|
return n.client.controller.Lister().Get(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClientCache) List(namespace string, selector labels.Selector) ([]*v1.Deployment, error) {
|
||||||
|
return n.client.controller.Lister().List(namespace, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) Cache() DeploymentClientCache {
|
||||||
|
n.loadController()
|
||||||
|
return &deploymentClientCache{
|
||||||
|
client: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) OnCreate(ctx context.Context, name string, sync DeploymentChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-create", &deploymentLifecycleDelegate{create: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) OnChange(ctx context.Context, name string, sync DeploymentChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-change", &deploymentLifecycleDelegate{update: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) OnRemove(ctx context.Context, name string, sync DeploymentChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name, &deploymentLifecycleDelegate{remove: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClientCache) Index(name string, indexer DeploymentIndexer) {
|
||||||
|
err := n.client.controller.Informer().GetIndexer().AddIndexers(map[string]cache.IndexFunc{
|
||||||
|
name: func(obj interface{}) ([]string, error) {
|
||||||
|
if v, ok := obj.(*v1.Deployment); ok {
|
||||||
|
return indexer(v)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClientCache) GetIndexed(name, key string) ([]*v1.Deployment, error) {
|
||||||
|
var result []*v1.Deployment
|
||||||
|
objs, err := n.client.controller.Informer().GetIndexer().ByIndex(name, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, obj := range objs {
|
||||||
|
if v, ok := obj.(*v1.Deployment); ok {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentClient2) loadController() {
|
||||||
|
if n.controller == nil {
|
||||||
|
n.controller = n.iface.Controller()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentLifecycleDelegate struct {
|
||||||
|
create DeploymentChangeHandlerFunc
|
||||||
|
update DeploymentChangeHandlerFunc
|
||||||
|
remove DeploymentChangeHandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentLifecycleDelegate) HasCreate() bool {
|
||||||
|
return n.create != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentLifecycleDelegate) Create(obj *v1.Deployment) (runtime.Object, error) {
|
||||||
|
if n.create == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentLifecycleDelegate) HasFinalize() bool {
|
||||||
|
return n.remove != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentLifecycleDelegate) Remove(obj *v1.Deployment) (runtime.Object, error) {
|
||||||
|
if n.remove == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.remove(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *deploymentLifecycleDelegate) Updated(obj *v1.Deployment) (runtime.Object, error) {
|
||||||
|
if n.update == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.update(obj)
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rancher/norman/lifecycle"
|
||||||
|
v1 "k8s.io/api/apps/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeploymentLifecycle interface {
|
||||||
|
Create(obj *v1.Deployment) (runtime.Object, error)
|
||||||
|
Remove(obj *v1.Deployment) (runtime.Object, error)
|
||||||
|
Updated(obj *v1.Deployment) (runtime.Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type deploymentLifecycleAdapter struct {
|
||||||
|
lifecycle DeploymentLifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *deploymentLifecycleAdapter) HasCreate() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *deploymentLifecycleAdapter) HasFinalize() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasFinalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *deploymentLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Create(obj.(*v1.Deployment))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *deploymentLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Remove(obj.(*v1.Deployment))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *deploymentLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Updated(obj.(*v1.Deployment))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDeploymentLifecycleAdapter(name string, clusterScoped bool, client DeploymentInterface, l DeploymentLifecycle) DeploymentHandlerFunc {
|
||||||
|
adapter := &deploymentLifecycleAdapter{lifecycle: l}
|
||||||
|
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
|
||||||
|
return func(key string, obj *v1.Deployment) (runtime.Object, error) {
|
||||||
|
newObj, err := syncFn(key, obj)
|
||||||
|
if o, ok := newObj.(runtime.Object); ok {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
"github.com/rancher/norman/objectclient/dynamic"
|
||||||
|
"github.com/rancher/norman/restwatch"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
contextKeyType struct{}
|
||||||
|
contextClientsKeyType struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Interface interface {
|
||||||
|
RESTClient() rest.Interface
|
||||||
|
controller.Starter
|
||||||
|
|
||||||
|
DeploymentsGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
type Clients struct {
|
||||||
|
Interface Interface
|
||||||
|
|
||||||
|
Deployment DeploymentClient
|
||||||
|
}
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
sync.Mutex
|
||||||
|
restClient rest.Interface
|
||||||
|
starters []controller.Starter
|
||||||
|
|
||||||
|
deploymentControllers map[string]DeploymentController
|
||||||
|
}
|
||||||
|
|
||||||
|
func Factory(ctx context.Context, config rest.Config) (context.Context, controller.Starter, error) {
|
||||||
|
c, err := NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := NewClientsFromInterface(c)
|
||||||
|
|
||||||
|
ctx = context.WithValue(ctx, contextKeyType{}, c)
|
||||||
|
ctx = context.WithValue(ctx, contextClientsKeyType{}, cs)
|
||||||
|
return ctx, c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClientsFrom(ctx context.Context) *Clients {
|
||||||
|
return ctx.Value(contextClientsKeyType{}).(*Clients)
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(ctx context.Context) Interface {
|
||||||
|
return ctx.Value(contextKeyType{}).(Interface)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClients(config rest.Config) (*Clients, error) {
|
||||||
|
iface, err := NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewClientsFromInterface(iface), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientsFromInterface(iface Interface) *Clients {
|
||||||
|
return &Clients{
|
||||||
|
Interface: iface,
|
||||||
|
|
||||||
|
Deployment: &deploymentClient2{
|
||||||
|
iface: iface.Deployments(""),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewForConfig(config rest.Config) (Interface, error) {
|
||||||
|
if config.NegotiatedSerializer == nil {
|
||||||
|
config.NegotiatedSerializer = dynamic.NegotiatedSerializer
|
||||||
|
}
|
||||||
|
|
||||||
|
restClient, err := restwatch.UnversionedRESTClientFor(&config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
restClient: restClient,
|
||||||
|
|
||||||
|
deploymentControllers: map[string]DeploymentController{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) RESTClient() rest.Interface {
|
||||||
|
return c.restClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Sync(ctx context.Context) error {
|
||||||
|
return controller.Sync(ctx, c.starters...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Start(ctx context.Context, threadiness int) error {
|
||||||
|
return controller.Start(ctx, threadiness, c.starters...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentsGetter interface {
|
||||||
|
Deployments(namespace string) DeploymentInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Deployments(namespace string) DeploymentInterface {
|
||||||
|
objectClient := objectclient.NewObjectClient(namespace, c.restClient, &DeploymentResource, DeploymentGroupVersionKind, deploymentFactory{})
|
||||||
|
return &deploymentClient{
|
||||||
|
ns: namespace,
|
||||||
|
client: c,
|
||||||
|
objectClient: objectClient,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GroupName = "apps"
|
||||||
|
Version = "v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SchemeGroupVersion is group version used to register these objects
|
||||||
|
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version}
|
||||||
|
|
||||||
|
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||||
|
func Kind(kind string) schema.GroupKind {
|
||||||
|
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||||
|
func Resource(resource string) schema.GroupResource {
|
||||||
|
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||||
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
|
)
|
||||||
|
|
||||||
|
// Adds the list of known types to api.Scheme.
|
||||||
|
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
|
// TODO this gets cleaned up when the types are fixed
|
||||||
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
|
|
||||||
|
&DeploymentList{},
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *NodeList) DeepCopyInto(out *NodeList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
out.ListMeta = in.ListMeta
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]corev1.Node, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeList.
|
||||||
|
func (in *NodeList) DeepCopy() *NodeList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NodeList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *NodeList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PodList) DeepCopyInto(out *PodList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
out.ListMeta = in.ListMeta
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]corev1.Pod, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodList.
|
||||||
|
func (in *PodList) DeepCopy() *PodList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PodList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *PodList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *ServiceList) DeepCopyInto(out *ServiceList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
out.ListMeta = in.ListMeta
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]corev1.Service, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceList.
|
||||||
|
func (in *ServiceList) DeepCopy() *ServiceList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(ServiceList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *ServiceList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
"github.com/rancher/norman/objectclient/dynamic"
|
||||||
|
"github.com/rancher/norman/restwatch"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
contextKeyType struct{}
|
||||||
|
contextClientsKeyType struct{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Interface interface {
|
||||||
|
RESTClient() rest.Interface
|
||||||
|
controller.Starter
|
||||||
|
|
||||||
|
NodesGetter
|
||||||
|
ServicesGetter
|
||||||
|
PodsGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
type Clients struct {
|
||||||
|
Interface Interface
|
||||||
|
|
||||||
|
Node NodeClient
|
||||||
|
Service ServiceClient
|
||||||
|
Pod PodClient
|
||||||
|
}
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
sync.Mutex
|
||||||
|
restClient rest.Interface
|
||||||
|
starters []controller.Starter
|
||||||
|
|
||||||
|
nodeControllers map[string]NodeController
|
||||||
|
serviceControllers map[string]ServiceController
|
||||||
|
podControllers map[string]PodController
|
||||||
|
}
|
||||||
|
|
||||||
|
func Factory(ctx context.Context, config rest.Config) (context.Context, controller.Starter, error) {
|
||||||
|
c, err := NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := NewClientsFromInterface(c)
|
||||||
|
|
||||||
|
ctx = context.WithValue(ctx, contextKeyType{}, c)
|
||||||
|
ctx = context.WithValue(ctx, contextClientsKeyType{}, cs)
|
||||||
|
return ctx, c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClientsFrom(ctx context.Context) *Clients {
|
||||||
|
return ctx.Value(contextClientsKeyType{}).(*Clients)
|
||||||
|
}
|
||||||
|
|
||||||
|
func From(ctx context.Context) Interface {
|
||||||
|
return ctx.Value(contextKeyType{}).(Interface)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClients(config rest.Config) (*Clients, error) {
|
||||||
|
iface, err := NewForConfig(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewClientsFromInterface(iface), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientsFromInterface(iface Interface) *Clients {
|
||||||
|
return &Clients{
|
||||||
|
Interface: iface,
|
||||||
|
|
||||||
|
Node: &nodeClient2{
|
||||||
|
iface: iface.Nodes(""),
|
||||||
|
},
|
||||||
|
Service: &serviceClient2{
|
||||||
|
iface: iface.Services(""),
|
||||||
|
},
|
||||||
|
Pod: &podClient2{
|
||||||
|
iface: iface.Pods(""),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewForConfig(config rest.Config) (Interface, error) {
|
||||||
|
if config.NegotiatedSerializer == nil {
|
||||||
|
config.NegotiatedSerializer = dynamic.NegotiatedSerializer
|
||||||
|
}
|
||||||
|
|
||||||
|
restClient, err := restwatch.UnversionedRESTClientFor(&config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
restClient: restClient,
|
||||||
|
|
||||||
|
nodeControllers: map[string]NodeController{},
|
||||||
|
serviceControllers: map[string]ServiceController{},
|
||||||
|
podControllers: map[string]PodController{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) RESTClient() rest.Interface {
|
||||||
|
return c.restClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Sync(ctx context.Context) error {
|
||||||
|
return controller.Sync(ctx, c.starters...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Start(ctx context.Context, threadiness int) error {
|
||||||
|
return controller.Start(ctx, threadiness, c.starters...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodesGetter interface {
|
||||||
|
Nodes(namespace string) NodeInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Nodes(namespace string) NodeInterface {
|
||||||
|
objectClient := objectclient.NewObjectClient(namespace, c.restClient, &NodeResource, NodeGroupVersionKind, nodeFactory{})
|
||||||
|
return &nodeClient{
|
||||||
|
ns: namespace,
|
||||||
|
client: c,
|
||||||
|
objectClient: objectClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServicesGetter interface {
|
||||||
|
Services(namespace string) ServiceInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Services(namespace string) ServiceInterface {
|
||||||
|
objectClient := objectclient.NewObjectClient(namespace, c.restClient, &ServiceResource, ServiceGroupVersionKind, serviceFactory{})
|
||||||
|
return &serviceClient{
|
||||||
|
ns: namespace,
|
||||||
|
client: c,
|
||||||
|
objectClient: objectClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodsGetter interface {
|
||||||
|
Pods(namespace string) PodInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Pods(namespace string) PodInterface {
|
||||||
|
objectClient := objectclient.NewObjectClient(namespace, c.restClient, &PodResource, PodGroupVersionKind, podFactory{})
|
||||||
|
return &podClient{
|
||||||
|
ns: namespace,
|
||||||
|
client: c,
|
||||||
|
objectClient: objectClient,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,440 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
NodeGroupVersionKind = schema.GroupVersionKind{
|
||||||
|
Version: Version,
|
||||||
|
Group: GroupName,
|
||||||
|
Kind: "Node",
|
||||||
|
}
|
||||||
|
NodeResource = metav1.APIResource{
|
||||||
|
Name: "nodes",
|
||||||
|
SingularName: "node",
|
||||||
|
Namespaced: false,
|
||||||
|
Kind: NodeGroupVersionKind.Kind,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewNode(namespace, name string, obj v1.Node) *v1.Node {
|
||||||
|
obj.APIVersion, obj.Kind = NodeGroupVersionKind.ToAPIVersionAndKind()
|
||||||
|
obj.Name = name
|
||||||
|
obj.Namespace = namespace
|
||||||
|
return &obj
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []v1.Node
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeHandlerFunc func(key string, obj *v1.Node) (runtime.Object, error)
|
||||||
|
|
||||||
|
type NodeChangeHandlerFunc func(obj *v1.Node) (runtime.Object, error)
|
||||||
|
|
||||||
|
type NodeLister interface {
|
||||||
|
List(namespace string, selector labels.Selector) (ret []*v1.Node, err error)
|
||||||
|
Get(namespace, name string) (*v1.Node, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeController interface {
|
||||||
|
Generic() controller.GenericController
|
||||||
|
Informer() cache.SharedIndexInformer
|
||||||
|
Lister() NodeLister
|
||||||
|
AddHandler(ctx context.Context, name string, handler NodeHandlerFunc)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodeHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
Sync(ctx context.Context) error
|
||||||
|
Start(ctx context.Context, threadiness int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeInterface interface {
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Create(*v1.Node) (*v1.Node, error)
|
||||||
|
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Node, error)
|
||||||
|
Get(name string, opts metav1.GetOptions) (*v1.Node, error)
|
||||||
|
Update(*v1.Node) (*v1.Node, error)
|
||||||
|
Delete(name string, options *metav1.DeleteOptions) error
|
||||||
|
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(opts metav1.ListOptions) (*NodeList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
Controller() NodeController
|
||||||
|
AddHandler(ctx context.Context, name string, sync NodeHandlerFunc)
|
||||||
|
AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc)
|
||||||
|
AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeLister struct {
|
||||||
|
controller *nodeController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *nodeLister) List(namespace string, selector labels.Selector) (ret []*v1.Node, err error) {
|
||||||
|
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
|
||||||
|
ret = append(ret, obj.(*v1.Node))
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *nodeLister) Get(namespace, name string) (*v1.Node, error) {
|
||||||
|
var key string
|
||||||
|
if namespace != "" {
|
||||||
|
key = namespace + "/" + name
|
||||||
|
} else {
|
||||||
|
key = name
|
||||||
|
}
|
||||||
|
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(schema.GroupResource{
|
||||||
|
Group: NodeGroupVersionKind.Group,
|
||||||
|
Resource: "node",
|
||||||
|
}, key)
|
||||||
|
}
|
||||||
|
return obj.(*v1.Node), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeController struct {
|
||||||
|
controller.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nodeController) Generic() controller.GenericController {
|
||||||
|
return c.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nodeController) Lister() NodeLister {
|
||||||
|
return &nodeLister{
|
||||||
|
controller: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nodeController) AddHandler(ctx context.Context, name string, handler NodeHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Node); ok {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *nodeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodeHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Node); ok && controller.ObjectInCluster(cluster, obj) {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeFactory struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c nodeFactory) Object() runtime.Object {
|
||||||
|
return &v1.Node{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c nodeFactory) List() runtime.Object {
|
||||||
|
return &NodeList{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Controller() NodeController {
|
||||||
|
s.client.Lock()
|
||||||
|
defer s.client.Unlock()
|
||||||
|
|
||||||
|
c, ok := s.client.nodeControllers[s.ns]
|
||||||
|
if ok {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
genericController := controller.NewGenericController(NodeGroupVersionKind.Kind+"Controller",
|
||||||
|
s.objectClient)
|
||||||
|
|
||||||
|
c = &nodeController{
|
||||||
|
GenericController: genericController,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.client.nodeControllers[s.ns] = c
|
||||||
|
s.client.starters = append(s.client.starters, c)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeClient struct {
|
||||||
|
client *Client
|
||||||
|
ns string
|
||||||
|
objectClient *objectclient.ObjectClient
|
||||||
|
controller NodeController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return s.objectClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Create(o *v1.Node) (*v1.Node, error) {
|
||||||
|
obj, err := s.objectClient.Create(o)
|
||||||
|
return obj.(*v1.Node), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Get(name string, opts metav1.GetOptions) (*v1.Node, error) {
|
||||||
|
obj, err := s.objectClient.Get(name, opts)
|
||||||
|
return obj.(*v1.Node), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Node, error) {
|
||||||
|
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
|
||||||
|
return obj.(*v1.Node), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Update(o *v1.Node) (*v1.Node, error) {
|
||||||
|
obj, err := s.objectClient.Update(o.Name, o)
|
||||||
|
return obj.(*v1.Node), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Delete(name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.Delete(name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) List(opts metav1.ListOptions) (*NodeList, error) {
|
||||||
|
obj, err := s.objectClient.List(opts)
|
||||||
|
return obj.(*NodeList), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return s.objectClient.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched deployment.
|
||||||
|
func (s *nodeClient) Patch(o *v1.Node, patchType types.PatchType, data []byte, subresources ...string) (*v1.Node, error) {
|
||||||
|
obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...)
|
||||||
|
return obj.(*v1.Node), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) AddHandler(ctx context.Context, name string, sync NodeHandlerFunc) {
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle) {
|
||||||
|
sync := NewNodeLifecycleAdapter(name, false, s, lifecycle)
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc) {
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *nodeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle) {
|
||||||
|
sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeIndexer func(obj *v1.Node) ([]string, error)
|
||||||
|
|
||||||
|
type NodeClientCache interface {
|
||||||
|
Get(namespace, name string) (*v1.Node, error)
|
||||||
|
List(namespace string, selector labels.Selector) ([]*v1.Node, error)
|
||||||
|
|
||||||
|
Index(name string, indexer NodeIndexer)
|
||||||
|
GetIndexed(name, key string) ([]*v1.Node, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeClient interface {
|
||||||
|
Create(*v1.Node) (*v1.Node, error)
|
||||||
|
Get(namespace, name string, opts metav1.GetOptions) (*v1.Node, error)
|
||||||
|
Update(*v1.Node) (*v1.Node, error)
|
||||||
|
Delete(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(namespace string, opts metav1.ListOptions) (*NodeList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
|
||||||
|
Cache() NodeClientCache
|
||||||
|
|
||||||
|
OnCreate(ctx context.Context, name string, sync NodeChangeHandlerFunc)
|
||||||
|
OnChange(ctx context.Context, name string, sync NodeChangeHandlerFunc)
|
||||||
|
OnRemove(ctx context.Context, name string, sync NodeChangeHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
|
||||||
|
Generic() controller.GenericController
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Interface() NodeInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeClientCache struct {
|
||||||
|
client *nodeClient2
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeClient2 struct {
|
||||||
|
iface NodeInterface
|
||||||
|
controller NodeController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Interface() NodeInterface {
|
||||||
|
return n.iface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Generic() controller.GenericController {
|
||||||
|
return n.iface.Controller().Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return n.Interface().ObjectClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Enqueue(namespace, name string) {
|
||||||
|
n.iface.Controller().Enqueue(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Create(obj *v1.Node) (*v1.Node, error) {
|
||||||
|
return n.iface.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Get(namespace, name string, opts metav1.GetOptions) (*v1.Node, error) {
|
||||||
|
return n.iface.GetNamespaced(namespace, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Update(obj *v1.Node) (*v1.Node, error) {
|
||||||
|
return n.iface.Update(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Delete(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return n.iface.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) List(namespace string, opts metav1.ListOptions) (*NodeList, error) {
|
||||||
|
return n.iface.List(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return n.iface.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClientCache) Get(namespace, name string) (*v1.Node, error) {
|
||||||
|
return n.client.controller.Lister().Get(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClientCache) List(namespace string, selector labels.Selector) ([]*v1.Node, error) {
|
||||||
|
return n.client.controller.Lister().List(namespace, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) Cache() NodeClientCache {
|
||||||
|
n.loadController()
|
||||||
|
return &nodeClientCache{
|
||||||
|
client: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) OnCreate(ctx context.Context, name string, sync NodeChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-create", &nodeLifecycleDelegate{create: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) OnChange(ctx context.Context, name string, sync NodeChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-change", &nodeLifecycleDelegate{update: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) OnRemove(ctx context.Context, name string, sync NodeChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name, &nodeLifecycleDelegate{remove: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClientCache) Index(name string, indexer NodeIndexer) {
|
||||||
|
err := n.client.controller.Informer().GetIndexer().AddIndexers(map[string]cache.IndexFunc{
|
||||||
|
name: func(obj interface{}) ([]string, error) {
|
||||||
|
if v, ok := obj.(*v1.Node); ok {
|
||||||
|
return indexer(v)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClientCache) GetIndexed(name, key string) ([]*v1.Node, error) {
|
||||||
|
var result []*v1.Node
|
||||||
|
objs, err := n.client.controller.Informer().GetIndexer().ByIndex(name, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, obj := range objs {
|
||||||
|
if v, ok := obj.(*v1.Node); ok {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeClient2) loadController() {
|
||||||
|
if n.controller == nil {
|
||||||
|
n.controller = n.iface.Controller()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeLifecycleDelegate struct {
|
||||||
|
create NodeChangeHandlerFunc
|
||||||
|
update NodeChangeHandlerFunc
|
||||||
|
remove NodeChangeHandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeLifecycleDelegate) HasCreate() bool {
|
||||||
|
return n.create != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeLifecycleDelegate) Create(obj *v1.Node) (runtime.Object, error) {
|
||||||
|
if n.create == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeLifecycleDelegate) HasFinalize() bool {
|
||||||
|
return n.remove != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeLifecycleDelegate) Remove(obj *v1.Node) (runtime.Object, error) {
|
||||||
|
if n.remove == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.remove(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *nodeLifecycleDelegate) Updated(obj *v1.Node) (runtime.Object, error) {
|
||||||
|
if n.update == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.update(obj)
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rancher/norman/lifecycle"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NodeLifecycle interface {
|
||||||
|
Create(obj *v1.Node) (runtime.Object, error)
|
||||||
|
Remove(obj *v1.Node) (runtime.Object, error)
|
||||||
|
Updated(obj *v1.Node) (runtime.Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type nodeLifecycleAdapter struct {
|
||||||
|
lifecycle NodeLifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nodeLifecycleAdapter) HasCreate() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nodeLifecycleAdapter) HasFinalize() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasFinalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nodeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Create(obj.(*v1.Node))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nodeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Remove(obj.(*v1.Node))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nodeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Updated(obj.(*v1.Node))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNodeLifecycleAdapter(name string, clusterScoped bool, client NodeInterface, l NodeLifecycle) NodeHandlerFunc {
|
||||||
|
adapter := &nodeLifecycleAdapter{lifecycle: l}
|
||||||
|
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
|
||||||
|
return func(key string, obj *v1.Node) (runtime.Object, error) {
|
||||||
|
newObj, err := syncFn(key, obj)
|
||||||
|
if o, ok := newObj.(runtime.Object); ok {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,441 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
PodGroupVersionKind = schema.GroupVersionKind{
|
||||||
|
Version: Version,
|
||||||
|
Group: GroupName,
|
||||||
|
Kind: "Pod",
|
||||||
|
}
|
||||||
|
PodResource = metav1.APIResource{
|
||||||
|
Name: "pods",
|
||||||
|
SingularName: "pod",
|
||||||
|
Namespaced: true,
|
||||||
|
|
||||||
|
Kind: PodGroupVersionKind.Kind,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPod(namespace, name string, obj v1.Pod) *v1.Pod {
|
||||||
|
obj.APIVersion, obj.Kind = PodGroupVersionKind.ToAPIVersionAndKind()
|
||||||
|
obj.Name = name
|
||||||
|
obj.Namespace = namespace
|
||||||
|
return &obj
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []v1.Pod
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodHandlerFunc func(key string, obj *v1.Pod) (runtime.Object, error)
|
||||||
|
|
||||||
|
type PodChangeHandlerFunc func(obj *v1.Pod) (runtime.Object, error)
|
||||||
|
|
||||||
|
type PodLister interface {
|
||||||
|
List(namespace string, selector labels.Selector) (ret []*v1.Pod, err error)
|
||||||
|
Get(namespace, name string) (*v1.Pod, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodController interface {
|
||||||
|
Generic() controller.GenericController
|
||||||
|
Informer() cache.SharedIndexInformer
|
||||||
|
Lister() PodLister
|
||||||
|
AddHandler(ctx context.Context, name string, handler PodHandlerFunc)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PodHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
Sync(ctx context.Context) error
|
||||||
|
Start(ctx context.Context, threadiness int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodInterface interface {
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Create(*v1.Pod) (*v1.Pod, error)
|
||||||
|
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error)
|
||||||
|
Get(name string, opts metav1.GetOptions) (*v1.Pod, error)
|
||||||
|
Update(*v1.Pod) (*v1.Pod, error)
|
||||||
|
Delete(name string, options *metav1.DeleteOptions) error
|
||||||
|
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(opts metav1.ListOptions) (*PodList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
Controller() PodController
|
||||||
|
AddHandler(ctx context.Context, name string, sync PodHandlerFunc)
|
||||||
|
AddLifecycle(ctx context.Context, name string, lifecycle PodLifecycle)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodHandlerFunc)
|
||||||
|
AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodLifecycle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type podLister struct {
|
||||||
|
controller *podController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *podLister) List(namespace string, selector labels.Selector) (ret []*v1.Pod, err error) {
|
||||||
|
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
|
||||||
|
ret = append(ret, obj.(*v1.Pod))
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *podLister) Get(namespace, name string) (*v1.Pod, error) {
|
||||||
|
var key string
|
||||||
|
if namespace != "" {
|
||||||
|
key = namespace + "/" + name
|
||||||
|
} else {
|
||||||
|
key = name
|
||||||
|
}
|
||||||
|
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(schema.GroupResource{
|
||||||
|
Group: PodGroupVersionKind.Group,
|
||||||
|
Resource: "pod",
|
||||||
|
}, key)
|
||||||
|
}
|
||||||
|
return obj.(*v1.Pod), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type podController struct {
|
||||||
|
controller.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *podController) Generic() controller.GenericController {
|
||||||
|
return c.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *podController) Lister() PodLister {
|
||||||
|
return &podLister{
|
||||||
|
controller: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *podController) AddHandler(ctx context.Context, name string, handler PodHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Pod); ok {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *podController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PodHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Pod); ok && controller.ObjectInCluster(cluster, obj) {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type podFactory struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c podFactory) Object() runtime.Object {
|
||||||
|
return &v1.Pod{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c podFactory) List() runtime.Object {
|
||||||
|
return &PodList{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Controller() PodController {
|
||||||
|
s.client.Lock()
|
||||||
|
defer s.client.Unlock()
|
||||||
|
|
||||||
|
c, ok := s.client.podControllers[s.ns]
|
||||||
|
if ok {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
genericController := controller.NewGenericController(PodGroupVersionKind.Kind+"Controller",
|
||||||
|
s.objectClient)
|
||||||
|
|
||||||
|
c = &podController{
|
||||||
|
GenericController: genericController,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.client.podControllers[s.ns] = c
|
||||||
|
s.client.starters = append(s.client.starters, c)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type podClient struct {
|
||||||
|
client *Client
|
||||||
|
ns string
|
||||||
|
objectClient *objectclient.ObjectClient
|
||||||
|
controller PodController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return s.objectClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Create(o *v1.Pod) (*v1.Pod, error) {
|
||||||
|
obj, err := s.objectClient.Create(o)
|
||||||
|
return obj.(*v1.Pod), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Get(name string, opts metav1.GetOptions) (*v1.Pod, error) {
|
||||||
|
obj, err := s.objectClient.Get(name, opts)
|
||||||
|
return obj.(*v1.Pod), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error) {
|
||||||
|
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
|
||||||
|
return obj.(*v1.Pod), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Update(o *v1.Pod) (*v1.Pod, error) {
|
||||||
|
obj, err := s.objectClient.Update(o.Name, o)
|
||||||
|
return obj.(*v1.Pod), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Delete(name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.Delete(name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) List(opts metav1.ListOptions) (*PodList, error) {
|
||||||
|
obj, err := s.objectClient.List(opts)
|
||||||
|
return obj.(*PodList), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return s.objectClient.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched deployment.
|
||||||
|
func (s *podClient) Patch(o *v1.Pod, patchType types.PatchType, data []byte, subresources ...string) (*v1.Pod, error) {
|
||||||
|
obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...)
|
||||||
|
return obj.(*v1.Pod), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) AddHandler(ctx context.Context, name string, sync PodHandlerFunc) {
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) AddLifecycle(ctx context.Context, name string, lifecycle PodLifecycle) {
|
||||||
|
sync := NewPodLifecycleAdapter(name, false, s, lifecycle)
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodHandlerFunc) {
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *podClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodLifecycle) {
|
||||||
|
sync := NewPodLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodIndexer func(obj *v1.Pod) ([]string, error)
|
||||||
|
|
||||||
|
type PodClientCache interface {
|
||||||
|
Get(namespace, name string) (*v1.Pod, error)
|
||||||
|
List(namespace string, selector labels.Selector) ([]*v1.Pod, error)
|
||||||
|
|
||||||
|
Index(name string, indexer PodIndexer)
|
||||||
|
GetIndexed(name, key string) ([]*v1.Pod, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PodClient interface {
|
||||||
|
Create(*v1.Pod) (*v1.Pod, error)
|
||||||
|
Get(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error)
|
||||||
|
Update(*v1.Pod) (*v1.Pod, error)
|
||||||
|
Delete(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(namespace string, opts metav1.ListOptions) (*PodList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
|
||||||
|
Cache() PodClientCache
|
||||||
|
|
||||||
|
OnCreate(ctx context.Context, name string, sync PodChangeHandlerFunc)
|
||||||
|
OnChange(ctx context.Context, name string, sync PodChangeHandlerFunc)
|
||||||
|
OnRemove(ctx context.Context, name string, sync PodChangeHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
|
||||||
|
Generic() controller.GenericController
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Interface() PodInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
type podClientCache struct {
|
||||||
|
client *podClient2
|
||||||
|
}
|
||||||
|
|
||||||
|
type podClient2 struct {
|
||||||
|
iface PodInterface
|
||||||
|
controller PodController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Interface() PodInterface {
|
||||||
|
return n.iface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Generic() controller.GenericController {
|
||||||
|
return n.iface.Controller().Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return n.Interface().ObjectClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Enqueue(namespace, name string) {
|
||||||
|
n.iface.Controller().Enqueue(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Create(obj *v1.Pod) (*v1.Pod, error) {
|
||||||
|
return n.iface.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Get(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error) {
|
||||||
|
return n.iface.GetNamespaced(namespace, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Update(obj *v1.Pod) (*v1.Pod, error) {
|
||||||
|
return n.iface.Update(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Delete(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return n.iface.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) List(namespace string, opts metav1.ListOptions) (*PodList, error) {
|
||||||
|
return n.iface.List(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return n.iface.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClientCache) Get(namespace, name string) (*v1.Pod, error) {
|
||||||
|
return n.client.controller.Lister().Get(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClientCache) List(namespace string, selector labels.Selector) ([]*v1.Pod, error) {
|
||||||
|
return n.client.controller.Lister().List(namespace, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) Cache() PodClientCache {
|
||||||
|
n.loadController()
|
||||||
|
return &podClientCache{
|
||||||
|
client: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) OnCreate(ctx context.Context, name string, sync PodChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-create", &podLifecycleDelegate{create: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) OnChange(ctx context.Context, name string, sync PodChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-change", &podLifecycleDelegate{update: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) OnRemove(ctx context.Context, name string, sync PodChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name, &podLifecycleDelegate{remove: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClientCache) Index(name string, indexer PodIndexer) {
|
||||||
|
err := n.client.controller.Informer().GetIndexer().AddIndexers(map[string]cache.IndexFunc{
|
||||||
|
name: func(obj interface{}) ([]string, error) {
|
||||||
|
if v, ok := obj.(*v1.Pod); ok {
|
||||||
|
return indexer(v)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClientCache) GetIndexed(name, key string) ([]*v1.Pod, error) {
|
||||||
|
var result []*v1.Pod
|
||||||
|
objs, err := n.client.controller.Informer().GetIndexer().ByIndex(name, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, obj := range objs {
|
||||||
|
if v, ok := obj.(*v1.Pod); ok {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podClient2) loadController() {
|
||||||
|
if n.controller == nil {
|
||||||
|
n.controller = n.iface.Controller()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type podLifecycleDelegate struct {
|
||||||
|
create PodChangeHandlerFunc
|
||||||
|
update PodChangeHandlerFunc
|
||||||
|
remove PodChangeHandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podLifecycleDelegate) HasCreate() bool {
|
||||||
|
return n.create != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podLifecycleDelegate) Create(obj *v1.Pod) (runtime.Object, error) {
|
||||||
|
if n.create == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podLifecycleDelegate) HasFinalize() bool {
|
||||||
|
return n.remove != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podLifecycleDelegate) Remove(obj *v1.Pod) (runtime.Object, error) {
|
||||||
|
if n.remove == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.remove(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *podLifecycleDelegate) Updated(obj *v1.Pod) (runtime.Object, error) {
|
||||||
|
if n.update == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.update(obj)
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rancher/norman/lifecycle"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PodLifecycle interface {
|
||||||
|
Create(obj *v1.Pod) (runtime.Object, error)
|
||||||
|
Remove(obj *v1.Pod) (runtime.Object, error)
|
||||||
|
Updated(obj *v1.Pod) (runtime.Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type podLifecycleAdapter struct {
|
||||||
|
lifecycle PodLifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *podLifecycleAdapter) HasCreate() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *podLifecycleAdapter) HasFinalize() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasFinalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *podLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Create(obj.(*v1.Pod))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *podLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Remove(obj.(*v1.Pod))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *podLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Updated(obj.(*v1.Pod))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPodLifecycleAdapter(name string, clusterScoped bool, client PodInterface, l PodLifecycle) PodHandlerFunc {
|
||||||
|
adapter := &podLifecycleAdapter{lifecycle: l}
|
||||||
|
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
|
||||||
|
return func(key string, obj *v1.Pod) (runtime.Object, error) {
|
||||||
|
newObj, err := syncFn(key, obj)
|
||||||
|
if o, ok := newObj.(runtime.Object); ok {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GroupName = ""
|
||||||
|
Version = "v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SchemeGroupVersion is group version used to register these objects
|
||||||
|
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version}
|
||||||
|
|
||||||
|
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||||
|
func Kind(kind string) schema.GroupKind {
|
||||||
|
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||||
|
func Resource(resource string) schema.GroupResource {
|
||||||
|
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||||
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
|
)
|
||||||
|
|
||||||
|
// Adds the list of known types to api.Scheme.
|
||||||
|
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||||
|
// TODO this gets cleaned up when the types are fixed
|
||||||
|
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||||
|
|
||||||
|
&NodeList{},
|
||||||
|
&ServiceList{},
|
||||||
|
&PodList{},
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,441 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/rancher/norman/controller"
|
||||||
|
"github.com/rancher/norman/objectclient"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ServiceGroupVersionKind = schema.GroupVersionKind{
|
||||||
|
Version: Version,
|
||||||
|
Group: GroupName,
|
||||||
|
Kind: "Service",
|
||||||
|
}
|
||||||
|
ServiceResource = metav1.APIResource{
|
||||||
|
Name: "services",
|
||||||
|
SingularName: "service",
|
||||||
|
Namespaced: true,
|
||||||
|
|
||||||
|
Kind: ServiceGroupVersionKind.Kind,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewService(namespace, name string, obj v1.Service) *v1.Service {
|
||||||
|
obj.APIVersion, obj.Kind = ServiceGroupVersionKind.ToAPIVersionAndKind()
|
||||||
|
obj.Name = name
|
||||||
|
obj.Namespace = namespace
|
||||||
|
return &obj
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
Items []v1.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceHandlerFunc func(key string, obj *v1.Service) (runtime.Object, error)
|
||||||
|
|
||||||
|
type ServiceChangeHandlerFunc func(obj *v1.Service) (runtime.Object, error)
|
||||||
|
|
||||||
|
type ServiceLister interface {
|
||||||
|
List(namespace string, selector labels.Selector) (ret []*v1.Service, err error)
|
||||||
|
Get(namespace, name string) (*v1.Service, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceController interface {
|
||||||
|
Generic() controller.GenericController
|
||||||
|
Informer() cache.SharedIndexInformer
|
||||||
|
Lister() ServiceLister
|
||||||
|
AddHandler(ctx context.Context, name string, handler ServiceHandlerFunc)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ServiceHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
Sync(ctx context.Context) error
|
||||||
|
Start(ctx context.Context, threadiness int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceInterface interface {
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Create(*v1.Service) (*v1.Service, error)
|
||||||
|
GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Service, error)
|
||||||
|
Get(name string, opts metav1.GetOptions) (*v1.Service, error)
|
||||||
|
Update(*v1.Service) (*v1.Service, error)
|
||||||
|
Delete(name string, options *metav1.DeleteOptions) error
|
||||||
|
DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(opts metav1.ListOptions) (*ServiceList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
Controller() ServiceController
|
||||||
|
AddHandler(ctx context.Context, name string, sync ServiceHandlerFunc)
|
||||||
|
AddLifecycle(ctx context.Context, name string, lifecycle ServiceLifecycle)
|
||||||
|
AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceHandlerFunc)
|
||||||
|
AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceLifecycle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceLister struct {
|
||||||
|
controller *serviceController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *serviceLister) List(namespace string, selector labels.Selector) (ret []*v1.Service, err error) {
|
||||||
|
err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) {
|
||||||
|
ret = append(ret, obj.(*v1.Service))
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *serviceLister) Get(namespace, name string) (*v1.Service, error) {
|
||||||
|
var key string
|
||||||
|
if namespace != "" {
|
||||||
|
key = namespace + "/" + name
|
||||||
|
} else {
|
||||||
|
key = name
|
||||||
|
}
|
||||||
|
obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(schema.GroupResource{
|
||||||
|
Group: ServiceGroupVersionKind.Group,
|
||||||
|
Resource: "service",
|
||||||
|
}, key)
|
||||||
|
}
|
||||||
|
return obj.(*v1.Service), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceController struct {
|
||||||
|
controller.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serviceController) Generic() controller.GenericController {
|
||||||
|
return c.GenericController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serviceController) Lister() ServiceLister {
|
||||||
|
return &serviceLister{
|
||||||
|
controller: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serviceController) AddHandler(ctx context.Context, name string, handler ServiceHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Service); ok {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *serviceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ServiceHandlerFunc) {
|
||||||
|
c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) {
|
||||||
|
if obj == nil {
|
||||||
|
return handler(key, nil)
|
||||||
|
} else if v, ok := obj.(*v1.Service); ok && controller.ObjectInCluster(cluster, obj) {
|
||||||
|
return handler(key, v)
|
||||||
|
} else {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceFactory struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c serviceFactory) Object() runtime.Object {
|
||||||
|
return &v1.Service{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c serviceFactory) List() runtime.Object {
|
||||||
|
return &ServiceList{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Controller() ServiceController {
|
||||||
|
s.client.Lock()
|
||||||
|
defer s.client.Unlock()
|
||||||
|
|
||||||
|
c, ok := s.client.serviceControllers[s.ns]
|
||||||
|
if ok {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
genericController := controller.NewGenericController(ServiceGroupVersionKind.Kind+"Controller",
|
||||||
|
s.objectClient)
|
||||||
|
|
||||||
|
c = &serviceController{
|
||||||
|
GenericController: genericController,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.client.serviceControllers[s.ns] = c
|
||||||
|
s.client.starters = append(s.client.starters, c)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceClient struct {
|
||||||
|
client *Client
|
||||||
|
ns string
|
||||||
|
objectClient *objectclient.ObjectClient
|
||||||
|
controller ServiceController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return s.objectClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Create(o *v1.Service) (*v1.Service, error) {
|
||||||
|
obj, err := s.objectClient.Create(o)
|
||||||
|
return obj.(*v1.Service), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Get(name string, opts metav1.GetOptions) (*v1.Service, error) {
|
||||||
|
obj, err := s.objectClient.Get(name, opts)
|
||||||
|
return obj.(*v1.Service), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Service, error) {
|
||||||
|
obj, err := s.objectClient.GetNamespaced(namespace, name, opts)
|
||||||
|
return obj.(*v1.Service), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Update(o *v1.Service) (*v1.Service, error) {
|
||||||
|
obj, err := s.objectClient.Update(o.Name, o)
|
||||||
|
return obj.(*v1.Service), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Delete(name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.Delete(name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return s.objectClient.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) List(opts metav1.ListOptions) (*ServiceList, error) {
|
||||||
|
obj, err := s.objectClient.List(opts)
|
||||||
|
return obj.(*ServiceList), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return s.objectClient.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch applies the patch and returns the patched deployment.
|
||||||
|
func (s *serviceClient) Patch(o *v1.Service, patchType types.PatchType, data []byte, subresources ...string) (*v1.Service, error) {
|
||||||
|
obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...)
|
||||||
|
return obj.(*v1.Service), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return s.objectClient.DeleteCollection(deleteOpts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) AddHandler(ctx context.Context, name string, sync ServiceHandlerFunc) {
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) AddLifecycle(ctx context.Context, name string, lifecycle ServiceLifecycle) {
|
||||||
|
sync := NewServiceLifecycleAdapter(name, false, s, lifecycle)
|
||||||
|
s.Controller().AddHandler(ctx, name, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceHandlerFunc) {
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceLifecycle) {
|
||||||
|
sync := NewServiceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle)
|
||||||
|
s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceIndexer func(obj *v1.Service) ([]string, error)
|
||||||
|
|
||||||
|
type ServiceClientCache interface {
|
||||||
|
Get(namespace, name string) (*v1.Service, error)
|
||||||
|
List(namespace string, selector labels.Selector) ([]*v1.Service, error)
|
||||||
|
|
||||||
|
Index(name string, indexer ServiceIndexer)
|
||||||
|
GetIndexed(name, key string) ([]*v1.Service, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceClient interface {
|
||||||
|
Create(*v1.Service) (*v1.Service, error)
|
||||||
|
Get(namespace, name string, opts metav1.GetOptions) (*v1.Service, error)
|
||||||
|
Update(*v1.Service) (*v1.Service, error)
|
||||||
|
Delete(namespace, name string, options *metav1.DeleteOptions) error
|
||||||
|
List(namespace string, opts metav1.ListOptions) (*ServiceList, error)
|
||||||
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
|
|
||||||
|
Cache() ServiceClientCache
|
||||||
|
|
||||||
|
OnCreate(ctx context.Context, name string, sync ServiceChangeHandlerFunc)
|
||||||
|
OnChange(ctx context.Context, name string, sync ServiceChangeHandlerFunc)
|
||||||
|
OnRemove(ctx context.Context, name string, sync ServiceChangeHandlerFunc)
|
||||||
|
Enqueue(namespace, name string)
|
||||||
|
|
||||||
|
Generic() controller.GenericController
|
||||||
|
ObjectClient() *objectclient.ObjectClient
|
||||||
|
Interface() ServiceInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceClientCache struct {
|
||||||
|
client *serviceClient2
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceClient2 struct {
|
||||||
|
iface ServiceInterface
|
||||||
|
controller ServiceController
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Interface() ServiceInterface {
|
||||||
|
return n.iface
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Generic() controller.GenericController {
|
||||||
|
return n.iface.Controller().Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) ObjectClient() *objectclient.ObjectClient {
|
||||||
|
return n.Interface().ObjectClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Enqueue(namespace, name string) {
|
||||||
|
n.iface.Controller().Enqueue(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Create(obj *v1.Service) (*v1.Service, error) {
|
||||||
|
return n.iface.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Get(namespace, name string, opts metav1.GetOptions) (*v1.Service, error) {
|
||||||
|
return n.iface.GetNamespaced(namespace, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Update(obj *v1.Service) (*v1.Service, error) {
|
||||||
|
return n.iface.Update(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Delete(namespace, name string, options *metav1.DeleteOptions) error {
|
||||||
|
return n.iface.DeleteNamespaced(namespace, name, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) List(namespace string, opts metav1.ListOptions) (*ServiceList, error) {
|
||||||
|
return n.iface.List(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
return n.iface.Watch(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClientCache) Get(namespace, name string) (*v1.Service, error) {
|
||||||
|
return n.client.controller.Lister().Get(namespace, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClientCache) List(namespace string, selector labels.Selector) ([]*v1.Service, error) {
|
||||||
|
return n.client.controller.Lister().List(namespace, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) Cache() ServiceClientCache {
|
||||||
|
n.loadController()
|
||||||
|
return &serviceClientCache{
|
||||||
|
client: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) OnCreate(ctx context.Context, name string, sync ServiceChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-create", &serviceLifecycleDelegate{create: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) OnChange(ctx context.Context, name string, sync ServiceChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name+"-change", &serviceLifecycleDelegate{update: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) OnRemove(ctx context.Context, name string, sync ServiceChangeHandlerFunc) {
|
||||||
|
n.loadController()
|
||||||
|
n.iface.AddLifecycle(ctx, name, &serviceLifecycleDelegate{remove: sync})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClientCache) Index(name string, indexer ServiceIndexer) {
|
||||||
|
err := n.client.controller.Informer().GetIndexer().AddIndexers(map[string]cache.IndexFunc{
|
||||||
|
name: func(obj interface{}) ([]string, error) {
|
||||||
|
if v, ok := obj.(*v1.Service); ok {
|
||||||
|
return indexer(v)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClientCache) GetIndexed(name, key string) ([]*v1.Service, error) {
|
||||||
|
var result []*v1.Service
|
||||||
|
objs, err := n.client.controller.Informer().GetIndexer().ByIndex(name, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, obj := range objs {
|
||||||
|
if v, ok := obj.(*v1.Service); ok {
|
||||||
|
result = append(result, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceClient2) loadController() {
|
||||||
|
if n.controller == nil {
|
||||||
|
n.controller = n.iface.Controller()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceLifecycleDelegate struct {
|
||||||
|
create ServiceChangeHandlerFunc
|
||||||
|
update ServiceChangeHandlerFunc
|
||||||
|
remove ServiceChangeHandlerFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceLifecycleDelegate) HasCreate() bool {
|
||||||
|
return n.create != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceLifecycleDelegate) Create(obj *v1.Service) (runtime.Object, error) {
|
||||||
|
if n.create == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceLifecycleDelegate) HasFinalize() bool {
|
||||||
|
return n.remove != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceLifecycleDelegate) Remove(obj *v1.Service) (runtime.Object, error) {
|
||||||
|
if n.remove == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.remove(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *serviceLifecycleDelegate) Updated(obj *v1.Service) (runtime.Object, error) {
|
||||||
|
if n.update == nil {
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return n.update(obj)
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/rancher/norman/lifecycle"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceLifecycle interface {
|
||||||
|
Create(obj *v1.Service) (runtime.Object, error)
|
||||||
|
Remove(obj *v1.Service) (runtime.Object, error)
|
||||||
|
Updated(obj *v1.Service) (runtime.Object, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type serviceLifecycleAdapter struct {
|
||||||
|
lifecycle ServiceLifecycle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *serviceLifecycleAdapter) HasCreate() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *serviceLifecycleAdapter) HasFinalize() bool {
|
||||||
|
o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition)
|
||||||
|
return !ok || o.HasFinalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *serviceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Create(obj.(*v1.Service))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *serviceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Remove(obj.(*v1.Service))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *serviceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
o, err := w.lifecycle.Updated(obj.(*v1.Service))
|
||||||
|
if o == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceLifecycleAdapter(name string, clusterScoped bool, client ServiceInterface, l ServiceLifecycle) ServiceHandlerFunc {
|
||||||
|
adapter := &serviceLifecycleAdapter{lifecycle: l}
|
||||||
|
syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient())
|
||||||
|
return func(key string, obj *v1.Service) (runtime.Object, error) {
|
||||||
|
newObj, err := syncFn(key, obj)
|
||||||
|
if o, ok := newObj.(runtime.Object); ok {
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@ import (
|
||||||
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
v1 "github.com/rancher/k3s/types/apis/k3s.cattle.io/v1"
|
||||||
"github.com/rancher/norman/generator"
|
"github.com/rancher/norman/generator"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
v13 "k8s.io/api/apps/v1"
|
||||||
|
v12 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -65,4 +67,19 @@ func main() {
|
||||||
if err := generator.DefaultGenerate(v1.Schemas, basePackage, false, nil); err != nil {
|
if err := generator.DefaultGenerate(v1.Schemas, basePackage, false, nil); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := generator.ControllersForForeignTypes(basePackage, v12.SchemeGroupVersion, []interface{}{
|
||||||
|
v12.Service{},
|
||||||
|
v12.Pod{},
|
||||||
|
}, []interface{}{
|
||||||
|
v12.Node{},
|
||||||
|
}); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := generator.ControllersForForeignTypes(basePackage, v13.SchemeGroupVersion, []interface{}{
|
||||||
|
v13.Deployment{},
|
||||||
|
}, nil); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue