mirror of https://github.com/kubernetes/kops.git
server groups, lb, instance, and dns tasks, models and resources
This commit is contained in:
parent
83365a992a
commit
3064f6be15
|
@ -5,12 +5,16 @@ go_library(
|
|||
srcs = [
|
||||
"context.go",
|
||||
"convenience.go",
|
||||
"instance.go",
|
||||
"lb.go",
|
||||
"network.go",
|
||||
"servergroup.go",
|
||||
"sshkey.go",
|
||||
],
|
||||
importpath = "k8s.io/kops/pkg/model/openstackmodel",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/kops:go_default_library",
|
||||
"//pkg/model:go_default_library",
|
||||
"//upup/pkg/fi:go_default_library",
|
||||
"//upup/pkg/fi/cloudup/openstacktasks:go_default_library",
|
||||
|
|
|
@ -36,3 +36,7 @@ func (c *OpenstackModelContext) LinkToRouter(name *string) *openstacktasks.Route
|
|||
func (c *OpenstackModelContext) LinkToSubnet(name *string) *openstacktasks.Subnet {
|
||||
return &openstacktasks.Subnet{Name: name}
|
||||
}
|
||||
|
||||
func (c *OpenstackModelContext) LinkToPort(name *string) *openstacktasks.Port {
|
||||
return &openstacktasks.Port{Name: name}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2018 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 openstackmodel
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kops/pkg/model"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstacktasks"
|
||||
)
|
||||
|
||||
// InstanceModelBuilder configures instance objects
|
||||
type InstanceModelBuilder struct {
|
||||
*OpenstackModelContext
|
||||
BootstrapScript *model.BootstrapScript
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.ModelBuilder = &InstanceModelBuilder{}
|
||||
|
||||
func (b *InstanceModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||
sshKeyNameFull, err := b.SSHKeyName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
splitSSHKeyNameFull := strings.Split(sshKeyNameFull, "-")
|
||||
sshKeyName := splitSSHKeyNameFull[0]
|
||||
|
||||
clusterTag := "KubernetesCluster:" + strings.Replace(b.ClusterName(), ".", "-", -1)
|
||||
|
||||
// In the future, OpenStack will use Machine API to manage groups,
|
||||
// for now create d.InstanceGroups.Spec.MinSize amount of servers
|
||||
for _, ig := range b.InstanceGroups {
|
||||
clusterName := b.AutoscalingGroupName(ig)
|
||||
|
||||
{
|
||||
t := &openstacktasks.Port{
|
||||
Name: s(clusterName),
|
||||
Network: b.LinkToNetwork(),
|
||||
Lifecycle: b.Lifecycle,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
||||
{
|
||||
var t openstacktasks.Instance
|
||||
t.Count = int(fi.Int32Value(ig.Spec.MinSize))
|
||||
t.Name = fi.String(clusterName)
|
||||
t.Region = fi.String(b.Cluster.Spec.Subnets[0].Region)
|
||||
t.Flavor = fi.String(ig.Spec.MachineType)
|
||||
t.Image = fi.String(ig.Spec.Image)
|
||||
t.SSHKey = fi.String(sshKeyName)
|
||||
t.Tags = []string{clusterTag}
|
||||
t.Role = fi.String(string(ig.Spec.Role))
|
||||
t.Port = b.LinkToPort(fi.String(clusterName))
|
||||
c.AddTask(&t)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright 2018 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 openstackmodel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstacktasks"
|
||||
)
|
||||
|
||||
// APILBModelBuilder configures loadbalancer objects
|
||||
type APILBModelBuilder struct {
|
||||
*OpenstackModelContext
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.ModelBuilder = &APILBModelBuilder{}
|
||||
|
||||
func (b *APILBModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||
if !b.UseLoadBalancerForAPI() {
|
||||
return nil
|
||||
}
|
||||
|
||||
lbSpec := b.Cluster.Spec.API.LoadBalancer
|
||||
if lbSpec == nil {
|
||||
// Skipping API LB creation; not requested in Spec
|
||||
return nil
|
||||
}
|
||||
|
||||
switch lbSpec.Type {
|
||||
case kops.LoadBalancerTypePublic:
|
||||
// OK
|
||||
|
||||
case kops.LoadBalancerTypeInternal:
|
||||
return fmt.Errorf("internal loadbalancers are not yet supported by kops on openstack")
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled loadbalancers type %q", lbSpec.Type)
|
||||
}
|
||||
|
||||
clusterName := b.ClusterName()
|
||||
lbName := "api-" + strings.Replace(clusterName, ".", "-", -1)
|
||||
|
||||
{
|
||||
t := &openstacktasks.LB{
|
||||
Name: s(lbName),
|
||||
Subnet: b.LinkToSubnet(s(b.Cluster.Spec.Subnets[0].Name)),
|
||||
Lifecycle: b.Lifecycle,
|
||||
}
|
||||
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Copyright 2018 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 openstackmodel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstacktasks"
|
||||
)
|
||||
|
||||
// ServerGroupModelBuilder configures server group objects
|
||||
type ServerGroupModelBuilder struct {
|
||||
*OpenstackModelContext
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.ModelBuilder = &ServerGroupModelBuilder{}
|
||||
|
||||
func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
|
||||
clusterName := b.ClusterName()
|
||||
|
||||
for _, ig := range b.InstanceGroups {
|
||||
t := &openstacktasks.ServerGroup{
|
||||
Name: s(fmt.Sprintf("%s-%s", clusterName, ig.Spec.Role)),
|
||||
Policies: []string{"anti-affinity"},
|
||||
Lifecycle: b.Lifecycle,
|
||||
}
|
||||
c.AddTask(t)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -2,11 +2,29 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
|||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["resources.go"],
|
||||
srcs = [
|
||||
"blockstorage.go",
|
||||
"compute.go",
|
||||
"dns.go",
|
||||
"lb.go",
|
||||
"networking.go",
|
||||
"openstack.go",
|
||||
],
|
||||
importpath = "k8s.io/kops/pkg/resources/openstack",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/resources:go_default_library",
|
||||
"//upup/pkg/fi:go_default_library",
|
||||
"//upup/pkg/fi/cloudup/openstack:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/ports:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
const (
|
||||
typeVolume = "Volume"
|
||||
)
|
||||
|
||||
var listBlockStorageFunctions = []listFn{
|
||||
listVolumes,
|
||||
}
|
||||
|
||||
func listVolumes(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
var resourceTrackers []*resources.Resource
|
||||
|
||||
opts := volumes.ListOpts{
|
||||
Metadata: cloud.GetCloudTags(),
|
||||
}
|
||||
vs, err := cloud.ListVolumes(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list volumes: %s", err)
|
||||
}
|
||||
|
||||
for _, v := range vs {
|
||||
resourceTracker := &resources.Resource{
|
||||
Name: v.Name,
|
||||
ID: v.ID,
|
||||
Type: typeVolume,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return volumes.Delete(cloud.(openstack.OpenstackCloud).BlockStorageClient(), r.ID).ExtractErr()
|
||||
},
|
||||
Obj: v,
|
||||
}
|
||||
resourceTrackers = append(resourceTrackers, resourceTracker)
|
||||
}
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
const (
|
||||
typeKeypair = "keypair"
|
||||
typeServer = "server"
|
||||
typeServerGroup = "serverGroup"
|
||||
)
|
||||
|
||||
func listInstances(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
var resourceTrackers []*resources.Resource
|
||||
|
||||
clusterTag := "KubernetesCluster:" + strings.Replace(clusterName, ".", "-", -1)
|
||||
|
||||
opts := servers.ListOpts{
|
||||
Name: clusterTag,
|
||||
}
|
||||
ss, err := cloud.ListInstances(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list servers: %v", err)
|
||||
}
|
||||
|
||||
for _, s := range ss {
|
||||
resourceTracker := &resources.Resource{
|
||||
Name: s.Name,
|
||||
ID: s.ID,
|
||||
Type: typeServer,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return servers.Delete(cloud.(openstack.OpenstackCloud).ComputeClient(), s.ID).ExtractErr()
|
||||
},
|
||||
Obj: s,
|
||||
}
|
||||
|
||||
resourceTrackers = append(resourceTrackers, resourceTracker)
|
||||
}
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
||||
|
||||
func listServerGroups(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
var resourceTrackers []*resources.Resource
|
||||
|
||||
sgsAll, err := cloud.ListServerGroups()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract server group pages: %s", err)
|
||||
}
|
||||
|
||||
var sgs []servergroups.ServerGroup
|
||||
for _, sg := range sgsAll {
|
||||
if strings.HasPrefix(sg.Name, clusterName) {
|
||||
sgs = append(sgs, sg)
|
||||
}
|
||||
}
|
||||
|
||||
for _, sg := range sgs {
|
||||
resourceTracker := &resources.Resource{
|
||||
Name: sg.ID,
|
||||
ID: sg.Name,
|
||||
Type: typeServerGroup,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return servergroups.Delete(cloud.(openstack.OpenstackCloud).ComputeClient(), r.ID).ExtractErr()
|
||||
},
|
||||
Obj: sg,
|
||||
}
|
||||
|
||||
resourceTrackers = append(resourceTrackers, resourceTracker)
|
||||
}
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
||||
|
||||
func listKeypairs(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
var resourceTrackers []*resources.Resource
|
||||
|
||||
kp, err := cloud.ListKeypair(clusterName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get keypair: %s", err)
|
||||
}
|
||||
|
||||
if kp == nil {
|
||||
return resourceTrackers, nil
|
||||
}
|
||||
|
||||
resourceTracker := &resources.Resource{
|
||||
Name: kp.Name,
|
||||
ID: kp.Name,
|
||||
Type: typeKeypair,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return keypairs.Delete(cloud.(openstack.OpenstackCloud).ComputeClient(), r.ID).ExtractErr()
|
||||
},
|
||||
Obj: kp,
|
||||
}
|
||||
|
||||
resourceTrackers = append(resourceTrackers, resourceTracker)
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
const (
|
||||
typeDNSRecord = "dNSRecord"
|
||||
)
|
||||
|
||||
var listDNSFunctions = []listFn{
|
||||
listDNSRecordsets,
|
||||
}
|
||||
|
||||
func listDNSRecordsets(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
zopts := zones.ListOpts{
|
||||
Name: clusterName,
|
||||
}
|
||||
zs, err := cloud.ListDNSZones(zopts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list dns zones: %s", err)
|
||||
}
|
||||
|
||||
switch len(zs) {
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
}
|
||||
|
||||
z := zs[0]
|
||||
|
||||
rrs, err := cloud.ListDNSRecordsets(z.ID, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract recordsets pages for zone %s: %v", z.Name, err)
|
||||
}
|
||||
|
||||
var resourceTrackers []*resources.Resource
|
||||
for _, rr := range rrs {
|
||||
if rr.Type != "A" {
|
||||
continue
|
||||
}
|
||||
|
||||
resourceTracker := &resources.Resource{
|
||||
Name: rr.Name,
|
||||
ID: rr.ID,
|
||||
Type: typeDNSRecord,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return recordsets.Delete(cloud.(openstack.OpenstackCloud).DNSClient(), z.ID, rr.ID).ExtractErr()
|
||||
},
|
||||
Obj: rr,
|
||||
}
|
||||
|
||||
resourceTrackers = append(resourceTrackers, resourceTracker)
|
||||
}
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
const (
|
||||
typeLB = "lb"
|
||||
)
|
||||
|
||||
func listLBs(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
opts := loadbalancers.ListOpts{
|
||||
Name: clusterName,
|
||||
}
|
||||
lbs, err := cloud.ListLBs(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list lbs: %s", err)
|
||||
}
|
||||
|
||||
var rts []*resources.Resource
|
||||
for _, t := range lbs {
|
||||
rt := &resources.Resource{
|
||||
Name: t.Name,
|
||||
ID: t.ID,
|
||||
Type: typeLB,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
opts := loadbalancers.DeleteOpts{
|
||||
Cascade: true,
|
||||
}
|
||||
return loadbalancers.Delete(cloud.(openstack.OpenstackCloud).LoadBalancerClient(), t.ID, opts).ExtractErr()
|
||||
},
|
||||
Obj: lbs,
|
||||
}
|
||||
rts = append(rts, rt)
|
||||
}
|
||||
|
||||
return rts, nil
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
const (
|
||||
typeNetwork = "network"
|
||||
typeSubnet = "subnet"
|
||||
typePort = "port"
|
||||
typeRouter = "router"
|
||||
)
|
||||
|
||||
func listNetworks(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
rts := make([]*resources.Resource, 0)
|
||||
opts := networks.ListOpts{
|
||||
Name: clusterName,
|
||||
}
|
||||
ns, err := cloud.ListNetworks(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list networks: %s", err)
|
||||
}
|
||||
for _, n := range ns {
|
||||
rt := &resources.Resource{
|
||||
Name: n.Name,
|
||||
ID: n.ID,
|
||||
Type: typeNetwork,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return networks.Delete(cloud.(openstack.OpenstackCloud).NetworkingClient(), n.ID).ExtractErr()
|
||||
},
|
||||
Obj: n,
|
||||
}
|
||||
rts = append(rts, rt)
|
||||
}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func listSubnets(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
rts := make([]*resources.Resource, 0)
|
||||
opts := subnets.ListOpts{
|
||||
Name: clusterName,
|
||||
}
|
||||
subs, err := cloud.ListSubnets(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list subnets: %s", err)
|
||||
}
|
||||
for _, s := range subs {
|
||||
rt := &resources.Resource{
|
||||
Name: s.Name,
|
||||
ID: s.ID,
|
||||
Type: typeSubnet,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return subnets.Delete(cloud.(openstack.OpenstackCloud).NetworkingClient(), s.ID).ExtractErr()
|
||||
},
|
||||
Obj: s,
|
||||
}
|
||||
rts = append(rts, rt)
|
||||
}
|
||||
return rts, nil
|
||||
}
|
||||
|
||||
func listPorts(cloud openstack.OpenstackCloud, clusterName string) ([]*resources.Resource, error) {
|
||||
rts := make([]*resources.Resource, 0)
|
||||
opts := ports.ListOpts{
|
||||
Name: clusterName,
|
||||
}
|
||||
ss, err := cloud.ListPorts(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list ports: %s", err)
|
||||
}
|
||||
for _, s := range ss {
|
||||
rt := &resources.Resource{
|
||||
Name: s.Name,
|
||||
ID: s.ID,
|
||||
Type: typeSubnet,
|
||||
Deleter: func(cloud fi.Cloud, r *resources.Resource) error {
|
||||
return ports.Delete(cloud.(openstack.OpenstackCloud).NetworkingClient(), s.ID).ExtractErr()
|
||||
},
|
||||
Obj: s,
|
||||
}
|
||||
rts = append(rts, rt)
|
||||
}
|
||||
return rts, nil
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups"
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
type listFn func(openstack.OpenstackCloud, string) ([]*resources.Resource, error)
|
||||
|
||||
// ListResources lists the OpenStack resources kops manages
|
||||
func ListResources(cloud openstack.OpenstackCloud, clusterName string) (map[string]*resources.Resource, error) {
|
||||
rts := make(map[string]*resources.Resource)
|
||||
|
||||
keypairs, err := listKeypairs(cloud, clusterName)
|
||||
if err != nil {
|
||||
return rts, err
|
||||
}
|
||||
keypairIDs := make([]string, len(keypairs))
|
||||
for i, t := range keypairs {
|
||||
id := t.Type + ":" + t.ID
|
||||
rts[id] = t
|
||||
keypairIDs[i] = id
|
||||
}
|
||||
|
||||
serverGroups, err := listServerGroups(cloud, clusterName)
|
||||
if err != nil {
|
||||
return rts, err
|
||||
}
|
||||
serverGroupIDs := make([]string, len(serverGroups))
|
||||
for _, t := range serverGroups {
|
||||
id := t.Type + ":" + t.ID
|
||||
for _, m := range t.Obj.(servergroups.ServerGroup).Members {
|
||||
t.Blocked = append(t.Blocks, typeServer+":"+m)
|
||||
}
|
||||
serverGroupIDs = append(serverGroupIDs, id)
|
||||
rts[id] = t
|
||||
}
|
||||
|
||||
instances, err := listInstances(cloud, clusterName)
|
||||
if err != nil {
|
||||
return rts, err
|
||||
}
|
||||
for _, t := range instances {
|
||||
rts[t.Type+":"+t.ID] = t
|
||||
}
|
||||
|
||||
lbs, err := listLBs(cloud, clusterName)
|
||||
if err != nil {
|
||||
return rts, err
|
||||
}
|
||||
for _, t := range lbs {
|
||||
listeners := t.Obj.(loadbalancers.LoadBalancer).Listeners
|
||||
for _, l := range listeners {
|
||||
for _, p := range l.Pools {
|
||||
t.Blocks = append(t.Blocks, typeSubnet+":"+p.SubnetID)
|
||||
}
|
||||
}
|
||||
rts[t.Type+":"+t.ID] = t
|
||||
}
|
||||
|
||||
return rts, nil
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"k8s.io/kops/pkg/resources"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
type listFn func(openstack.OpenstackCloud, string) ([]*resources.Resource, error)
|
||||
|
||||
func ListResources(cloud openstack.OpenstackCloud, clusterName string) (map[string]*resources.Resource, error) {
|
||||
resourceTrackers := make(map[string]*resources.Resource)
|
||||
|
||||
// TODO(lmb): Implement resource list
|
||||
|
||||
return resourceTrackers, nil
|
||||
}
|
|
@ -518,10 +518,20 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
region = osCloud.Region()
|
||||
|
||||
l.AddTypes(map[string]interface{}{
|
||||
"sshKey": &openstacktasks.SSHKey{},
|
||||
// Compute
|
||||
"sshKey": &openstacktasks.SSHKey{},
|
||||
"serverGroup": &openstacktasks.ServerGroup{},
|
||||
"instance": &openstacktasks.Instance{},
|
||||
// Networking
|
||||
"network": &openstacktasks.Network{},
|
||||
"router": &openstacktasks.Router{},
|
||||
"network": &openstacktasks.Network{},
|
||||
"subnet": &openstacktasks.Subnet{},
|
||||
"router": &openstacktasks.Router{},
|
||||
"securityGroup": &openstacktasks.SecurityGroup{},
|
||||
"securityGroupRule": &openstacktasks.SecurityGroupRule{},
|
||||
// BlockStorage
|
||||
"volume": &openstacktasks.Volume{},
|
||||
// LB
|
||||
"lb": &openstacktasks.LB{},
|
||||
})
|
||||
|
||||
if len(sshPublicKeys) == 0 {
|
||||
|
@ -679,8 +689,10 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
}
|
||||
|
||||
l.Builders = append(l.Builders,
|
||||
&openstackmodel.APILBModelBuilder{OpenstackModelContext: openstackModelContext, Lifecycle: &clusterLifecycle},
|
||||
&openstackmodel.NetworkModelBuilder{OpenstackModelContext: openstackModelContext, Lifecycle: &networkLifecycle},
|
||||
&openstackmodel.SSHKeyModelBuilder{OpenstackModelContext: openstackModelContext, Lifecycle: &securityLifecycle},
|
||||
&openstackmodel.ServerGroupModelBuilder{OpenstackModelContext: openstackModelContext, Lifecycle: &clusterLifecycle},
|
||||
)
|
||||
|
||||
default:
|
||||
|
@ -780,6 +792,15 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
// BareMetal tasks will go here
|
||||
|
||||
case kops.CloudProviderOpenstack:
|
||||
openstackModelContext := &openstackmodel.OpenstackModelContext{
|
||||
KopsModelContext: modelContext,
|
||||
}
|
||||
|
||||
l.Builders = append(l.Builders, &openstackmodel.InstanceModelBuilder{
|
||||
OpenstackModelContext: openstackModelContext,
|
||||
//BootstrapScript: bootstrapScriptBuilder,
|
||||
Lifecycle: &clusterLifecycle,
|
||||
})
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown cloudprovider %q", cluster.Spec.CloudProvider)
|
||||
|
|
|
@ -10,6 +10,7 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//dnsprovider/pkg/dnsprovider:go_default_library",
|
||||
"//dnsprovider/pkg/dnsprovider/providers/openstack/designate:go_default_library",
|
||||
"//pkg/apis/kops:go_default_library",
|
||||
"//pkg/cloudinstances:go_default_library",
|
||||
"//upup/pkg/fi:go_default_library",
|
||||
|
@ -20,6 +21,10 @@ go_library(
|
|||
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules:go_default_library",
|
||||
|
|
|
@ -17,7 +17,9 @@ limitations under the License.
|
|||
package openstack
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
@ -26,6 +28,10 @@ import (
|
|||
cinder "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
|
||||
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
|
||||
sg "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
|
||||
sgr "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
|
||||
|
@ -35,6 +41,7 @@ import (
|
|||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider"
|
||||
"k8s.io/kops/dnsprovider/pkg/dnsprovider/providers/openstack/designate"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/cloudinstances"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
|
@ -67,9 +74,19 @@ var writeBackoff = wait.Backoff{
|
|||
type OpenstackCloud interface {
|
||||
fi.Cloud
|
||||
|
||||
ComputeClient() *gophercloud.ServiceClient
|
||||
BlockStorageClient() *gophercloud.ServiceClient
|
||||
NetworkingClient() *gophercloud.ServiceClient
|
||||
LoadBalancerClient() *gophercloud.ServiceClient
|
||||
DNSClient() *gophercloud.ServiceClient
|
||||
|
||||
// Region returns the region which cloud will run on
|
||||
Region() string
|
||||
|
||||
ListInstances(servers.ListOptsBuilder) ([]servers.Server, error)
|
||||
|
||||
CreateInstance(servers.CreateOptsBuilder) (*servers.Server, error)
|
||||
|
||||
// SetVolumeTags will set the tags for the Cinder volume
|
||||
SetVolumeTags(id string, tags map[string]string) error
|
||||
|
||||
|
@ -77,22 +94,22 @@ type OpenstackCloud interface {
|
|||
GetCloudTags() map[string]string
|
||||
|
||||
// ListVolumes will return the Cinder volumes which match the options
|
||||
ListVolumes(opt cinder.ListOpts) ([]cinder.Volume, error)
|
||||
ListVolumes(opt cinder.ListOptsBuilder) ([]cinder.Volume, error)
|
||||
|
||||
// CreateVolume will create a new Cinder Volume
|
||||
CreateVolume(opt cinder.CreateOpts) (*cinder.Volume, error)
|
||||
CreateVolume(opt cinder.CreateOptsBuilder) (*cinder.Volume, error)
|
||||
|
||||
//ListSecurityGroups will return the Neutron security groups which match the options
|
||||
ListSecurityGroups(opt sg.ListOpts) ([]sg.SecGroup, error)
|
||||
|
||||
//CreateSecurityGroup will create a new Neutron security group
|
||||
CreateSecurityGroup(opt sg.CreateOpts) (*sg.SecGroup, error)
|
||||
CreateSecurityGroup(opt sg.CreateOptsBuilder) (*sg.SecGroup, error)
|
||||
|
||||
//ListSecurityGroupRules will return the Neutron security group rules which match the options
|
||||
ListSecurityGroupRules(opt sgr.ListOpts) ([]sgr.SecGroupRule, error)
|
||||
|
||||
//CreateSecurityGroupRule will create a new Neutron security group rule
|
||||
CreateSecurityGroupRule(opt sgr.CreateOpts) (*sgr.SecGroupRule, error)
|
||||
CreateSecurityGroupRule(opt sgr.CreateOptsBuilder) (*sgr.SecGroupRule, error)
|
||||
|
||||
//ListNetworks will return the Neutron networks which match the options
|
||||
ListNetworks(opt networks.ListOptsBuilder) ([]networks.Network, error)
|
||||
|
@ -118,6 +135,8 @@ type OpenstackCloud interface {
|
|||
// CreateKeypair will create a new Nova Keypair
|
||||
CreateKeypair(opt keypairs.CreateOptsBuilder) (*keypairs.KeyPair, error)
|
||||
|
||||
CreatePort(opt ports.CreateOptsBuilder) (*ports.Port, error)
|
||||
|
||||
//ListPorts will return the Neutron ports which match the options
|
||||
ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error)
|
||||
|
||||
|
@ -125,13 +144,28 @@ type OpenstackCloud interface {
|
|||
CreateRouterInterface(routerID string, opt routers.AddInterfaceOptsBuilder) (*routers.InterfaceInfo, error)
|
||||
|
||||
// CreateServerGroup will create a new server group.
|
||||
CreateServerGroup(opt servergroups.CreateOpts) (*servergroups.ServerGroup, error)
|
||||
CreateServerGroup(opt servergroups.CreateOptsBuilder) (*servergroups.ServerGroup, error)
|
||||
|
||||
// ListServerGroups will list available server groups
|
||||
ListServerGroups() ([]servergroups.ServerGroup, error)
|
||||
|
||||
// ListDNSZones will list available DNS zones
|
||||
ListDNSZones(opt zones.ListOptsBuilder) ([]zones.Zone, error)
|
||||
|
||||
// ListDNSRecordsets will list the DNS recordsets for the given zone id
|
||||
ListDNSRecordsets(zoneID string, opt recordsets.ListOptsBuilder) ([]recordsets.RecordSet, error)
|
||||
|
||||
CreateLB(opt loadbalancers.CreateOptsBuilder) (*loadbalancers.LoadBalancer, error)
|
||||
|
||||
ListLBs(opt loadbalancers.ListOptsBuilder) ([]loadbalancers.LoadBalancer, error)
|
||||
}
|
||||
|
||||
type openstackCloud struct {
|
||||
cinderClient *gophercloud.ServiceClient
|
||||
neutronClient *gophercloud.ServiceClient
|
||||
novaClient *gophercloud.ServiceClient
|
||||
dnsClient *gophercloud.ServiceClient
|
||||
lbClient *gophercloud.ServiceClient
|
||||
tags map[string]string
|
||||
region string
|
||||
}
|
||||
|
@ -145,7 +179,28 @@ func NewOpenstackCloud(tags map[string]string) (OpenstackCloud, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider, err := os.AuthenticatedClient(authOption)
|
||||
|
||||
/*
|
||||
provider, err := os.AuthenticatedClient(authOption)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack authenticated client: %v", err)
|
||||
}*/
|
||||
|
||||
provider, err := os.NewClient(authOption.IdentityEndpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack provider client: %v", err)
|
||||
}
|
||||
|
||||
tlsconfig := &tls.Config{}
|
||||
tlsconfig.InsecureSkipVerify = true
|
||||
transport := &http.Transport{TLSClientConfig: tlsconfig}
|
||||
provider.HTTPClient = http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
glog.V(2).Info("authenticating to keystone")
|
||||
|
||||
err = os.Authenticate(provider, authOption)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack authenticated client: %v", err)
|
||||
}
|
||||
|
@ -177,18 +232,55 @@ func NewOpenstackCloud(tags map[string]string) (OpenstackCloud, error) {
|
|||
return nil, fmt.Errorf("error building nova client: %v", err)
|
||||
}
|
||||
|
||||
endpointOpt, err = config.GetServiceConfig("Designate")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dnsClient, err := os.NewDNSV2(provider, endpointOpt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building dns client: %v", err)
|
||||
}
|
||||
|
||||
endpointOpt, err = config.GetServiceConfig("LB")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lbClient, err := os.NewLoadBalancerV2(provider, endpointOpt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building lb client: %v", err)
|
||||
}
|
||||
|
||||
region := endpointOpt.Region
|
||||
|
||||
c := &openstackCloud{
|
||||
cinderClient: cinderClient,
|
||||
neutronClient: neutronClient,
|
||||
novaClient: novaClient,
|
||||
lbClient: lbClient,
|
||||
dnsClient: dnsClient,
|
||||
tags: tags,
|
||||
region: region,
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *openstackCloud) ComputeClient() *gophercloud.ServiceClient {
|
||||
return c.novaClient
|
||||
}
|
||||
func (c *openstackCloud) BlockStorageClient() *gophercloud.ServiceClient {
|
||||
return c.cinderClient
|
||||
}
|
||||
func (c *openstackCloud) NetworkingClient() *gophercloud.ServiceClient {
|
||||
return c.neutronClient
|
||||
}
|
||||
func (c *openstackCloud) LoadBalancerClient() *gophercloud.ServiceClient {
|
||||
return c.lbClient
|
||||
}
|
||||
|
||||
func (c *openstackCloud) DNSClient() *gophercloud.ServiceClient {
|
||||
return c.dnsClient
|
||||
}
|
||||
|
||||
func (c *openstackCloud) Region() string {
|
||||
return c.region
|
||||
}
|
||||
|
@ -198,7 +290,11 @@ func (c *openstackCloud) ProviderID() kops.CloudProviderID {
|
|||
}
|
||||
|
||||
func (c *openstackCloud) DNS() (dnsprovider.Interface, error) {
|
||||
return nil, fmt.Errorf("openstackCloud::DNS not implemented")
|
||||
provider, err := dnsprovider.GetDnsProvider(designate.ProviderName, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error building (Designate) DNS provider: %v", err)
|
||||
}
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
func (c *openstackCloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
|
||||
|
@ -217,6 +313,51 @@ func (c *openstackCloud) GetCloudGroups(cluster *kops.Cluster, instancegroups []
|
|||
return nil, fmt.Errorf("openstackCloud::GetCloudGroups not implemented")
|
||||
}
|
||||
|
||||
func (c *openstackCloud) ListInstances(opt servers.ListOptsBuilder) ([]servers.Server, error) {
|
||||
var instances []servers.Server
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
allPages, err := servers.List(c.novaClient, opt).AllPages()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error listing servers %v: %v", opt, err)
|
||||
}
|
||||
|
||||
ss, err := servers.ExtractServers(allPages)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error extracting servers from pages: %v", err)
|
||||
}
|
||||
instances = ss
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return instances, err
|
||||
} else if done {
|
||||
return instances, nil
|
||||
} else {
|
||||
return instances, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateInstance(opt servers.CreateOptsBuilder) (*servers.Server, error) {
|
||||
var server *servers.Server
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
v, err := servers.Create(c.novaClient, opt).Extract()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error creating server %v: %v", opt, err)
|
||||
}
|
||||
server = v
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return server, err
|
||||
} else if done {
|
||||
return server, nil
|
||||
} else {
|
||||
return server, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) SetVolumeTags(id string, tags map[string]string) error {
|
||||
if len(tags) == 0 {
|
||||
return nil
|
||||
|
@ -247,7 +388,7 @@ func (c *openstackCloud) GetCloudTags() map[string]string {
|
|||
return c.tags
|
||||
}
|
||||
|
||||
func (c *openstackCloud) ListVolumes(opt cinder.ListOpts) ([]cinder.Volume, error) {
|
||||
func (c *openstackCloud) ListVolumes(opt cinder.ListOptsBuilder) ([]cinder.Volume, error) {
|
||||
var volumes []cinder.Volume
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
|
@ -272,7 +413,7 @@ func (c *openstackCloud) ListVolumes(opt cinder.ListOpts) ([]cinder.Volume, erro
|
|||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateVolume(opt cinder.CreateOpts) (*cinder.Volume, error) {
|
||||
func (c *openstackCloud) CreateVolume(opt cinder.CreateOptsBuilder) (*cinder.Volume, error) {
|
||||
var volume *cinder.Volume
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
|
@ -317,7 +458,7 @@ func (c *openstackCloud) ListSecurityGroups(opt sg.ListOpts) ([]sg.SecGroup, err
|
|||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateSecurityGroup(opt sg.CreateOpts) (*sg.SecGroup, error) {
|
||||
func (c *openstackCloud) CreateSecurityGroup(opt sg.CreateOptsBuilder) (*sg.SecGroup, error) {
|
||||
var group *sg.SecGroup
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
|
@ -362,7 +503,7 @@ func (c *openstackCloud) ListSecurityGroupRules(opt sgr.ListOpts) ([]sgr.SecGrou
|
|||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateSecurityGroupRule(opt sgr.CreateOpts) (*sgr.SecGroupRule, error) {
|
||||
func (c *openstackCloud) CreateSecurityGroupRule(opt sgr.CreateOptsBuilder) (*sgr.SecGroupRule, error) {
|
||||
var rule *sgr.SecGroupRule
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
|
@ -559,6 +700,26 @@ func (c *openstackCloud) CreateKeypair(opt keypairs.CreateOptsBuilder) (*keypair
|
|||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreatePort(opt ports.CreateOptsBuilder) (*ports.Port, error) {
|
||||
var p *ports.Port
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
v, err := ports.Create(c.neutronClient, opt).Extract()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error creating port: %v", err)
|
||||
}
|
||||
p = v
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return p, err
|
||||
} else if done {
|
||||
return p, nil
|
||||
} else {
|
||||
return p, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error) {
|
||||
var p []ports.Port
|
||||
|
||||
|
@ -604,6 +765,142 @@ func (c *openstackCloud) CreateRouterInterface(routerID string, opt routers.AddI
|
|||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateServerGroup(opt servergroups.CreateOpts) (*servergroups.ServerGroup, error) {
|
||||
return nil, fmt.Errorf("openstackCloud::CreateServerGroup not implemented")
|
||||
func (c *openstackCloud) CreateServerGroup(opt servergroups.CreateOptsBuilder) (*servergroups.ServerGroup, error) {
|
||||
var i *servergroups.ServerGroup
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
v, err := servergroups.Create(c.novaClient, opt).Extract()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error creating server group: %v", err)
|
||||
}
|
||||
i = v
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return i, err
|
||||
} else if done {
|
||||
return i, nil
|
||||
} else {
|
||||
return i, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) ListServerGroups() ([]servergroups.ServerGroup, error) {
|
||||
var sgs []servergroups.ServerGroup
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
allPages, err := servergroups.List(c.novaClient).AllPages()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error listing server groups: %v", err)
|
||||
}
|
||||
|
||||
r, err := servergroups.ExtractServerGroups(allPages)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error extracting server groups from pages: %v", err)
|
||||
}
|
||||
sgs = r
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return sgs, err
|
||||
} else if done {
|
||||
return sgs, nil
|
||||
} else {
|
||||
return sgs, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// ListDNSZones will list available DNS zones
|
||||
func (c *openstackCloud) ListDNSZones(opt zones.ListOptsBuilder) ([]zones.Zone, error) {
|
||||
var zs []zones.Zone
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
allPages, err := zones.List(c.dnsClient, opt).AllPages()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list dns zones: %s", err)
|
||||
}
|
||||
r, err := zones.ExtractZones(allPages)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to extract dns zone pages: %s", err)
|
||||
}
|
||||
zs = r
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return zs, err
|
||||
} else if done {
|
||||
return zs, nil
|
||||
} else {
|
||||
return zs, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// ListDNSRecordsets will list DNS recordsets
|
||||
func (c *openstackCloud) ListDNSRecordsets(zoneID string, opt recordsets.ListOptsBuilder) ([]recordsets.RecordSet, error) {
|
||||
var rrs []recordsets.RecordSet
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
allPages, err := recordsets.ListByZone(c.dnsClient, zoneID, opt).AllPages()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list dns recordsets: %s", err)
|
||||
}
|
||||
r, err := recordsets.ExtractRecordSets(allPages)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to extract dns recordsets pages: %s", err)
|
||||
}
|
||||
rrs = r
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return rrs, err
|
||||
} else if done {
|
||||
return rrs, nil
|
||||
} else {
|
||||
return rrs, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func (c *openstackCloud) CreateLB(opt loadbalancers.CreateOptsBuilder) (*loadbalancers.LoadBalancer, error) {
|
||||
var i *loadbalancers.LoadBalancer
|
||||
|
||||
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
|
||||
v, err := loadbalancers.Create(c.lbClient, opt).Extract()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error creating loadbalancer: %v", err)
|
||||
}
|
||||
i = v
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return i, err
|
||||
} else if done {
|
||||
return i, nil
|
||||
} else {
|
||||
return i, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// ListLBs will list load balancers
|
||||
func (c *openstackCloud) ListLBs(opt loadbalancers.ListOptsBuilder) ([]loadbalancers.LoadBalancer, error) {
|
||||
var lbs []loadbalancers.LoadBalancer
|
||||
|
||||
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
|
||||
allPages, err := loadbalancers.List(c.lbClient, opt).AllPages()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to list loadbalancers: %s", err)
|
||||
}
|
||||
r, err := loadbalancers.ExtractLoadBalancers(allPages)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to extract loadbalancer pages: %s", err)
|
||||
}
|
||||
lbs = r
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
return lbs, err
|
||||
} else if done {
|
||||
return lbs, nil
|
||||
} else {
|
||||
return lbs, wait.ErrWaitTimeout
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,13 @@ go_library(
|
|||
name = "go_default_library",
|
||||
srcs = [
|
||||
"instance.go",
|
||||
"instance_fitask.go",
|
||||
"lb.go",
|
||||
"lb_fitask.go",
|
||||
"network.go",
|
||||
"network_fitask.go",
|
||||
"port.go",
|
||||
"port_fitask.go",
|
||||
"router.go",
|
||||
"router_fitask.go",
|
||||
"routerinterface.go",
|
||||
|
@ -13,6 +18,8 @@ go_library(
|
|||
"securitygroup.go",
|
||||
"securitygroup_fitask.go",
|
||||
"securitygrouprule.go",
|
||||
"servergroup.go",
|
||||
"servergroup_fitask.go",
|
||||
"sshkey.go",
|
||||
"sshkey_fitask.go",
|
||||
"subnet.go",
|
||||
|
@ -30,6 +37,11 @@ go_library(
|
|||
"//vendor/github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/listeners:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules:go_default_library",
|
||||
|
|
|
@ -16,7 +16,116 @@ limitations under the License.
|
|||
|
||||
package openstacktasks
|
||||
|
||||
import "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
// TODO(lmb): Remove after implementing. Using this to pull in the vendor dep.
|
||||
var _ schedulerhints.SchedulerHints
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
//go:generate fitask -type=Instance
|
||||
type Instance struct {
|
||||
ID *string
|
||||
Name *string
|
||||
Port *Port
|
||||
Region *string
|
||||
Flavor *string
|
||||
Image *string
|
||||
SSHKey *string
|
||||
Tags []string
|
||||
Count int
|
||||
Role *string
|
||||
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.CompareWithID = &Instance{}
|
||||
|
||||
func (e *Instance) CompareWithID() *string {
|
||||
return e.ID
|
||||
}
|
||||
|
||||
func (e *Instance) Find(c *fi.Context) (*Instance, error) {
|
||||
if e == nil || e.ID == nil {
|
||||
return nil, nil
|
||||
}
|
||||
id := *(e.ID)
|
||||
v, err := servers.Get(c.Cloud.(openstack.OpenstackCloud).ComputeClient(), id).Extract()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error finding server with id %s: %v", id, err)
|
||||
}
|
||||
|
||||
a := new(Instance)
|
||||
a.ID = fi.String(v.ID)
|
||||
a.Name = fi.String(v.Name)
|
||||
a.SSHKey = fi.String(v.KeyName)
|
||||
a.Lifecycle = e.Lifecycle
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (e *Instance) Run(c *fi.Context) error {
|
||||
return fi.DefaultDeltaRunMethod(e, c)
|
||||
}
|
||||
|
||||
func (_ *Instance) CheckChanges(a, e, changes *Instance) error {
|
||||
if a == nil {
|
||||
if e.Name == nil {
|
||||
return fi.RequiredField("Name")
|
||||
}
|
||||
} else {
|
||||
if changes.ID != nil {
|
||||
return fi.CannotChangeField("ID")
|
||||
}
|
||||
if changes.Name != nil {
|
||||
return fi.CannotChangeField("Name")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Instance) ShouldCreate(a, e, changes *Instance) (bool, error) {
|
||||
return a == nil, nil
|
||||
}
|
||||
|
||||
func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *Instance) error {
|
||||
if a == nil {
|
||||
glog.V(2).Infof("Creating Instance with name: %q", fi.StringValue(e.Name))
|
||||
|
||||
opt := servers.CreateOpts{
|
||||
Name: fi.StringValue(e.Name),
|
||||
ImageName: fi.StringValue(e.Image),
|
||||
FlavorName: fi.StringValue(e.Flavor),
|
||||
Networks: []servers.Network{
|
||||
{
|
||||
Port: fi.StringValue(e.Port.ID),
|
||||
},
|
||||
},
|
||||
}
|
||||
keyext := keypairs.CreateOptsExt{
|
||||
CreateOptsBuilder: opt,
|
||||
KeyName: fi.StringValue(e.SSHKey),
|
||||
}
|
||||
sgext := schedulerhints.CreateOptsExt{
|
||||
CreateOptsBuilder: keyext,
|
||||
SchedulerHints: &schedulerhints.SchedulerHints{
|
||||
Group: fi.StringValue(e.Role),
|
||||
},
|
||||
}
|
||||
v, err := t.Cloud.CreateInstance(sgext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating instance: %v", err)
|
||||
}
|
||||
|
||||
e.ID = fi.String(v.ID)
|
||||
glog.V(2).Infof("Creating a new Openstack instance, id=%s", v.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Openstack task Instance::RenderOpenstack did nothing")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// Code generated by ""fitask" -type=Instance"; DO NOT EDIT
|
||||
|
||||
package openstacktasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
// Instance
|
||||
|
||||
// JSON marshalling boilerplate
|
||||
type realInstance Instance
|
||||
|
||||
// UnmarshalJSON implements conversion to JSON, supporting an alternate specification of the object as a string
|
||||
func (o *Instance) UnmarshalJSON(data []byte) error {
|
||||
var jsonName string
|
||||
if err := json.Unmarshal(data, &jsonName); err == nil {
|
||||
o.Name = &jsonName
|
||||
return nil
|
||||
}
|
||||
|
||||
var r realInstance
|
||||
if err := json.Unmarshal(data, &r); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = Instance(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ fi.HasLifecycle = &Instance{}
|
||||
|
||||
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||
func (o *Instance) GetLifecycle() *fi.Lifecycle {
|
||||
return o.Lifecycle
|
||||
}
|
||||
|
||||
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||
func (o *Instance) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||
o.Lifecycle = &lifecycle
|
||||
}
|
||||
|
||||
var _ fi.HasName = &Instance{}
|
||||
|
||||
// GetName returns the Name of the object, implementing fi.HasName
|
||||
func (o *Instance) GetName() *string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// SetName sets the Name of the object, implementing fi.SetName
|
||||
func (o *Instance) SetName(name string) {
|
||||
o.Name = &name
|
||||
}
|
||||
|
||||
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||
func (o *Instance) String() string {
|
||||
return fi.TaskAsString(o)
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Copyright 2017 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 openstacktasks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/listeners"
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
|
||||
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/pools"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
//go:generate fitask -type=LB
|
||||
type LB struct {
|
||||
ID *string
|
||||
Name *string
|
||||
Subnet *Subnet
|
||||
Listeners []listeners.Listener
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.CompareWithID = &LB{}
|
||||
|
||||
func (s *LB) CompareWithID() *string {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *LB) Find(context *fi.Context) (*LB, error) {
|
||||
if s.ID == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
cloud := context.Cloud.(openstack.OpenstackCloud)
|
||||
lb, err := loadbalancers.Get(cloud.LoadBalancerClient(), fi.StringValue(s.ID)).Extract()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sub, err := subnets.Get(cloud.NetworkingClient(), fi.StringValue(s.Subnet.ID)).Extract()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
a := &LB{
|
||||
ID: fi.String(lb.ID),
|
||||
Name: fi.String(lb.Name),
|
||||
Listeners: lb.Listeners,
|
||||
Lifecycle: s.Lifecycle,
|
||||
Subnet: &Subnet{
|
||||
ID: fi.String(sub.ID),
|
||||
Name: fi.String(sub.Name),
|
||||
CIDR: fi.String(sub.CIDR),
|
||||
Network: &Network{
|
||||
ID: fi.String(sub.NetworkID),
|
||||
Lifecycle: s.Lifecycle,
|
||||
},
|
||||
Lifecycle: s.Lifecycle,
|
||||
},
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (s *LB) Run(context *fi.Context) error {
|
||||
return fi.DefaultDeltaRunMethod(s, context)
|
||||
}
|
||||
|
||||
func (_ *LB) CheckChanges(a, e, changes *LB) error {
|
||||
if a == nil {
|
||||
if e.Name == nil {
|
||||
return fi.RequiredField("Name")
|
||||
}
|
||||
} else {
|
||||
if changes.ID != nil {
|
||||
return fi.CannotChangeField("ID")
|
||||
}
|
||||
if changes.Name != nil {
|
||||
return fi.CannotChangeField("Name")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *LB) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *LB) error {
|
||||
if a == nil {
|
||||
glog.V(2).Infof("Creating LB with Name: %q", fi.StringValue(e.Name))
|
||||
|
||||
var vipsubid string
|
||||
if subid := fi.StringValue(e.Subnet.ID); subid != "" {
|
||||
vipsubid = subid
|
||||
} else {
|
||||
subid, err := subnets.IDFromName(t.Cloud.NetworkingClient(), fi.StringValue(e.Subnet.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vipsubid = subid
|
||||
}
|
||||
|
||||
lbopts := loadbalancers.CreateOpts{
|
||||
Name: fi.StringValue(e.Name),
|
||||
VipSubnetID: vipsubid,
|
||||
}
|
||||
lb, err := t.Cloud.CreateLB(lbopts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating LB: %v", err)
|
||||
}
|
||||
e.ID = fi.String(lb.ID)
|
||||
|
||||
poolopts := pools.CreateOpts{
|
||||
Name: lb.Name + "-https",
|
||||
LBMethod: pools.LBMethodRoundRobin,
|
||||
Protocol: pools.ProtocolTCP,
|
||||
LoadbalancerID: lb.ID,
|
||||
}
|
||||
pool, err := pools.Create(t.Cloud.LoadBalancerClient(), poolopts).Extract()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating LB pool: %v", err)
|
||||
}
|
||||
|
||||
listeneropts := listeners.CreateOpts{
|
||||
Name: lb.Name + "-https",
|
||||
DefaultPoolID: pool.ID,
|
||||
LoadbalancerID: lb.ID,
|
||||
Protocol: listeners.ProtocolTCP,
|
||||
ProtocolPort: 443,
|
||||
}
|
||||
_, err = listeners.Create(t.Cloud.LoadBalancerClient(), listeneropts).Extract()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating LB listener: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Openstack task LB::RenderOpenstack did nothing")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// Code generated by ""fitask" -type=LB"; DO NOT EDIT
|
||||
|
||||
package openstacktasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
// LB
|
||||
|
||||
// JSON marshalling boilerplate
|
||||
type realLB LB
|
||||
|
||||
// UnmarshalJSON implements conversion to JSON, supporting an alternate specification of the object as a string
|
||||
func (o *LB) UnmarshalJSON(data []byte) error {
|
||||
var jsonName string
|
||||
if err := json.Unmarshal(data, &jsonName); err == nil {
|
||||
o.Name = &jsonName
|
||||
return nil
|
||||
}
|
||||
|
||||
var r realLB
|
||||
if err := json.Unmarshal(data, &r); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = LB(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ fi.HasLifecycle = &LB{}
|
||||
|
||||
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||
func (o *LB) GetLifecycle() *fi.Lifecycle {
|
||||
return o.Lifecycle
|
||||
}
|
||||
|
||||
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||
func (o *LB) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||
o.Lifecycle = &lifecycle
|
||||
}
|
||||
|
||||
var _ fi.HasName = &LB{}
|
||||
|
||||
// GetName returns the Name of the object, implementing fi.HasName
|
||||
func (o *LB) GetName() *string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// SetName sets the Name of the object, implementing fi.SetName
|
||||
func (o *LB) SetName(name string) {
|
||||
o.Name = &name
|
||||
}
|
||||
|
||||
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||
func (o *LB) String() string {
|
||||
return fi.TaskAsString(o)
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright 2018 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 openstacktasks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
//go:generate fitask -type=Port
|
||||
type Port struct {
|
||||
ID *string
|
||||
Name *string
|
||||
Network *Network
|
||||
SecurityGroups []SecurityGroup
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.CompareWithID = &Port{}
|
||||
|
||||
func (s *Port) CompareWithID() *string {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *Port) Find(context *fi.Context) (*Port, error) {
|
||||
cloud := context.Cloud.(openstack.OpenstackCloud)
|
||||
opt := ports.ListOpts{
|
||||
Name: fi.StringValue(s.Name),
|
||||
}
|
||||
rs, err := cloud.ListPorts(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rs == nil {
|
||||
return nil, nil
|
||||
} else if len(rs) != 1 {
|
||||
return nil, fmt.Errorf("found multiple ports with name: %s", fi.StringValue(s.Name))
|
||||
}
|
||||
v := rs[0]
|
||||
|
||||
sgs := make([]SecurityGroup, len(v.SecurityGroups))
|
||||
for i, sgid := range v.SecurityGroups {
|
||||
sgs[i] = SecurityGroup{
|
||||
ID: fi.String(sgid),
|
||||
Lifecycle: s.Lifecycle,
|
||||
}
|
||||
}
|
||||
|
||||
actual := &Port{
|
||||
ID: fi.String(v.ID),
|
||||
Name: fi.String(v.Name),
|
||||
Network: &Network{ID: fi.String(v.NetworkID)},
|
||||
SecurityGroups: sgs,
|
||||
Lifecycle: s.Lifecycle,
|
||||
}
|
||||
return actual, nil
|
||||
}
|
||||
|
||||
func (s *Port) Run(context *fi.Context) error {
|
||||
return fi.DefaultDeltaRunMethod(s, context)
|
||||
}
|
||||
|
||||
func (_ *Port) CheckChanges(a, e, changes *Port) error {
|
||||
if a == nil {
|
||||
if e.Name == nil {
|
||||
return fi.RequiredField("Name")
|
||||
}
|
||||
if e.Network == nil {
|
||||
return fi.RequiredField("Network")
|
||||
}
|
||||
} else {
|
||||
if changes.Name != nil {
|
||||
return fi.CannotChangeField("Name")
|
||||
}
|
||||
if e.Network != nil {
|
||||
return fi.CannotChangeField("Network")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Port) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *Port) error {
|
||||
if a == nil {
|
||||
glog.V(2).Infof("Creating Port with name: %q", fi.StringValue(e.Name))
|
||||
|
||||
sgs := make([]string, len(e.SecurityGroups))
|
||||
for i, sg := range e.SecurityGroups {
|
||||
sgs[i] = fi.StringValue(sg.ID)
|
||||
}
|
||||
|
||||
opt := ports.CreateOpts{
|
||||
Name: fi.StringValue(e.Name),
|
||||
NetworkID: fi.StringValue(e.Network.ID),
|
||||
SecurityGroups: &sgs,
|
||||
}
|
||||
|
||||
v, err := t.Cloud.CreatePort(opt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating port: %v", err)
|
||||
}
|
||||
|
||||
e.ID = fi.String(v.ID)
|
||||
glog.V(2).Infof("Creating a new Openstack port, id=%s", v.ID)
|
||||
return nil
|
||||
}
|
||||
e.ID = a.ID
|
||||
glog.V(2).Infof("Using an existing Openstack port, id=%s", fi.StringValue(e.ID))
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// Code generated by ""fitask" -type=Port"; DO NOT EDIT
|
||||
|
||||
package openstacktasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
// Port
|
||||
|
||||
// JSON marshalling boilerplate
|
||||
type realPort Port
|
||||
|
||||
// UnmarshalJSON implements conversion to JSON, supporting an alternate specification of the object as a string
|
||||
func (o *Port) UnmarshalJSON(data []byte) error {
|
||||
var jsonName string
|
||||
if err := json.Unmarshal(data, &jsonName); err == nil {
|
||||
o.Name = &jsonName
|
||||
return nil
|
||||
}
|
||||
|
||||
var r realPort
|
||||
if err := json.Unmarshal(data, &r); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = Port(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ fi.HasLifecycle = &Port{}
|
||||
|
||||
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||
func (o *Port) GetLifecycle() *fi.Lifecycle {
|
||||
return o.Lifecycle
|
||||
}
|
||||
|
||||
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||
func (o *Port) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||
o.Lifecycle = &lifecycle
|
||||
}
|
||||
|
||||
var _ fi.HasName = &Port{}
|
||||
|
||||
// GetName returns the Name of the object, implementing fi.HasName
|
||||
func (o *Port) GetName() *string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// SetName sets the Name of the object, implementing fi.SetName
|
||||
func (o *Port) SetName(name string) {
|
||||
o.Name = &name
|
||||
}
|
||||
|
||||
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||
func (o *Port) String() string {
|
||||
return fi.TaskAsString(o)
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2017 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 openstacktasks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
||||
//go:generate fitask -type=ServerGroup
|
||||
type ServerGroup struct {
|
||||
ID *string
|
||||
Name *string
|
||||
Members []string
|
||||
Policies []string
|
||||
Lifecycle *fi.Lifecycle
|
||||
}
|
||||
|
||||
var _ fi.CompareWithID = &ServerGroup{}
|
||||
|
||||
func (s *ServerGroup) CompareWithID() *string {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *ServerGroup) Find(context *fi.Context) (*ServerGroup, error) {
|
||||
if s == nil || s.ID == nil {
|
||||
return nil, nil
|
||||
}
|
||||
id := *(s.ID)
|
||||
cloud := context.Cloud.(openstack.OpenstackCloud)
|
||||
g, err := servergroups.Get(cloud.ComputeClient(), id).Extract()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
a := &ServerGroup{
|
||||
ID: fi.String(g.ID),
|
||||
Name: fi.String(g.Name),
|
||||
Members: g.Members,
|
||||
Policies: g.Policies,
|
||||
Lifecycle: s.Lifecycle,
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (s *ServerGroup) Run(context *fi.Context) error {
|
||||
return fi.DefaultDeltaRunMethod(s, context)
|
||||
}
|
||||
|
||||
func (_ *ServerGroup) CheckChanges(a, e, changes *ServerGroup) error {
|
||||
if a == nil {
|
||||
if e.Name == nil {
|
||||
return fi.RequiredField("Name")
|
||||
}
|
||||
} else {
|
||||
if changes.ID != nil {
|
||||
return fi.CannotChangeField("ID")
|
||||
}
|
||||
if changes.Name != nil {
|
||||
return fi.CannotChangeField("Name")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *ServerGroup) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *ServerGroup) error {
|
||||
if a == nil {
|
||||
glog.V(2).Infof("Creating ServerGroup with Name:%q", fi.StringValue(e.Name))
|
||||
|
||||
opt := servergroups.CreateOpts{
|
||||
Name: fi.StringValue(e.Name),
|
||||
Policies: e.Policies,
|
||||
}
|
||||
|
||||
g, err := t.Cloud.CreateServerGroup(opt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating ServerGroup: %v", err)
|
||||
}
|
||||
|
||||
e.ID = fi.String(g.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
glog.V(2).Infof("Openstack task ServerGroup::RenderOpenstack did nothing")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// Code generated by ""fitask" -type=ServerGroup"; DO NOT EDIT
|
||||
|
||||
package openstacktasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
// ServerGroup
|
||||
|
||||
// JSON marshalling boilerplate
|
||||
type realServerGroup ServerGroup
|
||||
|
||||
// UnmarshalJSON implements conversion to JSON, supporting an alternate specification of the object as a string
|
||||
func (o *ServerGroup) UnmarshalJSON(data []byte) error {
|
||||
var jsonName string
|
||||
if err := json.Unmarshal(data, &jsonName); err == nil {
|
||||
o.Name = &jsonName
|
||||
return nil
|
||||
}
|
||||
|
||||
var r realServerGroup
|
||||
if err := json.Unmarshal(data, &r); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = ServerGroup(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ fi.HasLifecycle = &ServerGroup{}
|
||||
|
||||
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||
func (o *ServerGroup) GetLifecycle() *fi.Lifecycle {
|
||||
return o.Lifecycle
|
||||
}
|
||||
|
||||
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||
func (o *ServerGroup) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||
o.Lifecycle = &lifecycle
|
||||
}
|
||||
|
||||
var _ fi.HasName = &ServerGroup{}
|
||||
|
||||
// GetName returns the Name of the object, implementing fi.HasName
|
||||
func (o *ServerGroup) GetName() *string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// SetName sets the Name of the object, implementing fi.SetName
|
||||
func (o *ServerGroup) SetName(name string) {
|
||||
o.Name = &name
|
||||
}
|
||||
|
||||
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||
func (o *ServerGroup) String() string {
|
||||
return fi.TaskAsString(o)
|
||||
}
|
|
@ -20,7 +20,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
cinder "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||
cinderv2 "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
)
|
||||
|
@ -44,9 +44,9 @@ func (c *Volume) CompareWithID() *string {
|
|||
|
||||
func (c *Volume) Find(context *fi.Context) (*Volume, error) {
|
||||
cloud := context.Cloud.(openstack.OpenstackCloud)
|
||||
opt := cinder.ListOpts{
|
||||
opt := cinderv2.ListOpts{
|
||||
Name: fi.StringValue(c.Name),
|
||||
Metadata: cloud.GetCloudTags(),
|
||||
Metadata: c.Tags,
|
||||
}
|
||||
volumes, err := cloud.ListVolumes(opt)
|
||||
if err != nil {
|
||||
|
@ -115,7 +115,7 @@ func (_ *Volume) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes
|
|||
if a == nil {
|
||||
glog.V(2).Infof("Creating PersistentVolume with Name:%q", fi.StringValue(e.Name))
|
||||
|
||||
opt := cinder.CreateOpts{
|
||||
opt := cinderv2.CreateOpts{
|
||||
Size: int(*e.SizeGB),
|
||||
AvailabilityZone: fi.StringValue(e.AvailabilityZone),
|
||||
Metadata: e.Tags,
|
||||
|
|
|
@ -18,9 +18,11 @@ package vfs
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
@ -47,16 +49,32 @@ func NewSwiftClient() (*gophercloud.ServiceClient, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider, err := openstack.AuthenticatedClient(authOption)
|
||||
|
||||
pc, err := openstack.NewClient(authOption.IdentityEndpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack provider client: %v", err)
|
||||
}
|
||||
|
||||
tlsconfig := &tls.Config{}
|
||||
tlsconfig.InsecureSkipVerify = true
|
||||
transport := &http.Transport{TLSClientConfig: tlsconfig}
|
||||
pc.HTTPClient = http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
glog.V(2).Info("authenticating to keystone")
|
||||
|
||||
err = openstack.Authenticate(pc, authOption)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building openstack authenticated client: %v", err)
|
||||
}
|
||||
|
||||
endpointOpt, err := config.GetServiceConfig("Swift")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := openstack.NewObjectStorageV1(provider, endpointOpt)
|
||||
client, err := openstack.NewObjectStorageV1(pc, endpointOpt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building swift client: %v", err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue