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
|
||||
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/aws: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/apimachinery/pkg/runtime: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"
|
||||
nodeidentityaws "k8s.io/kops/pkg/nodeidentity/aws"
|
||||
nodeidentitygce "k8s.io/kops/pkg/nodeidentity/gce"
|
||||
nodeidentityos "k8s.io/kops/pkg/nodeidentity/openstack"
|
||||
|
||||
"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)
|
||||
}
|
||||
|
||||
case "openstack":
|
||||
identifier, err = nodeidentityos.New()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building identifier: %v", err)
|
||||
}
|
||||
|
||||
case "":
|
||||
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/aws
|
||||
k8s.io/kops/pkg/nodeidentity/gce
|
||||
k8s.io/kops/pkg/nodeidentity/openstack
|
||||
k8s.io/kops/pkg/nodelabels
|
||||
k8s.io/kops/pkg/pki
|
||||
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