mirror of
https://github.com/rancher/rke.git
synced 2025-08-01 23:33:39 +00:00
Merge pull request #6 from galal-hussein/cluster_controller_structures
Cluster controller structures
This commit is contained in:
commit
7172f6ec46
@ -1,4 +1,5 @@
|
||||
---
|
||||
auth_type: x509
|
||||
network_plugin: flannel
|
||||
hosts:
|
||||
- hostname: server1
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
"k8s.io/client-go/util/cert"
|
||||
)
|
||||
|
||||
func SetUpAuthentication(kubeCluster, currentCluster *Cluster, authType string) error {
|
||||
if authType == X509AuthenticationProvider {
|
||||
func SetUpAuthentication(kubeCluster, currentCluster *Cluster) error {
|
||||
if kubeCluster.AuthType == X509AuthenticationProvider {
|
||||
var err error
|
||||
if currentCluster != nil {
|
||||
kubeCluster.Certificates, err = getClusterCerts(kubeCluster.KubeClient)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/rancher/rke/hosts"
|
||||
"github.com/rancher/rke/pki"
|
||||
"github.com/rancher/rke/services"
|
||||
@ -13,8 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type Cluster struct {
|
||||
Services services.Services `yaml:"services"`
|
||||
Hosts []hosts.Host `yaml:"hosts"`
|
||||
v1.RKEConfig `yaml:",inline"`
|
||||
EtcdHosts []hosts.Host
|
||||
WorkerHosts []hosts.Host
|
||||
ControlPlaneHosts []hosts.Host
|
||||
@ -22,7 +22,6 @@ type Cluster struct {
|
||||
KubernetesServiceIP net.IP
|
||||
Certificates map[string]pki.CertificatePKI
|
||||
ClusterDomain string
|
||||
NetworkPlugin string `yaml:"network_plugin"`
|
||||
ClusterCIDR string
|
||||
ClusterDNSServer string
|
||||
}
|
||||
|
@ -38,13 +38,16 @@ func (c *Cluster) InvertIndexHosts() error {
|
||||
for _, host := range c.Hosts {
|
||||
for _, role := range host.Role {
|
||||
logrus.Debugf("Host: " + host.Hostname + " has role: " + role)
|
||||
newHost := hosts.Host{
|
||||
RKEConfigHost: host,
|
||||
}
|
||||
switch role {
|
||||
case services.ETCDRole:
|
||||
c.EtcdHosts = append(c.EtcdHosts, host)
|
||||
c.EtcdHosts = append(c.EtcdHosts, newHost)
|
||||
case services.ControlRole:
|
||||
c.ControlPlaneHosts = append(c.ControlPlaneHosts, host)
|
||||
c.ControlPlaneHosts = append(c.ControlPlaneHosts, newHost)
|
||||
case services.WorkerRole:
|
||||
c.WorkerHosts = append(c.WorkerHosts, host)
|
||||
c.WorkerHosts = append(c.WorkerHosts, newHost)
|
||||
default:
|
||||
return fmt.Errorf("Failed to recognize host [%s] role %s", host.Hostname, role)
|
||||
}
|
||||
@ -53,8 +56,8 @@ func (c *Cluster) InvertIndexHosts() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cluster) SetUpHosts(authType string) error {
|
||||
if authType == X509AuthenticationProvider {
|
||||
func (c *Cluster) SetUpHosts() error {
|
||||
if c.AuthType == X509AuthenticationProvider {
|
||||
logrus.Infof("[certificates] Deploying kubernetes certificates to Cluster nodes")
|
||||
err := pki.DeployCertificatesOnMasters(c.ControlPlaneHosts, c.Certificates)
|
||||
if err != nil {
|
||||
|
@ -21,12 +21,6 @@ func ClusterCommand() cli.Command {
|
||||
Value: "cluster.yml",
|
||||
EnvVar: "CLUSTER_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "auth-type",
|
||||
Usage: "Specify authentication type",
|
||||
Value: "x509",
|
||||
EnvVar: "AUTH_TYPE",
|
||||
},
|
||||
}
|
||||
return cli.Command{
|
||||
Name: "cluster",
|
||||
@ -44,7 +38,7 @@ func ClusterCommand() cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func ClusterUp(clusterFile, authType string) (string, string, string, string, error) {
|
||||
func ClusterUp(clusterFile string) (string, string, string, string, error) {
|
||||
logrus.Infof("Building Kubernetes cluster")
|
||||
var APIURL, caCrt, clientCert, clientKey string
|
||||
kubeCluster, err := cluster.ParseConfig(clusterFile)
|
||||
@ -62,12 +56,12 @@ func ClusterUp(clusterFile, authType string) (string, string, string, string, er
|
||||
return APIURL, caCrt, clientCert, clientKey, err
|
||||
}
|
||||
|
||||
err = cluster.SetUpAuthentication(kubeCluster, currentCluster, authType)
|
||||
err = cluster.SetUpAuthentication(kubeCluster, currentCluster)
|
||||
if err != nil {
|
||||
return APIURL, caCrt, clientCert, clientKey, err
|
||||
}
|
||||
|
||||
err = kubeCluster.SetUpHosts(authType)
|
||||
err = kubeCluster.SetUpHosts()
|
||||
if err != nil {
|
||||
return APIURL, caCrt, clientCert, clientKey, err
|
||||
}
|
||||
@ -99,12 +93,11 @@ func ClusterUp(clusterFile, authType string) (string, string, string, string, er
|
||||
}
|
||||
|
||||
func clusterUpFromCli(ctx *cli.Context) error {
|
||||
authType := ctx.String("auth-type")
|
||||
clusterFile, err := resolveClusterFile(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to resolve cluster file: %v", err)
|
||||
}
|
||||
_, _, _, _, err = ClusterUp(clusterFile, authType)
|
||||
_, _, _, _, err = ClusterUp(clusterFile)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -2,19 +2,15 @@ package hosts
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/rancher/rke/k8s"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
type Host struct {
|
||||
IP string `yaml:"ip"`
|
||||
AdvertiseAddress string `yaml:"advertise_address"`
|
||||
Role []string `yaml:"role"`
|
||||
Hostname string `yaml:"hostname"`
|
||||
User string `yaml:"user"`
|
||||
DockerSocket string `yaml:"docker_socket"`
|
||||
DClient *client.Client
|
||||
v1.RKEConfigHost
|
||||
DClient *client.Client
|
||||
}
|
||||
|
||||
func ReconcileWorkers(currentWorkers []Host, newWorkers []Host, kubeClient *kubernetes.Clientset) error {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/rancher/rke/hosts"
|
||||
)
|
||||
|
||||
@ -17,10 +18,13 @@ const (
|
||||
func TestPKI(t *testing.T) {
|
||||
cpHosts := []hosts.Host{
|
||||
hosts.Host{
|
||||
IP: "1.1.1.1",
|
||||
AdvertiseAddress: "192.168.1.5",
|
||||
Role: []string{"controlplane"},
|
||||
Hostname: "server1",
|
||||
RKEConfigHost: v1.RKEConfigHost{
|
||||
IP: "1.1.1.1",
|
||||
AdvertiseAddress: "192.168.1.5",
|
||||
Role: []string{"controlplane"},
|
||||
Hostname: "server1",
|
||||
},
|
||||
DClient: nil,
|
||||
},
|
||||
}
|
||||
certificateMap, err := StartCertificatesGeneration(cpHosts, cpHosts, FakeClusterDomain, net.ParseIP(FakeKubernetesServiceIP))
|
||||
|
@ -2,10 +2,11 @@ package services
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/rancher/rke/hosts"
|
||||
)
|
||||
|
||||
func RunControlPlane(controlHosts []hosts.Host, etcdHosts []hosts.Host, controlServices Services) error {
|
||||
func RunControlPlane(controlHosts []hosts.Host, etcdHosts []hosts.Host, controlServices v1.RKEConfigServices) error {
|
||||
logrus.Infof("[%s] Building up Controller Plane..", ControlRole)
|
||||
for _, host := range controlHosts {
|
||||
// run kubeapi
|
||||
|
@ -2,13 +2,14 @@ package services
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/rancher/rke/docker"
|
||||
"github.com/rancher/rke/hosts"
|
||||
)
|
||||
|
||||
func RunEtcdPlane(etcdHosts []hosts.Host, etcdService Etcd) error {
|
||||
func RunEtcdPlane(etcdHosts []hosts.Host, etcdService v1.ETCDService) error {
|
||||
logrus.Infof("[%s] Building up Etcd Plane..", ETCDRole)
|
||||
for _, host := range etcdHosts {
|
||||
imageCfg, hostCfg := buildEtcdConfig(host, etcdService)
|
||||
@ -21,7 +22,7 @@ func RunEtcdPlane(etcdHosts []hosts.Host, etcdService Etcd) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildEtcdConfig(host hosts.Host, etcdService Etcd) (*container.Config, *container.HostConfig) {
|
||||
func buildEtcdConfig(host hosts.Host, etcdService v1.ETCDService) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: etcdService.Image,
|
||||
Cmd: []string{"/usr/local/bin/etcd",
|
||||
|
@ -1,6 +1,7 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/rancher/rke/docker"
|
||||
@ -8,13 +9,13 @@ import (
|
||||
"github.com/rancher/rke/pki"
|
||||
)
|
||||
|
||||
func runKubeAPI(host hosts.Host, etcdHosts []hosts.Host, kubeAPIService KubeAPI) error {
|
||||
func runKubeAPI(host hosts.Host, etcdHosts []hosts.Host, kubeAPIService v1.KubeAPIService) error {
|
||||
etcdConnString := getEtcdConnString(etcdHosts)
|
||||
imageCfg, hostCfg := buildKubeAPIConfig(host, kubeAPIService, etcdConnString)
|
||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Hostname, ControlRole)
|
||||
}
|
||||
|
||||
func buildKubeAPIConfig(host hosts.Host, kubeAPIService KubeAPI, etcdConnString string) (*container.Config, *container.HostConfig) {
|
||||
func buildKubeAPIConfig(host hosts.Host, kubeAPIService v1.KubeAPIService, etcdConnString string) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: kubeAPIService.Image,
|
||||
Cmd: []string{"/hyperkube",
|
||||
|
@ -1,18 +1,19 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/rancher/rke/docker"
|
||||
"github.com/rancher/rke/hosts"
|
||||
"github.com/rancher/rke/pki"
|
||||
)
|
||||
|
||||
func runKubeController(host hosts.Host, kubeControllerService KubeController) error {
|
||||
func runKubeController(host hosts.Host, kubeControllerService v1.KubeControllerService) error {
|
||||
imageCfg, hostCfg := buildKubeControllerConfig(kubeControllerService)
|
||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeControllerContainerName, host.Hostname, ControlRole)
|
||||
}
|
||||
|
||||
func buildKubeControllerConfig(kubeControllerService KubeController) (*container.Config, *container.HostConfig) {
|
||||
func buildKubeControllerConfig(kubeControllerService v1.KubeControllerService) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: kubeControllerService.Image,
|
||||
Cmd: []string{"/hyperkube",
|
||||
|
@ -1,6 +1,7 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/rancher/rke/docker"
|
||||
@ -8,12 +9,12 @@ import (
|
||||
"github.com/rancher/rke/pki"
|
||||
)
|
||||
|
||||
func runKubelet(host hosts.Host, kubeletService Kubelet, isMaster bool) error {
|
||||
func runKubelet(host hosts.Host, kubeletService v1.KubeletService, isMaster bool) error {
|
||||
imageCfg, hostCfg := buildKubeletConfig(host, kubeletService, isMaster)
|
||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeletContainerName, host.Hostname, WorkerRole)
|
||||
}
|
||||
|
||||
func buildKubeletConfig(host hosts.Host, kubeletService Kubelet, isMaster bool) (*container.Config, *container.HostConfig) {
|
||||
func buildKubeletConfig(host hosts.Host, kubeletService v1.KubeletService, isMaster bool) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: kubeletService.Image,
|
||||
Cmd: []string{"/hyperkube",
|
||||
|
@ -1,18 +1,19 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/rancher/rke/docker"
|
||||
"github.com/rancher/rke/hosts"
|
||||
"github.com/rancher/rke/pki"
|
||||
)
|
||||
|
||||
func runKubeproxy(host hosts.Host, kubeproxyService Kubeproxy) error {
|
||||
func runKubeproxy(host hosts.Host, kubeproxyService v1.KubeproxyService) error {
|
||||
imageCfg, hostCfg := buildKubeproxyConfig(host, kubeproxyService)
|
||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeproxyContainerName, host.Hostname, WorkerRole)
|
||||
}
|
||||
|
||||
func buildKubeproxyConfig(host hosts.Host, kubeproxyService Kubeproxy) (*container.Config, *container.HostConfig) {
|
||||
func buildKubeproxyConfig(host hosts.Host, kubeproxyService v1.KubeproxyService) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: kubeproxyService.Image,
|
||||
Cmd: []string{"/hyperkube",
|
||||
|
@ -1,18 +1,19 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/rancher/rke/docker"
|
||||
"github.com/rancher/rke/hosts"
|
||||
"github.com/rancher/rke/pki"
|
||||
)
|
||||
|
||||
func runScheduler(host hosts.Host, schedulerService Scheduler) error {
|
||||
func runScheduler(host hosts.Host, schedulerService v1.SchedulerService) error {
|
||||
imageCfg, hostCfg := buildSchedulerConfig(host, schedulerService)
|
||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, SchedulerContainerName, host.Hostname, ControlRole)
|
||||
}
|
||||
|
||||
func buildSchedulerConfig(host hosts.Host, schedulerService Scheduler) (*container.Config, *container.HostConfig) {
|
||||
func buildSchedulerConfig(host hosts.Host, schedulerService v1.SchedulerService) (*container.Config, *container.HostConfig) {
|
||||
imageCfg := &container.Config{
|
||||
Image: schedulerService.Image,
|
||||
Cmd: []string{"/hyperkube",
|
||||
|
@ -1,40 +0,0 @@
|
||||
package services
|
||||
|
||||
type Services struct {
|
||||
Etcd Etcd `yaml:"etcd"`
|
||||
KubeAPI KubeAPI `yaml:"kube-api"`
|
||||
KubeController KubeController `yaml:"kube-controller"`
|
||||
Scheduler Scheduler `yaml:"scheduler"`
|
||||
Kubelet Kubelet `yaml:"kubelet"`
|
||||
Kubeproxy Kubeproxy `yaml:"kubeproxy"`
|
||||
}
|
||||
|
||||
type Etcd struct {
|
||||
Image string `yaml:"image"`
|
||||
}
|
||||
|
||||
type KubeAPI struct {
|
||||
Image string `yaml:"image"`
|
||||
ServiceClusterIPRange string `yaml:"service_cluster_ip_range"`
|
||||
}
|
||||
|
||||
type KubeController struct {
|
||||
Image string `yaml:"image"`
|
||||
ClusterCIDR string `yaml:"cluster_cidr"`
|
||||
ServiceClusterIPRange string `yaml:"service_cluster_ip_range"`
|
||||
}
|
||||
|
||||
type Kubelet struct {
|
||||
Image string `yaml:"image"`
|
||||
ClusterDomain string `yaml:"cluster_domain"`
|
||||
InfraContainerImage string `yaml:"infra_container_image"`
|
||||
ClusterDNSServer string `yaml:"cluster_dns_server"`
|
||||
}
|
||||
|
||||
type Kubeproxy struct {
|
||||
Image string `yaml:"image"`
|
||||
}
|
||||
|
||||
type Scheduler struct {
|
||||
Image string `yaml:"image"`
|
||||
}
|
@ -2,10 +2,11 @@ package services
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/alena1108/cluster-controller/client/v1"
|
||||
"github.com/rancher/rke/hosts"
|
||||
)
|
||||
|
||||
func RunWorkerPlane(controlHosts []hosts.Host, workerHosts []hosts.Host, workerServices Services) error {
|
||||
func RunWorkerPlane(controlHosts []hosts.Host, workerHosts []hosts.Host, workerServices v1.RKEConfigServices) error {
|
||||
logrus.Infof("[%s] Building up Worker Plane..", WorkerRole)
|
||||
for _, host := range controlHosts {
|
||||
// only one master for now
|
||||
|
31
vendor.conf
31
vendor.conf
@ -1,18 +1,19 @@
|
||||
# package
|
||||
github.com/rancher/rke
|
||||
|
||||
github.com/Sirupsen/logrus v0.10.0
|
||||
github.com/urfave/cli v1.18.0
|
||||
golang.org/x/crypto 2509b142fb2b797aa7587dad548f113b2c0f20ce
|
||||
gopkg.in/yaml.v2 eb3733d160e74a9c7e442f435eb3bea458e1d19f
|
||||
github.com/docker/docker ecf4125b85e0faa57d2739348e0d453c1d24d10c
|
||||
github.com/docker/distribution 3800056b8832cf6075e78b282ac010131d8687bc
|
||||
github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
|
||||
github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
|
||||
golang.org/x/net 186fd3fc8194a5e9980a82230d69c1ff7134229f
|
||||
github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf
|
||||
github.com/gogo/protobuf 117892bf1866fbaa2318c03e50e40564c8845457
|
||||
github.com/opencontainers/image-spec 7c889fafd04a893f5c5f50b7ab9963d5d64e5242
|
||||
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
|
||||
k8s.io/client-go v4.0.0 transitive=true
|
||||
gopkg.in/check.v1 11d3bc7aa68e238947792f30573146a3231fc0f1
|
||||
github.com/Sirupsen/logrus v0.10.0
|
||||
github.com/urfave/cli v1.18.0
|
||||
golang.org/x/crypto 2509b142fb2b797aa7587dad548f113b2c0f20ce
|
||||
gopkg.in/yaml.v2 eb3733d160e74a9c7e442f435eb3bea458e1d19f
|
||||
github.com/docker/docker ecf4125b85e0faa57d2739348e0d453c1d24d10c
|
||||
github.com/docker/distribution 3800056b8832cf6075e78b282ac010131d8687bc
|
||||
github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
|
||||
github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
|
||||
golang.org/x/net 186fd3fc8194a5e9980a82230d69c1ff7134229f
|
||||
github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf
|
||||
github.com/gogo/protobuf 117892bf1866fbaa2318c03e50e40564c8845457
|
||||
github.com/opencontainers/image-spec 7c889fafd04a893f5c5f50b7ab9963d5d64e5242
|
||||
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
|
||||
k8s.io/client-go v4.0.0 transitive=true
|
||||
gopkg.in/check.v1 11d3bc7aa68e238947792f30573146a3231fc0f1
|
||||
github.com/alena1108/cluster-controller 85168a7fe249bf97f703afe53f03d3654cc70350
|
||||
|
4
vendor/github.com/alena1108/cluster-controller/.dockerignore
generated
vendored
Normal file
4
vendor/github.com/alena1108/cluster-controller/.dockerignore
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
./bin
|
||||
./.dapper
|
||||
./dist
|
||||
./.trash-cache
|
9
vendor/github.com/alena1108/cluster-controller/.drone.yml
generated
vendored
Normal file
9
vendor/github.com/alena1108/cluster-controller/.drone.yml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
pipeline:
|
||||
build:
|
||||
privileged: true
|
||||
image: rancher/dapper:1.11.2
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- dapper ci
|
6
vendor/github.com/alena1108/cluster-controller/.gitignore
generated
vendored
Normal file
6
vendor/github.com/alena1108/cluster-controller/.gitignore
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/.dapper
|
||||
/bin
|
||||
/dist
|
||||
*.swp
|
||||
/.trash-cache
|
||||
cluster-controller
|
31
vendor/github.com/alena1108/cluster-controller/Dockerfile.dapper
generated
vendored
Normal file
31
vendor/github.com/alena1108/cluster-controller/Dockerfile.dapper
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
FROM ubuntu:16.04
|
||||
# FROM arm=armhf/ubuntu:16.04
|
||||
|
||||
ARG DAPPER_HOST_ARCH
|
||||
ENV HOST_ARCH=${DAPPER_HOST_ARCH} ARCH=${DAPPER_HOST_ARCH}
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y gcc ca-certificates git wget curl vim less file && \
|
||||
rm -f /bin/sh && ln -s /bin/bash /bin/sh
|
||||
|
||||
ENV GOLANG_ARCH_amd64=amd64 GOLANG_ARCH_arm=armv6l GOLANG_ARCH=GOLANG_ARCH_${ARCH} \
|
||||
GOPATH=/go PATH=/go/bin:/usr/local/go/bin:${PATH} SHELL=/bin/bash
|
||||
|
||||
RUN wget -O - https://storage.googleapis.com/golang/go1.8.3.linux-${!GOLANG_ARCH}.tar.gz | tar -xzf - -C /usr/local && \
|
||||
go get github.com/rancher/trash && go get github.com/golang/lint/golint
|
||||
|
||||
ENV DOCKER_URL_amd64=https://get.docker.com/builds/Linux/x86_64/docker-1.10.3 \
|
||||
DOCKER_URL_arm=https://github.com/rancher/docker/releases/download/v1.10.3-ros1/docker-1.10.3_arm \
|
||||
DOCKER_URL=DOCKER_URL_${ARCH}
|
||||
|
||||
RUN wget -O - ${!DOCKER_URL} > /usr/bin/docker && chmod +x /usr/bin/docker
|
||||
|
||||
ENV DAPPER_SOURCE /go/src/github.com/rancher/cluster-controller/
|
||||
ENV DAPPER_OUTPUT ./bin ./dist
|
||||
ENV DAPPER_DOCKER_SOCKET true
|
||||
ENV TRASH_CACHE ${DAPPER_SOURCE}/.trash-cache
|
||||
ENV HOME ${DAPPER_SOURCE}
|
||||
WORKDIR ${DAPPER_SOURCE}
|
||||
|
||||
ENTRYPOINT ["./scripts/entry"]
|
||||
CMD ["ci"]
|
177
vendor/github.com/alena1108/cluster-controller/LICENSE
generated
vendored
Normal file
177
vendor/github.com/alena1108/cluster-controller/LICENSE
generated
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
23
vendor/github.com/alena1108/cluster-controller/Makefile
generated
vendored
Normal file
23
vendor/github.com/alena1108/cluster-controller/Makefile
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
TARGETS := $(shell ls scripts)
|
||||
|
||||
.dapper:
|
||||
@echo Downloading dapper
|
||||
@curl -sL https://releases.rancher.com/dapper/latest/dapper-`uname -s`-`uname -m` > .dapper.tmp
|
||||
@@chmod +x .dapper.tmp
|
||||
@./.dapper.tmp -v
|
||||
@mv .dapper.tmp .dapper
|
||||
|
||||
$(TARGETS): .dapper
|
||||
./.dapper $@
|
||||
|
||||
trash: .dapper
|
||||
./.dapper -m bind trash
|
||||
|
||||
trash-keep: .dapper
|
||||
./.dapper -m bind trash -k
|
||||
|
||||
deps: trash
|
||||
|
||||
.DEFAULT_GOAL := ci
|
||||
|
||||
.PHONY: $(TARGETS)
|
28
vendor/github.com/alena1108/cluster-controller/README.md
generated
vendored
Normal file
28
vendor/github.com/alena1108/cluster-controller/README.md
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
cluster-controller
|
||||
========
|
||||
|
||||
A microservice that does micro things.
|
||||
|
||||
## Building
|
||||
|
||||
`make`
|
||||
|
||||
|
||||
## Running
|
||||
|
||||
`./bin/cluster-controller`
|
||||
|
||||
## License
|
||||
Copyright (c) 2014-2017 [Rancher Labs, Inc.](http://rancher.com)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
63
vendor/github.com/alena1108/cluster-controller/client/v1/client.go
generated
vendored
Normal file
63
vendor/github.com/alena1108/cluster-controller/client/v1/client.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
Group = "rancher.com"
|
||||
)
|
||||
|
||||
var Version = "v1"
|
||||
|
||||
type ClustersManagerV1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ClustersGetter
|
||||
}
|
||||
|
||||
type ClustersManagerV1Client struct {
|
||||
restClient rest.Interface
|
||||
dynamicClient *dynamic.Client
|
||||
}
|
||||
|
||||
func (c *ClustersManagerV1Client) Clusters() ClusterInterface {
|
||||
return newClusters(c.restClient, c.dynamicClient)
|
||||
}
|
||||
|
||||
func (c *ClustersManagerV1Client) ClusterNodes() ClusterNodeInterface {
|
||||
return newClusterNodes(c.restClient, c.dynamicClient)
|
||||
}
|
||||
|
||||
func (c *ClustersManagerV1Client) RESTClient() rest.Interface {
|
||||
return c.restClient
|
||||
}
|
||||
|
||||
func NewForConfig(c *rest.Config) (*ClustersManagerV1Client, error) {
|
||||
config := *c
|
||||
SetConfigDefaults(&config)
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dynamicClient, err := dynamic.NewClient(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ClustersManagerV1Client{client, dynamicClient}, nil
|
||||
}
|
||||
|
||||
func SetConfigDefaults(config *rest.Config) {
|
||||
config.GroupVersion = &schema.GroupVersion{
|
||||
Group: Group,
|
||||
Version: Version,
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
return
|
||||
}
|
184
vendor/github.com/alena1108/cluster-controller/client/v1/cluster.go
generated
vendored
Normal file
184
vendor/github.com/alena1108/cluster-controller/client/v1/cluster.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
ClustersKind = "Cluster"
|
||||
ClustersName = "clusters"
|
||||
ClustersSingularName = "cluster"
|
||||
)
|
||||
|
||||
type ClustersGetter interface {
|
||||
Clusters(namespace string) ClusterInterface
|
||||
}
|
||||
|
||||
var _ ClusterInterface = &clusters{}
|
||||
|
||||
type ClusterInterface interface {
|
||||
Create(*Cluster) (*Cluster, error)
|
||||
Get(name string, opts metav1.GetOptions) (*Cluster, error)
|
||||
Update(*Cluster) (*Cluster, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (runtime.Object, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
DeleteCollection(dopts *metav1.DeleteOptions, lopts metav1.ListOptions) error
|
||||
}
|
||||
|
||||
type clusters struct {
|
||||
restClient rest.Interface
|
||||
client *dynamic.ResourceClient
|
||||
ns string
|
||||
}
|
||||
|
||||
func newClusters(r rest.Interface, c *dynamic.Client) *clusters {
|
||||
return &clusters{
|
||||
r,
|
||||
c.Resource(
|
||||
&metav1.APIResource{
|
||||
Kind: ClustersKind,
|
||||
Name: ClustersName,
|
||||
Namespaced: false,
|
||||
},
|
||||
"",
|
||||
),
|
||||
"",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *clusters) Create(o *Cluster) (*Cluster, error) {
|
||||
up, err := UnstructuredFromCluster(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
up, err = p.client.Create(up)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ClusterFromUnstructured(up)
|
||||
}
|
||||
|
||||
func (p *clusters) Get(name string, opts metav1.GetOptions) (*Cluster, error) {
|
||||
obj, err := p.client.Get(name, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ClusterFromUnstructured(obj)
|
||||
}
|
||||
|
||||
func (p *clusters) Update(o *Cluster) (*Cluster, error) {
|
||||
up, err := UnstructuredFromCluster(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curp, err := p.Get(o.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get current version for update")
|
||||
}
|
||||
up.SetResourceVersion(curp.ObjectMeta.ResourceVersion)
|
||||
|
||||
up, err = p.client.Update(up)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ClusterFromUnstructured(up)
|
||||
}
|
||||
|
||||
func (p *clusters) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return p.client.Delete(name, options)
|
||||
}
|
||||
|
||||
func (p *clusters) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
req := p.restClient.Get().
|
||||
Namespace(p.ns).
|
||||
Resource(ClustersName).
|
||||
FieldsSelectorParam(nil)
|
||||
|
||||
b, err := req.DoRaw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var prom ClusterList
|
||||
return &prom, json.Unmarshal(b, &prom)
|
||||
}
|
||||
|
||||
func (p *clusters) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
r, err := p.restClient.Get().
|
||||
Prefix("watch").
|
||||
Namespace(p.ns).
|
||||
Resource(ClustersName).
|
||||
FieldsSelectorParam(nil).
|
||||
Stream()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return watch.NewStreamWatcher(&clusterDecoder{
|
||||
dec: json.NewDecoder(r),
|
||||
close: r.Close,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *clusters) DeleteCollection(dopts *metav1.DeleteOptions, lopts metav1.ListOptions) error {
|
||||
return p.client.DeleteCollection(dopts, lopts)
|
||||
}
|
||||
|
||||
func ClusterFromUnstructured(r *unstructured.Unstructured) (*Cluster, error) {
|
||||
b, err := json.Marshal(r.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var p Cluster
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.TypeMeta.Kind = ClustersKind
|
||||
p.TypeMeta.APIVersion = Group + "/" + Version
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
func UnstructuredFromCluster(p *Cluster) (*unstructured.Unstructured, error) {
|
||||
p.TypeMeta.Kind = ClustersKind
|
||||
p.TypeMeta.APIVersion = Group + "/" + Version
|
||||
b, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var r unstructured.Unstructured
|
||||
if err := json.Unmarshal(b, &r.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
type clusterDecoder struct {
|
||||
dec *json.Decoder
|
||||
close func() error
|
||||
}
|
||||
|
||||
func (d *clusterDecoder) Close() {
|
||||
d.close()
|
||||
}
|
||||
|
||||
func (d *clusterDecoder) Decode() (action watch.EventType, object runtime.Object, err error) {
|
||||
var e struct {
|
||||
Type watch.EventType
|
||||
Object Cluster
|
||||
}
|
||||
if err := d.dec.Decode(&e); err != nil {
|
||||
return watch.Error, nil, err
|
||||
}
|
||||
return e.Type, &e.Object, nil
|
||||
}
|
184
vendor/github.com/alena1108/cluster-controller/client/v1/clusternode.go
generated
vendored
Normal file
184
vendor/github.com/alena1108/cluster-controller/client/v1/clusternode.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
ClusterNodesKind = "ClusterNode"
|
||||
ClusterNodesName = "clusternodes"
|
||||
ClusterNodesSingularName = "clusternode"
|
||||
)
|
||||
|
||||
type ClusterNodesGetter interface {
|
||||
ClusterNodes(namespace string) ClusterNodeInterface
|
||||
}
|
||||
|
||||
var _ ClusterNodeInterface = &clusternodes{}
|
||||
|
||||
type ClusterNodeInterface interface {
|
||||
Create(*ClusterNode) (*ClusterNode, error)
|
||||
Get(name string, opts metav1.GetOptions) (*ClusterNode, error)
|
||||
Update(*ClusterNode) (*ClusterNode, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (runtime.Object, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
DeleteCollection(dopts *metav1.DeleteOptions, lopts metav1.ListOptions) error
|
||||
}
|
||||
|
||||
type clusternodes struct {
|
||||
restClient rest.Interface
|
||||
client *dynamic.ResourceClient
|
||||
ns string
|
||||
}
|
||||
|
||||
func newClusterNodes(r rest.Interface, c *dynamic.Client) *clusternodes {
|
||||
return &clusternodes{
|
||||
r,
|
||||
c.Resource(
|
||||
&metav1.APIResource{
|
||||
Kind: ClusterNodesKind,
|
||||
Name: ClusterNodesName,
|
||||
Namespaced: false,
|
||||
},
|
||||
"",
|
||||
),
|
||||
"",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *clusternodes) Create(o *ClusterNode) (*ClusterNode, error) {
|
||||
up, err := UnstructuredFromClusterNode(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
up, err = p.client.Create(up)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ClusterNodeFromUnstructured(up)
|
||||
}
|
||||
|
||||
func (p *clusternodes) Get(name string, opts metav1.GetOptions) (*ClusterNode, error) {
|
||||
obj, err := p.client.Get(name, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ClusterNodeFromUnstructured(obj)
|
||||
}
|
||||
|
||||
func (p *clusternodes) Update(o *ClusterNode) (*ClusterNode, error) {
|
||||
up, err := UnstructuredFromClusterNode(o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
curp, err := p.Get(o.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get current version for update")
|
||||
}
|
||||
up.SetResourceVersion(curp.ObjectMeta.ResourceVersion)
|
||||
|
||||
up, err = p.client.Update(up)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ClusterNodeFromUnstructured(up)
|
||||
}
|
||||
|
||||
func (p *clusternodes) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return p.client.Delete(name, options)
|
||||
}
|
||||
|
||||
func (p *clusternodes) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
req := p.restClient.Get().
|
||||
Namespace(p.ns).
|
||||
Resource(ClusterNodesName).
|
||||
FieldsSelectorParam(nil)
|
||||
|
||||
b, err := req.DoRaw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var prom ClusterNodeList
|
||||
return &prom, json.Unmarshal(b, &prom)
|
||||
}
|
||||
|
||||
func (p *clusternodes) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
r, err := p.restClient.Get().
|
||||
Prefix("watch").
|
||||
Namespace(p.ns).
|
||||
Resource(ClusterNodesName).
|
||||
FieldsSelectorParam(nil).
|
||||
Stream()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return watch.NewStreamWatcher(&clusterDecoder{
|
||||
dec: json.NewDecoder(r),
|
||||
close: r.Close,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *clusternodes) DeleteCollection(dopts *metav1.DeleteOptions, lopts metav1.ListOptions) error {
|
||||
return p.client.DeleteCollection(dopts, lopts)
|
||||
}
|
||||
|
||||
func ClusterNodeFromUnstructured(r *unstructured.Unstructured) (*ClusterNode, error) {
|
||||
b, err := json.Marshal(r.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var p ClusterNode
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.TypeMeta.Kind = ClusterNodesKind
|
||||
p.TypeMeta.APIVersion = Group + "/" + Version
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
func UnstructuredFromClusterNode(p *ClusterNode) (*unstructured.Unstructured, error) {
|
||||
p.TypeMeta.Kind = ClusterNodesKind
|
||||
p.TypeMeta.APIVersion = Group + "/" + Version
|
||||
b, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var r unstructured.Unstructured
|
||||
if err := json.Unmarshal(b, &r.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
type clusterNodeDecoder struct {
|
||||
dec *json.Decoder
|
||||
close func() error
|
||||
}
|
||||
|
||||
func (d *clusterNodeDecoder) Close() {
|
||||
d.close()
|
||||
}
|
||||
|
||||
func (d *clusterNodeDecoder) Decode() (action watch.EventType, object runtime.Object, err error) {
|
||||
var e struct {
|
||||
Type watch.EventType
|
||||
Object ClusterNode
|
||||
}
|
||||
if err := d.dec.Decode(&e); err != nil {
|
||||
return watch.Error, nil, err
|
||||
}
|
||||
return e.Type, &e.Object, nil
|
||||
}
|
216
vendor/github.com/alena1108/cluster-controller/client/v1/types.go
generated
vendored
Normal file
216
vendor/github.com/alena1108/cluster-controller/client/v1/types.go
generated
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
type ClusterConditionType string
|
||||
|
||||
const (
|
||||
// ClusterConditionReady Cluster ready to serve API (healthy when true, unehalthy when false)
|
||||
ClusterConditionReady = "Ready"
|
||||
// ClusterConditionProvisioned Cluster is provisioned
|
||||
ClusterConditionProvisioned = "Provisioned"
|
||||
// ClusterConditionUpdating Cluster is being updating (upgrading, scaling up)
|
||||
ClusterConditionUpdating = "Updating"
|
||||
// More conditions can be added if unredlying controllers request it
|
||||
)
|
||||
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object’s metadata. More info:
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
// Specification of the desired behavior of the the cluster. More info:
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
|
||||
Spec ClusterSpec `json:"spec"`
|
||||
// Most recent observed status of the cluster. More info:
|
||||
// https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status
|
||||
Status *ClusterStatus `json:"status"`
|
||||
}
|
||||
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
// List of Clusters
|
||||
Items []*Cluster `json:"items"`
|
||||
}
|
||||
|
||||
type ClusterSpec struct {
|
||||
GKEConfig *GKEConfig
|
||||
AKSConfig *AKSConfig
|
||||
RKEConfig *RKEConfig
|
||||
}
|
||||
|
||||
type ClusterStatus struct {
|
||||
//Conditions represent the latest available observations of an object's current state:
|
||||
//More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties
|
||||
Conditions []ClusterCondition `json:"conditions,omitempty"`
|
||||
//Component statuses will represent cluster's components (etcd/controller/scheduler) health
|
||||
// https://kubernetes.io/docs/api-reference/v1.8/#componentstatus-v1-core
|
||||
ComponentStatuses v1.ComponentStatusList
|
||||
APIEndpoint string
|
||||
ServiceAccountToken string
|
||||
CACert string
|
||||
}
|
||||
|
||||
type ClusterCondition struct {
|
||||
// Type of cluster condition.
|
||||
Type ClusterConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status v1.ConditionStatus `json:"status"`
|
||||
// The last time this condition was updated.
|
||||
LastUpdateTime string `json:"lastUpdateTime,omitempty"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
LastTransitionTime string `json:"lastTransitionTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
}
|
||||
|
||||
type GKEConfig struct {
|
||||
// ProjectID is the ID of your project to use when creating a cluster
|
||||
ProjectID string
|
||||
// The zone to launch the cluster
|
||||
Zone string
|
||||
// The IP address range of the container pods
|
||||
ClusterIpv4Cidr string
|
||||
// An optional description of this cluster
|
||||
Description string
|
||||
// The number of nodes to create in this cluster
|
||||
InitialNodeCount int64
|
||||
// Size of the disk attached to each node
|
||||
DiskSizeGb int64
|
||||
// The name of a Google Compute Engine
|
||||
MachineType string
|
||||
// the initial kubernetes version
|
||||
InitialClusterVersion string
|
||||
// The map of Kubernetes labels (key/value pairs) to be applied
|
||||
// to each node.
|
||||
Labels map[string]string
|
||||
// The path to the credential file(key.json)
|
||||
CredentialPath string
|
||||
// Enable alpha feature
|
||||
EnableAlphaFeature bool
|
||||
// NodePool id
|
||||
NodePoolID string
|
||||
|
||||
// Update Config
|
||||
UpdateConfig gkeUpdateConfig
|
||||
}
|
||||
|
||||
type gkeUpdateConfig struct {
|
||||
// the number of node
|
||||
NodeCount int64
|
||||
// Master kubernetes version
|
||||
MasterVersion string
|
||||
// Node kubernetes version
|
||||
NodeVersion string
|
||||
}
|
||||
|
||||
type AKSConfig struct {
|
||||
//TBD
|
||||
}
|
||||
|
||||
type RKEConfig struct {
|
||||
// Kubernetes nodes
|
||||
Hosts []RKEConfigHost `yaml:"hosts"`
|
||||
// Kubernetes components
|
||||
Services RKEConfigServices `yaml:"services"`
|
||||
// Network plugin used in the kubernetes cluster (flannel, calico)
|
||||
NetworkPlugin string `yaml:"network_plugin"`
|
||||
// Authentication type used in the cluster (default: x509)
|
||||
AuthType string `yaml:"auth_type"`
|
||||
}
|
||||
|
||||
type RKEConfigHost struct {
|
||||
// SSH IP address of the host
|
||||
IP string `yaml:"ip"`
|
||||
// Advertised address that will be used for components communication
|
||||
AdvertiseAddress string `yaml:"advertise_address"`
|
||||
// Host role in kubernetes cluster (controlplane, worker, or etcd)
|
||||
Role []string `yaml:"role"`
|
||||
// Hostname of the host
|
||||
Hostname string `yaml:"hostname"`
|
||||
// SSH usesr that will be used by RKE
|
||||
User string `yaml:"user"`
|
||||
// Docker socket on the host that will be used in tunneling
|
||||
DockerSocket string `yaml:"docker_socket"`
|
||||
}
|
||||
|
||||
type RKEConfigServices struct {
|
||||
// Etcd Service
|
||||
Etcd ETCDService `yaml:"etcd"`
|
||||
// KubeAPI Service
|
||||
KubeAPI KubeAPIService `yaml:"kube-api"`
|
||||
// KubeController Service
|
||||
KubeController KubeControllerService `yaml:"kube-controller"`
|
||||
// Scheduler Service
|
||||
Scheduler SchedulerService `yaml:"scheduler"`
|
||||
// Kubelet Service
|
||||
Kubelet KubeletService `yaml:"kubelet"`
|
||||
// KubeProxy Service
|
||||
Kubeproxy KubeproxyService `yaml:"kubeproxy"`
|
||||
}
|
||||
|
||||
type ETCDService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
}
|
||||
|
||||
type KubeAPIService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
// Virtual IP range that will be used by Kubernetes services
|
||||
ServiceClusterIPRange string `yaml:"service_cluster_ip_range"`
|
||||
}
|
||||
|
||||
type KubeControllerService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
// CIDR Range for Pods in cluster
|
||||
ClusterCIDR string `yaml:"cluster_cidr"`
|
||||
// Virtual IP range that will be used by Kubernetes services
|
||||
ServiceClusterIPRange string `yaml:"service_cluster_ip_range"`
|
||||
}
|
||||
|
||||
type KubeletService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
// Domain of the cluster (default: "cluster.local")
|
||||
ClusterDomain string `yaml:"cluster_domain"`
|
||||
// The image whose network/ipc namespaces containers in each pod will use
|
||||
InfraContainerImage string `yaml:"infra_container_image"`
|
||||
// Cluster DNS service ip
|
||||
ClusterDNSServer string `yaml:"cluster_dns_server"`
|
||||
}
|
||||
|
||||
type KubeproxyService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
}
|
||||
|
||||
type SchedulerService struct {
|
||||
// Base service properties
|
||||
baseService `yaml:",inline"`
|
||||
}
|
||||
|
||||
type baseService struct {
|
||||
// Docker image of the service
|
||||
Image string `yaml:"image"`
|
||||
}
|
||||
|
||||
type ClusterNode struct {
|
||||
v1.Node
|
||||
}
|
||||
|
||||
type ClusterNodeList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
// List of Clusters
|
||||
Items []*Cluster `json:"items"`
|
||||
}
|
10
vendor/github.com/alena1108/cluster-controller/vendor.conf
generated
vendored
Normal file
10
vendor/github.com/alena1108/cluster-controller/vendor.conf
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# package
|
||||
github.com/rancher/cluster-controller
|
||||
|
||||
github.com/Sirupsen/logrus v0.10.0
|
||||
github.com/urfave/cli v1.18.0
|
||||
k8s.io/client-go v4.0.0 transitive=true
|
||||
github.com/pkg/errors v0.8.0
|
||||
github.com/urfave/cli v1.19.1
|
||||
golang.org/x/sync/errgroup 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
||||
|
55
vendor/k8s.io/client-go/dynamic/BUILD
generated
vendored
Normal file
55
vendor/k8s.io/client-go/dynamic/BUILD
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"client_test.go",
|
||||
"dynamic_util_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"client_pool.go",
|
||||
"dynamic_util.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion/queryparams:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
],
|
||||
)
|
306
vendor/k8s.io/client-go/dynamic/client.go
generated
vendored
Normal file
306
vendor/k8s.io/client-go/dynamic/client.go
generated
vendored
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package dynamic provides a client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/conversion/queryparams"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
// Client is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group.
|
||||
type Client struct {
|
||||
cl *restclient.RESTClient
|
||||
parameterCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
// NewClient returns a new client based on the passed in config. The
|
||||
// codec is ignored, as the dynamic client uses it's own codec.
|
||||
func NewClient(conf *restclient.Config) (*Client, error) {
|
||||
// avoid changing the original config
|
||||
confCopy := *conf
|
||||
conf = &confCopy
|
||||
|
||||
contentConfig := ContentConfig()
|
||||
contentConfig.GroupVersion = conf.GroupVersion
|
||||
if conf.NegotiatedSerializer != nil {
|
||||
contentConfig.NegotiatedSerializer = conf.NegotiatedSerializer
|
||||
}
|
||||
conf.ContentConfig = contentConfig
|
||||
|
||||
if conf.APIPath == "" {
|
||||
conf.APIPath = "/api"
|
||||
}
|
||||
|
||||
if len(conf.UserAgent) == 0 {
|
||||
conf.UserAgent = restclient.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
cl, err := restclient.RESTClientFor(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{cl: cl}, nil
|
||||
}
|
||||
|
||||
// GetRateLimiter returns rate limier.
|
||||
func (c *Client) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
return c.cl.GetRateLimiter()
|
||||
}
|
||||
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceClient inherits the parameter codec of c.
|
||||
func (c *Client) Resource(resource *metav1.APIResource, namespace string) *ResourceClient {
|
||||
return &ResourceClient{
|
||||
cl: c.cl,
|
||||
resource: resource,
|
||||
ns: namespace,
|
||||
parameterCodec: c.parameterCodec,
|
||||
}
|
||||
}
|
||||
|
||||
// ParameterCodec returns a client with the provided parameter codec.
|
||||
func (c *Client) ParameterCodec(parameterCodec runtime.ParameterCodec) *Client {
|
||||
return &Client{
|
||||
cl: c.cl,
|
||||
parameterCodec: parameterCodec,
|
||||
}
|
||||
}
|
||||
|
||||
// ResourceClient is an API interface to a specific resource under a
|
||||
// dynamic client.
|
||||
type ResourceClient struct {
|
||||
cl *restclient.RESTClient
|
||||
resource *metav1.APIResource
|
||||
ns string
|
||||
parameterCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
// List returns a list of objects for this resource.
|
||||
func (rc *ResourceClient) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
return rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Do().
|
||||
Get()
|
||||
}
|
||||
|
||||
// Get gets the resource with the specified name.
|
||||
func (rc *ResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
result := new(unstructured.Unstructured)
|
||||
err := rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Delete deletes the resource with the specified name.
|
||||
func (rc *ResourceClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return rc.cl.Delete().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
Name(name).
|
||||
Body(opts).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (rc *ResourceClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
return rc.cl.Delete().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&listOptions, parameterEncoder).
|
||||
Body(deleteOptions).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Create creates the provided resource.
|
||||
func (rc *ResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
err := rc.cl.Post().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
Body(obj).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Update updates the provided resource.
|
||||
func (rc *ResourceClient) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
if len(obj.GetName()) == 0 {
|
||||
return result, errors.New("object missing name")
|
||||
}
|
||||
err := rc.cl.Put().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
Name(obj.GetName()).
|
||||
Body(obj).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
func (rc *ResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
opts.Watch = true
|
||||
return rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Watch()
|
||||
}
|
||||
|
||||
func (rc *ResourceClient) Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
err := rc.cl.Patch(pt).
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// dynamicCodec is a codec that wraps the standard unstructured codec
|
||||
// with special handling for Status objects.
|
||||
type dynamicCodec struct{}
|
||||
|
||||
func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(data, gvk, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := obj.(*metav1.Status); !ok && strings.ToLower(gvk.Kind) == "status" {
|
||||
obj = &metav1.Status{}
|
||||
err := json.Unmarshal(data, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, gvk, nil
|
||||
}
|
||||
|
||||
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
// ContentConfig returns a restclient.ContentConfig for dynamic types.
|
||||
func ContentConfig() restclient.ContentConfig {
|
||||
var jsonInfo runtime.SerializerInfo
|
||||
// TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need
|
||||
// to talk to a kubernetes server
|
||||
for _, info := range scheme.Codecs.SupportedMediaTypes() {
|
||||
if info.MediaType == runtime.ContentTypeJSON {
|
||||
jsonInfo = info
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
jsonInfo.Serializer = dynamicCodec{}
|
||||
jsonInfo.PrettySerializer = nil
|
||||
return restclient.ContentConfig{
|
||||
AcceptContentTypes: runtime.ContentTypeJSON,
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(jsonInfo),
|
||||
}
|
||||
}
|
||||
|
||||
// paramaterCodec is a codec converts an API object to query
|
||||
// parameters without trying to convert to the target version.
|
||||
type parameterCodec struct{}
|
||||
|
||||
func (parameterCodec) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
|
||||
return queryparams.Convert(obj)
|
||||
}
|
||||
|
||||
func (parameterCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
|
||||
return errors.New("DecodeParameters not implemented on dynamic parameterCodec")
|
||||
}
|
||||
|
||||
var defaultParameterEncoder runtime.ParameterCodec = parameterCodec{}
|
||||
|
||||
type versionedParameterEncoderWithV1Fallback struct{}
|
||||
|
||||
func (versionedParameterEncoderWithV1Fallback) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
|
||||
ret, err := scheme.ParameterCodec.EncodeParameters(obj, to)
|
||||
if err != nil && runtime.IsNotRegisteredError(err) {
|
||||
// fallback to v1
|
||||
return scheme.ParameterCodec.EncodeParameters(obj, v1.SchemeGroupVersion)
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (versionedParameterEncoderWithV1Fallback) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
|
||||
return errors.New("DecodeParameters not implemented on versionedParameterEncoderWithV1Fallback")
|
||||
}
|
||||
|
||||
// VersionedParameterEncoderWithV1Fallback is useful for encoding query
|
||||
// parameters for thirdparty resources. It tries to convert object to the
|
||||
// specified version before converting it to query parameters, and falls back to
|
||||
// converting to v1 if the object is not registered in the specified version.
|
||||
// For the record, currently API server always treats query parameters sent to a
|
||||
// thirdparty resource endpoint as v1.
|
||||
var VersionedParameterEncoderWithV1Fallback runtime.ParameterCodec = versionedParameterEncoderWithV1Fallback{}
|
122
vendor/k8s.io/client-go/dynamic/client_pool.go
generated
vendored
Normal file
122
vendor/k8s.io/client-go/dynamic/client_pool.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// ClientPool manages a pool of dynamic clients.
|
||||
type ClientPool interface {
|
||||
// ClientForGroupVersionKind returns a client configured for the specified groupVersionResource.
|
||||
// Resource may be empty.
|
||||
ClientForGroupVersionResource(resource schema.GroupVersionResource) (*Client, error)
|
||||
// ClientForGroupVersionKind returns a client configured for the specified groupVersionKind.
|
||||
// Kind may be empty.
|
||||
ClientForGroupVersionKind(kind schema.GroupVersionKind) (*Client, error)
|
||||
}
|
||||
|
||||
// APIPathResolverFunc knows how to convert a groupVersion to its API path. The Kind field is
|
||||
// optional.
|
||||
type APIPathResolverFunc func(kind schema.GroupVersionKind) string
|
||||
|
||||
// LegacyAPIPathResolverFunc can resolve paths properly with the legacy API.
|
||||
func LegacyAPIPathResolverFunc(kind schema.GroupVersionKind) string {
|
||||
if len(kind.Group) == 0 {
|
||||
return "/api"
|
||||
}
|
||||
return "/apis"
|
||||
}
|
||||
|
||||
// clientPoolImpl implements ClientPool and caches clients for the resource group versions
|
||||
// is asked to retrieve. This type is thread safe.
|
||||
type clientPoolImpl struct {
|
||||
lock sync.RWMutex
|
||||
config *restclient.Config
|
||||
clients map[schema.GroupVersion]*Client
|
||||
apiPathResolverFunc APIPathResolverFunc
|
||||
mapper meta.RESTMapper
|
||||
}
|
||||
|
||||
// NewClientPool returns a ClientPool from the specified config. It reuses clients for the the same
|
||||
// group version. It is expected this type may be wrapped by specific logic that special cases certain
|
||||
// resources or groups.
|
||||
func NewClientPool(config *restclient.Config, mapper meta.RESTMapper, apiPathResolverFunc APIPathResolverFunc) ClientPool {
|
||||
confCopy := *config
|
||||
|
||||
return &clientPoolImpl{
|
||||
config: &confCopy,
|
||||
clients: map[schema.GroupVersion]*Client{},
|
||||
apiPathResolverFunc: apiPathResolverFunc,
|
||||
mapper: mapper,
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiates a new dynamic client pool with the given config.
|
||||
func NewDynamicClientPool(cfg *restclient.Config) ClientPool {
|
||||
// restMapper is not needed when using LegacyAPIPathResolverFunc
|
||||
emptyMapper := meta.MultiRESTMapper{}
|
||||
return NewClientPool(cfg, emptyMapper, LegacyAPIPathResolverFunc)
|
||||
}
|
||||
|
||||
// ClientForGroupVersionResource uses the provided RESTMapper to identify the appropriate resource. Resource may
|
||||
// be empty. If no matching kind is found the underlying client for that group is still returned.
|
||||
func (c *clientPoolImpl) ClientForGroupVersionResource(resource schema.GroupVersionResource) (*Client, error) {
|
||||
kinds, err := c.mapper.KindsFor(resource)
|
||||
if err != nil {
|
||||
if meta.IsNoMatchError(err) {
|
||||
return c.ClientForGroupVersionKind(schema.GroupVersionKind{Group: resource.Group, Version: resource.Version})
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return c.ClientForGroupVersionKind(kinds[0])
|
||||
}
|
||||
|
||||
// ClientForGroupVersion returns a client for the specified groupVersion, creates one if none exists. Kind
|
||||
// in the GroupVersionKind may be empty.
|
||||
func (c *clientPoolImpl) ClientForGroupVersionKind(kind schema.GroupVersionKind) (*Client, error) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
gv := kind.GroupVersion()
|
||||
|
||||
// do we have a client already configured?
|
||||
if existingClient, found := c.clients[gv]; found {
|
||||
return existingClient, nil
|
||||
}
|
||||
|
||||
// avoid changing the original config
|
||||
confCopy := *c.config
|
||||
conf := &confCopy
|
||||
|
||||
// we need to set the api path based on group version, if no group, default to legacy path
|
||||
conf.APIPath = c.apiPathResolverFunc(kind)
|
||||
|
||||
// we need to make a client
|
||||
conf.GroupVersion = &gv
|
||||
|
||||
dynamicClient, err := NewClient(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[gv] = dynamicClient
|
||||
return dynamicClient, nil
|
||||
}
|
96
vendor/k8s.io/client-go/dynamic/dynamic_util.go
generated
vendored
Normal file
96
vendor/k8s.io/client-go/dynamic/dynamic_util.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// VersionInterfaces provides an object converter and metadata
|
||||
// accessor appropriate for use with unstructured objects.
|
||||
func VersionInterfaces(schema.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: &unstructured.UnstructuredObjectConverter{},
|
||||
MetadataAccessor: meta.NewAccessor(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information.
|
||||
func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) {
|
||||
rm := meta.NewDefaultRESTMapper(nil, versionFunc)
|
||||
for _, resourceList := range resources {
|
||||
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
gvk := gv.WithKind(resource.Kind)
|
||||
scope := meta.RESTScopeRoot
|
||||
if resource.Namespaced {
|
||||
scope = meta.RESTScopeNamespace
|
||||
}
|
||||
rm.Add(gvk, scope)
|
||||
}
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
|
||||
// ObjectTyper provides an ObjectTyper implementation for
|
||||
// unstructured.Unstructured object based on discovery information.
|
||||
type ObjectTyper struct {
|
||||
registered map[schema.GroupVersionKind]bool
|
||||
}
|
||||
|
||||
// NewObjectTyper constructs an ObjectTyper from discovery information.
|
||||
func NewObjectTyper(resources []*metav1.APIResourceList) (runtime.ObjectTyper, error) {
|
||||
ot := &ObjectTyper{registered: make(map[schema.GroupVersionKind]bool)}
|
||||
for _, resourceList := range resources {
|
||||
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
ot.registered[gv.WithKind(resource.Kind)] = true
|
||||
}
|
||||
}
|
||||
return ot, nil
|
||||
}
|
||||
|
||||
// ObjectKinds returns a slice of one element with the
|
||||
// group,version,kind of the provided object, or an error if the
|
||||
// object is not *unstructured.Unstructured or has no group,version,kind
|
||||
// information.
|
||||
func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
if _, ok := obj.(*unstructured.Unstructured); !ok {
|
||||
return nil, false, fmt.Errorf("type %T is invalid for dynamic object typer", obj)
|
||||
}
|
||||
return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
|
||||
// Recognizes returns true if the provided group,version,kind was in
|
||||
// the discovery information.
|
||||
func (ot *ObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return ot.registered[gvk]
|
||||
}
|
Loading…
Reference in New Issue
Block a user