mirror of
https://github.com/rancher/rke.git
synced 2025-08-16 13:56:34 +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
|
network_plugin: flannel
|
||||||
hosts:
|
hosts:
|
||||||
- hostname: server1
|
- hostname: server1
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"k8s.io/client-go/util/cert"
|
"k8s.io/client-go/util/cert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetUpAuthentication(kubeCluster, currentCluster *Cluster, authType string) error {
|
func SetUpAuthentication(kubeCluster, currentCluster *Cluster) error {
|
||||||
if authType == X509AuthenticationProvider {
|
if kubeCluster.AuthType == X509AuthenticationProvider {
|
||||||
var err error
|
var err error
|
||||||
if currentCluster != nil {
|
if currentCluster != nil {
|
||||||
kubeCluster.Certificates, err = getClusterCerts(kubeCluster.KubeClient)
|
kubeCluster.Certificates, err = getClusterCerts(kubeCluster.KubeClient)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/rancher/rke/hosts"
|
"github.com/rancher/rke/hosts"
|
||||||
"github.com/rancher/rke/pki"
|
"github.com/rancher/rke/pki"
|
||||||
"github.com/rancher/rke/services"
|
"github.com/rancher/rke/services"
|
||||||
@ -13,8 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
Services services.Services `yaml:"services"`
|
v1.RKEConfig `yaml:",inline"`
|
||||||
Hosts []hosts.Host `yaml:"hosts"`
|
|
||||||
EtcdHosts []hosts.Host
|
EtcdHosts []hosts.Host
|
||||||
WorkerHosts []hosts.Host
|
WorkerHosts []hosts.Host
|
||||||
ControlPlaneHosts []hosts.Host
|
ControlPlaneHosts []hosts.Host
|
||||||
@ -22,7 +22,6 @@ type Cluster struct {
|
|||||||
KubernetesServiceIP net.IP
|
KubernetesServiceIP net.IP
|
||||||
Certificates map[string]pki.CertificatePKI
|
Certificates map[string]pki.CertificatePKI
|
||||||
ClusterDomain string
|
ClusterDomain string
|
||||||
NetworkPlugin string `yaml:"network_plugin"`
|
|
||||||
ClusterCIDR string
|
ClusterCIDR string
|
||||||
ClusterDNSServer string
|
ClusterDNSServer string
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,16 @@ func (c *Cluster) InvertIndexHosts() error {
|
|||||||
for _, host := range c.Hosts {
|
for _, host := range c.Hosts {
|
||||||
for _, role := range host.Role {
|
for _, role := range host.Role {
|
||||||
logrus.Debugf("Host: " + host.Hostname + " has role: " + role)
|
logrus.Debugf("Host: " + host.Hostname + " has role: " + role)
|
||||||
|
newHost := hosts.Host{
|
||||||
|
RKEConfigHost: host,
|
||||||
|
}
|
||||||
switch role {
|
switch role {
|
||||||
case services.ETCDRole:
|
case services.ETCDRole:
|
||||||
c.EtcdHosts = append(c.EtcdHosts, host)
|
c.EtcdHosts = append(c.EtcdHosts, newHost)
|
||||||
case services.ControlRole:
|
case services.ControlRole:
|
||||||
c.ControlPlaneHosts = append(c.ControlPlaneHosts, host)
|
c.ControlPlaneHosts = append(c.ControlPlaneHosts, newHost)
|
||||||
case services.WorkerRole:
|
case services.WorkerRole:
|
||||||
c.WorkerHosts = append(c.WorkerHosts, host)
|
c.WorkerHosts = append(c.WorkerHosts, newHost)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Failed to recognize host [%s] role %s", host.Hostname, role)
|
return fmt.Errorf("Failed to recognize host [%s] role %s", host.Hostname, role)
|
||||||
}
|
}
|
||||||
@ -53,8 +56,8 @@ func (c *Cluster) InvertIndexHosts() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) SetUpHosts(authType string) error {
|
func (c *Cluster) SetUpHosts() error {
|
||||||
if authType == X509AuthenticationProvider {
|
if c.AuthType == X509AuthenticationProvider {
|
||||||
logrus.Infof("[certificates] Deploying kubernetes certificates to Cluster nodes")
|
logrus.Infof("[certificates] Deploying kubernetes certificates to Cluster nodes")
|
||||||
err := pki.DeployCertificatesOnMasters(c.ControlPlaneHosts, c.Certificates)
|
err := pki.DeployCertificatesOnMasters(c.ControlPlaneHosts, c.Certificates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,12 +21,6 @@ func ClusterCommand() cli.Command {
|
|||||||
Value: "cluster.yml",
|
Value: "cluster.yml",
|
||||||
EnvVar: "CLUSTER_FILE",
|
EnvVar: "CLUSTER_FILE",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "auth-type",
|
|
||||||
Usage: "Specify authentication type",
|
|
||||||
Value: "x509",
|
|
||||||
EnvVar: "AUTH_TYPE",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
Name: "cluster",
|
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")
|
logrus.Infof("Building Kubernetes cluster")
|
||||||
var APIURL, caCrt, clientCert, clientKey string
|
var APIURL, caCrt, clientCert, clientKey string
|
||||||
kubeCluster, err := cluster.ParseConfig(clusterFile)
|
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
|
return APIURL, caCrt, clientCert, clientKey, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cluster.SetUpAuthentication(kubeCluster, currentCluster, authType)
|
err = cluster.SetUpAuthentication(kubeCluster, currentCluster)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIURL, caCrt, clientCert, clientKey, err
|
return APIURL, caCrt, clientCert, clientKey, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = kubeCluster.SetUpHosts(authType)
|
err = kubeCluster.SetUpHosts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return APIURL, caCrt, clientCert, clientKey, err
|
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 {
|
func clusterUpFromCli(ctx *cli.Context) error {
|
||||||
authType := ctx.String("auth-type")
|
|
||||||
clusterFile, err := resolveClusterFile(ctx)
|
clusterFile, err := resolveClusterFile(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to resolve cluster file: %v", err)
|
return fmt.Errorf("Failed to resolve cluster file: %v", err)
|
||||||
}
|
}
|
||||||
_, _, _, _, err = ClusterUp(clusterFile, authType)
|
_, _, _, _, err = ClusterUp(clusterFile)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,18 +2,14 @@ package hosts
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/rancher/rke/k8s"
|
"github.com/rancher/rke/k8s"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Host struct {
|
type Host struct {
|
||||||
IP string `yaml:"ip"`
|
v1.RKEConfigHost
|
||||||
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
|
DClient *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/rancher/rke/hosts"
|
"github.com/rancher/rke/hosts"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,11 +18,14 @@ const (
|
|||||||
func TestPKI(t *testing.T) {
|
func TestPKI(t *testing.T) {
|
||||||
cpHosts := []hosts.Host{
|
cpHosts := []hosts.Host{
|
||||||
hosts.Host{
|
hosts.Host{
|
||||||
|
RKEConfigHost: v1.RKEConfigHost{
|
||||||
IP: "1.1.1.1",
|
IP: "1.1.1.1",
|
||||||
AdvertiseAddress: "192.168.1.5",
|
AdvertiseAddress: "192.168.1.5",
|
||||||
Role: []string{"controlplane"},
|
Role: []string{"controlplane"},
|
||||||
Hostname: "server1",
|
Hostname: "server1",
|
||||||
},
|
},
|
||||||
|
DClient: nil,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
certificateMap, err := StartCertificatesGeneration(cpHosts, cpHosts, FakeClusterDomain, net.ParseIP(FakeKubernetesServiceIP))
|
certificateMap, err := StartCertificatesGeneration(cpHosts, cpHosts, FakeClusterDomain, net.ParseIP(FakeKubernetesServiceIP))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2,10 +2,11 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/rancher/rke/hosts"
|
"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)
|
logrus.Infof("[%s] Building up Controller Plane..", ControlRole)
|
||||||
for _, host := range controlHosts {
|
for _, host := range controlHosts {
|
||||||
// run kubeapi
|
// run kubeapi
|
||||||
|
@ -2,13 +2,14 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
"github.com/rancher/rke/hosts"
|
"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)
|
logrus.Infof("[%s] Building up Etcd Plane..", ETCDRole)
|
||||||
for _, host := range etcdHosts {
|
for _, host := range etcdHosts {
|
||||||
imageCfg, hostCfg := buildEtcdConfig(host, etcdService)
|
imageCfg, hostCfg := buildEtcdConfig(host, etcdService)
|
||||||
@ -21,7 +22,7 @@ func RunEtcdPlane(etcdHosts []hosts.Host, etcdService Etcd) error {
|
|||||||
return nil
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: etcdService.Image,
|
Image: etcdService.Image,
|
||||||
Cmd: []string{"/usr/local/bin/etcd",
|
Cmd: []string{"/usr/local/bin/etcd",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
@ -8,13 +9,13 @@ import (
|
|||||||
"github.com/rancher/rke/pki"
|
"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)
|
etcdConnString := getEtcdConnString(etcdHosts)
|
||||||
imageCfg, hostCfg := buildKubeAPIConfig(host, kubeAPIService, etcdConnString)
|
imageCfg, hostCfg := buildKubeAPIConfig(host, kubeAPIService, etcdConnString)
|
||||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Hostname, ControlRole)
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: kubeAPIService.Image,
|
Image: kubeAPIService.Image,
|
||||||
Cmd: []string{"/hyperkube",
|
Cmd: []string{"/hyperkube",
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
"github.com/rancher/rke/hosts"
|
"github.com/rancher/rke/hosts"
|
||||||
"github.com/rancher/rke/pki"
|
"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)
|
imageCfg, hostCfg := buildKubeControllerConfig(kubeControllerService)
|
||||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeControllerContainerName, host.Hostname, ControlRole)
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: kubeControllerService.Image,
|
Image: kubeControllerService.Image,
|
||||||
Cmd: []string{"/hyperkube",
|
Cmd: []string{"/hyperkube",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
@ -8,12 +9,12 @@ import (
|
|||||||
"github.com/rancher/rke/pki"
|
"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)
|
imageCfg, hostCfg := buildKubeletConfig(host, kubeletService, isMaster)
|
||||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeletContainerName, host.Hostname, WorkerRole)
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: kubeletService.Image,
|
Image: kubeletService.Image,
|
||||||
Cmd: []string{"/hyperkube",
|
Cmd: []string{"/hyperkube",
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
"github.com/rancher/rke/hosts"
|
"github.com/rancher/rke/hosts"
|
||||||
"github.com/rancher/rke/pki"
|
"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)
|
imageCfg, hostCfg := buildKubeproxyConfig(host, kubeproxyService)
|
||||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, KubeproxyContainerName, host.Hostname, WorkerRole)
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: kubeproxyService.Image,
|
Image: kubeproxyService.Image,
|
||||||
Cmd: []string{"/hyperkube",
|
Cmd: []string{"/hyperkube",
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/rancher/rke/docker"
|
"github.com/rancher/rke/docker"
|
||||||
"github.com/rancher/rke/hosts"
|
"github.com/rancher/rke/hosts"
|
||||||
"github.com/rancher/rke/pki"
|
"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)
|
imageCfg, hostCfg := buildSchedulerConfig(host, schedulerService)
|
||||||
return docker.DoRunContainer(host.DClient, imageCfg, hostCfg, SchedulerContainerName, host.Hostname, ControlRole)
|
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{
|
imageCfg := &container.Config{
|
||||||
Image: schedulerService.Image,
|
Image: schedulerService.Image,
|
||||||
Cmd: []string{"/hyperkube",
|
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 (
|
import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/alena1108/cluster-controller/client/v1"
|
||||||
"github.com/rancher/rke/hosts"
|
"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)
|
logrus.Infof("[%s] Building up Worker Plane..", WorkerRole)
|
||||||
for _, host := range controlHosts {
|
for _, host := range controlHosts {
|
||||||
// only one master for now
|
// only one master for now
|
||||||
|
@ -16,3 +16,4 @@ github.com/opencontainers/image-spec 7c889fafd04a893f5c5f50b7ab9963d5d64e5242
|
|||||||
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
|
github.com/pkg/errors f15c970de5b76fac0b59abb32d62c17cc7bed265
|
||||||
k8s.io/client-go v4.0.0 transitive=true
|
k8s.io/client-go v4.0.0 transitive=true
|
||||||
gopkg.in/check.v1 11d3bc7aa68e238947792f30573146a3231fc0f1
|
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