mirror of https://github.com/kubernetes/kops.git
Merge pull request #7692 from zetaab/kops_ctrl_openstack
Kops controller support for OpenStack
This commit is contained in:
commit
ff1d94c7cb
2
Makefile
2
Makefile
|
@ -923,4 +923,4 @@ crds:
|
||||||
|
|
||||||
.PHONY: kops-controller-push
|
.PHONY: kops-controller-push
|
||||||
kops-controller-push:
|
kops-controller-push:
|
||||||
DOCKER_REGISTRY=${DOCKER_REGISTRY} DOCKER_IMAGE_PREFIX=${DOCKER_IMAGE_PREFIX} KOPS_CONTROLLER_TAG=${KOPS_CONTROLLER_TAG} bazel run //cmd/kops-controller:push-image
|
DOCKER_REGISTRY=${DOCKER_REGISTRY} DOCKER_IMAGE_PREFIX=${DOCKER_IMAGE_PREFIX} KOPS_CONTROLLER_TAG=${KOPS_CONTROLLER_TAG} bazel run --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //cmd/kops-controller:push-image
|
||||||
|
|
|
@ -10,6 +10,7 @@ go_library(
|
||||||
"//pkg/nodeidentity:go_default_library",
|
"//pkg/nodeidentity:go_default_library",
|
||||||
"//pkg/nodeidentity/aws:go_default_library",
|
"//pkg/nodeidentity/aws:go_default_library",
|
||||||
"//pkg/nodeidentity/gce:go_default_library",
|
"//pkg/nodeidentity/gce:go_default_library",
|
||||||
|
"//pkg/nodeidentity/openstack:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp:go_default_library",
|
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp:go_default_library",
|
||||||
|
|
|
@ -34,6 +34,8 @@ import (
|
||||||
"k8s.io/kops/pkg/nodeidentity"
|
"k8s.io/kops/pkg/nodeidentity"
|
||||||
nodeidentityaws "k8s.io/kops/pkg/nodeidentity/aws"
|
nodeidentityaws "k8s.io/kops/pkg/nodeidentity/aws"
|
||||||
nodeidentitygce "k8s.io/kops/pkg/nodeidentity/gce"
|
nodeidentitygce "k8s.io/kops/pkg/nodeidentity/gce"
|
||||||
|
nodeidentityos "k8s.io/kops/pkg/nodeidentity/openstack"
|
||||||
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -119,6 +121,12 @@ func addNodeController(mgr manager.Manager, opt *Options) error {
|
||||||
return fmt.Errorf("error building identifier: %v", err)
|
return fmt.Errorf("error building identifier: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "openstack":
|
||||||
|
identifier, err = nodeidentityos.New()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error building identifier: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
case "":
|
case "":
|
||||||
return fmt.Errorf("must specify cloud")
|
return fmt.Errorf("must specify cloud")
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ k8s.io/kops/pkg/model/vspheremodel
|
||||||
k8s.io/kops/pkg/nodeidentity
|
k8s.io/kops/pkg/nodeidentity
|
||||||
k8s.io/kops/pkg/nodeidentity/aws
|
k8s.io/kops/pkg/nodeidentity/aws
|
||||||
k8s.io/kops/pkg/nodeidentity/gce
|
k8s.io/kops/pkg/nodeidentity/gce
|
||||||
|
k8s.io/kops/pkg/nodeidentity/openstack
|
||||||
k8s.io/kops/pkg/nodelabels
|
k8s.io/kops/pkg/nodelabels
|
||||||
k8s.io/kops/pkg/pki
|
k8s.io/kops/pkg/pki
|
||||||
k8s.io/kops/pkg/pkiutil
|
k8s.io/kops/pkg/pkiutil
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["identify.go"],
|
||||||
|
importpath = "k8s.io/kops/pkg/nodeidentity/openstack",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/nodeidentity:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
|
||||||
|
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
|
||||||
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 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 openstack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gophercloud/gophercloud"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack"
|
||||||
|
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/kops/pkg/nodeidentity"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nodeIdentifier identifies a node
|
||||||
|
type nodeIdentifier struct {
|
||||||
|
novaClient *gophercloud.ServiceClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates and returns a nodeidentity.Identifier for Nodes running on OpenStack
|
||||||
|
func New() (nodeidentity.Identifier, error) {
|
||||||
|
env, err := openstack.AuthOptionsFromEnv()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
region := os.Getenv("OS_REGION_NAME")
|
||||||
|
if region == "" {
|
||||||
|
return nil, fmt.Errorf("Unable to find region")
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := openstack.NewClient(env.IdentityEndpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = openstack.Authenticate(provider, env)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
novaClient, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
|
||||||
|
Type: "compute",
|
||||||
|
Region: region,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error building nova client: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &nodeIdentifier{
|
||||||
|
novaClient: novaClient,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IdentifyNode queries OpenStack for the node identity information
|
||||||
|
func (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*nodeidentity.Info, error) {
|
||||||
|
providerID := node.Spec.ProviderID
|
||||||
|
if providerID == "" {
|
||||||
|
return nil, fmt.Errorf("providerID was not set for node %s", node.Name)
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(providerID, "openstack://") {
|
||||||
|
return nil, fmt.Errorf("providerID %q not recognized for node %s", providerID, node.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceID := strings.TrimPrefix(providerID, "openstack://")
|
||||||
|
// instanceid looks like its openstack:/// but no idea is that really correct like that?
|
||||||
|
// this supports now both openstack:// and openstack:/// format
|
||||||
|
if strings.HasPrefix(instanceID, "/") {
|
||||||
|
instanceID = strings.TrimPrefix(instanceID, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
kopsGroup, err := i.getInstanceGroup(instanceID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := &nodeidentity.Info{}
|
||||||
|
info.InstanceGroup = kopsGroup
|
||||||
|
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *nodeIdentifier) getInstanceGroup(instanceID string) (string, error) {
|
||||||
|
instance, err := servers.Get(i.novaClient, instanceID).Extract()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := instance.Metadata["KopsInstanceGroup"]; ok {
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("Could not find tag 'KopsInstanceGroup' from instance metadata")
|
||||||
|
}
|
Loading…
Reference in New Issue