Merge branch 'master' into sshkey

This commit is contained in:
Justin Santa Barbara 2018-06-11 11:23:28 -04:00 committed by GitHub
commit 89dc7b22f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1007 additions and 5 deletions

View File

@ -177,7 +177,7 @@ spec:
You could use the [fileAssets](https://github.com/kubernetes/kops/blob/master/docs/cluster_spec.md#fileassets) feature to push an advanced audit policy file on the master nodes.
Example policy file can be found [here]( https://raw.githubusercontent.com/kubernetes/website/master/docs/tasks/debug-application-cluster/audit-policy.yaml)
Example policy file can be found [here](https://github.com/kubernetes/website/blob/master/content/en/docs/tasks/debug-application-cluster/audit-policy.yaml)
#### Max Requests Inflight

View File

@ -28,3 +28,11 @@ type OpenstackModelContext struct {
func (c *OpenstackModelContext) LinkToNetwork() *openstacktasks.Network {
return &openstacktasks.Network{Name: s(c.ClusterName())}
}
func (c *OpenstackModelContext) LinkToRouter(name *string) *openstacktasks.Router {
return &openstacktasks.Router{Name: name}
}
func (c *OpenstackModelContext) LinkToSubnet(name *string) *openstacktasks.Subnet {
return &openstacktasks.Subnet{Name: name}
}

View File

@ -33,6 +33,7 @@ var _ fi.ModelBuilder = &NetworkModelBuilder{}
func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
clusterName := b.ClusterName()
routerName := strings.Replace(clusterName, ".", "-", -1)
{
t := &openstacktasks.Network{
@ -46,7 +47,7 @@ func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
{
t := &openstacktasks.Router{
Name: s(strings.Replace(clusterName, ".", "-", -1)),
Name: s(routerName),
Lifecycle: b.Lifecycle,
}
@ -61,6 +62,14 @@ func (b *NetworkModelBuilder) Build(c *fi.ModelBuilderContext) error {
Lifecycle: b.Lifecycle,
}
c.AddTask(t)
t1 := &openstacktasks.RouterInterface{
Name: s("ri-" + sp.Name),
Subnet: b.LinkToSubnet(s(sp.Name)),
Router: b.LinkToRouter(s(routerName)),
Lifecycle: b.Lifecycle,
}
c.AddTask(t1)
}
return nil

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-bastionuserdata-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.bastionuserdata-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-bastionuserdata-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-bastionuserdata-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.bastionuserdata-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.bastionuserdata-example-com.id}"
}

View File

@ -34,6 +34,18 @@ output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.complex-example-com.id}"
}
output "subnet_us-test-1a-public_id" {
value = "${aws_subnet.us-test-1a-complex-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.complex-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.complex-example-com.id}"
}

View File

@ -34,6 +34,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.ha-example-com.id}"
}
output "subnet_us-test-1a-public_id" {
value = "${aws_subnet.us-test-1a-ha-example-com.id}"
}
output "subnet_us-test-1b-public_id" {
value = "${aws_subnet.us-test-1b-ha-example-com.id}"
}
output "subnet_us-test-1c-public_id" {
value = "${aws_subnet.us-test-1c-ha-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.ha-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.ha-example-com.id}"
}

View File

@ -6,6 +6,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-lifecyclephases-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.lifecyclephases-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-lifecyclephases-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-lifecyclephases-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.lifecyclephases-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.lifecyclephases-example-com.id}"
}

View File

@ -34,6 +34,18 @@ output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.minimal-141-example-com.id}"
}
output "subnet_us-test-1a-public_id" {
value = "${aws_subnet.us-test-1a-minimal-141-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.minimal-141-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.minimal-141-example-com.id}"
}

View File

@ -34,6 +34,18 @@ output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.minimal-example-com.id}"
}
output "subnet_us-test-1a-public_id" {
value = "${aws_subnet.us-test-1a-minimal-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.minimal-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.minimal-example-com.id}"
}

View File

@ -50,6 +50,14 @@ output "subnet_ids" {
value = ["subnet-12345678", "subnet-abcdef"]
}
output "subnet_us-test-1a-private_id" {
value = "subnet-12345678"
}
output "subnet_us-test-1a-utility_id" {
value = "subnet-abcdef"
}
output "vpc_id" {
value = "vpc-12345678"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privatecalico-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privatecalico-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privatecalico-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privatecalico-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privatecalico-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privatecalico-example-com.id}"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privatecanal-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privatecanal-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privatecanal-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privatecanal-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privatecanal-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privatecanal-example-com.id}"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privatedns1-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privatedns1-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privatedns1-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privatedns1-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privatedns1-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privatedns1-example-com.id}"
}

View File

@ -46,6 +46,22 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privatedns2-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privatedns2-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privatedns2-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privatedns2-example-com.id}"
}
output "vpc_id" {
value = "vpc-12345678"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privateflannel-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privateflannel-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privateflannel-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privateflannel-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privateflannel-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privateflannel-example-com.id}"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privatekopeio-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privatekopeio-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privatekopeio-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privatekopeio-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privatekopeio-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privatekopeio-example-com.id}"
}

View File

@ -46,6 +46,26 @@ output "region" {
value = "us-test-1"
}
output "route_table_private-us-test-1a_id" {
value = "${aws_route_table.private-us-test-1a-privateweave-example-com.id}"
}
output "route_table_public_id" {
value = "${aws_route_table.privateweave-example-com.id}"
}
output "subnet_us-test-1a-private_id" {
value = "${aws_subnet.us-test-1a-privateweave-example-com.id}"
}
output "subnet_us-test-1a-utility_id" {
value = "${aws_subnet.utility-us-test-1a-privateweave-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.privateweave-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.privateweave-example-com.id}"
}

View File

@ -38,6 +38,10 @@ output "subnet_ids" {
value = ["subnet-12345678"]
}
output "subnet_us-test-1a-public_id" {
value = "subnet-12345678"
}
output "vpc_id" {
value = "vpc-12345678"
}

View File

@ -34,6 +34,14 @@ output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.sharedvpc-example-com.id}"
}
output "subnet_us-test-1a-public_id" {
value = "${aws_subnet.us-test-1a-sharedvpc-example-com.id}"
}
output "vpc_id" {
value = "vpc-12345678"
}

View File

@ -195,6 +195,14 @@ type terraformRouteTable struct {
}
func (_ *RouteTable) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *RouteTable) error {
// We use the role tag as a concise and stable identifier
tag := e.Tags[awsup.TagNameKopsRole]
if tag != "" {
if err := t.AddOutputVariable("route_table_"+tag+"_id", e.TerraformLink()); err != nil {
return err
}
}
tf := &terraformRouteTable{
VPCID: e.VPC.TerraformLink(),
Tags: e.Tags,

View File

@ -18,6 +18,7 @@ package awstasks
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/golang/glog"
@ -214,6 +215,17 @@ type terraformSubnet struct {
}
func (_ *Subnet) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *Subnet) error {
if fi.StringValue(e.AvailabilityZone) != "" {
name := fi.StringValue(e.AvailabilityZone)
if e.Tags["SubnetType"] != "" {
name += "-" + strings.ToLower(e.Tags["SubnetType"])
}
if err := t.AddOutputVariable("subnet_"+name+"_id", e.TerraformLink()); err != nil {
return err
}
}
shared := fi.BoolValue(e.Shared)
if shared {
// Not terraform owned / managed

View File

@ -212,6 +212,11 @@ func (_ *VPC) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *VPC)
return nil
}
if err := t.AddOutputVariable("vpc_cidr_block", terraform.LiteralProperty("aws_vpc", *e.Name, "cidr_block")); err != nil {
// TODO: Should we try to output vpc_cidr_block for shared vpcs?
return err
}
tf := &terraformVPC{
CIDR: e.CIDR,
Tags: e.Tags,

View File

@ -23,6 +23,7 @@ go_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",
"//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",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",

View File

@ -29,6 +29,7 @@ import (
sg "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
sgr "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
"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/api/core/v1"
"k8s.io/apimachinery/pkg/util/wait"
@ -115,6 +116,12 @@ type OpenstackCloud interface {
// CreateKeypair will create a new Nova Keypair
CreateKeypair(opt keypairs.CreateOptsBuilder) (*keypairs.KeyPair, error)
//ListPorts will return the Neutron ports which match the options
ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error)
//CreateRouterInterface will create a new Neutron router interface
CreateRouterInterface(routerID string, opt routers.AddInterfaceOptsBuilder) (*routers.InterfaceInfo, error)
}
type openstackCloud struct {
@ -545,5 +552,50 @@ func (c *openstackCloud) CreateKeypair(opt keypairs.CreateOptsBuilder) (*keypair
return k, nil
} else {
return k, wait.ErrWaitTimeout
}
}
func (c *openstackCloud) ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error) {
var p []ports.Port
done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
allPages, err := ports.List(c.neutronClient, opt).AllPages()
if err != nil {
return false, fmt.Errorf("error listing ports: %v", err)
}
r, err := ports.ExtractPorts(allPages)
if err != nil {
return false, fmt.Errorf("error extracting ports from pages: %v", err)
}
p = r
return true, nil
})
if err != nil {
return p, err
} else if done {
return p, nil
} else {
return p, wait.ErrWaitTimeout
}
}
func (c *openstackCloud) CreateRouterInterface(routerID string, opt routers.AddInterfaceOptsBuilder) (*routers.InterfaceInfo, error) {
var i *routers.InterfaceInfo
done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) {
v, err := routers.AddInterface(c.neutronClient, routerID, opt).Extract()
if err != nil {
return false, fmt.Errorf("error creating router interface: %v", err)
}
i = v
return true, nil
})
if err != nil {
return i, err
} else if done {
return i, nil
} else {
return i, wait.ErrWaitTimeout
}
}

View File

@ -7,6 +7,8 @@ go_library(
"network_fitask.go",
"router.go",
"router_fitask.go",
"routerinterface.go",
"routerinterface_fitask.go",
"securitygroup.go",
"securitygroup_fitask.go",
"securitygrouprule.go",
@ -30,6 +32,7 @@ go_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",
"//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",
],
)

View File

@ -0,0 +1,135 @@
/*
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/extensions/layer3/routers"
"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=RouterInterface
type RouterInterface struct {
ID *string
Name *string
Router *Router
Subnet *Subnet
Lifecycle *fi.Lifecycle
}
var _ fi.CompareWithID = &RouterInterface{}
func (i *RouterInterface) CompareWithID() *string {
return i.ID
}
func (i *RouterInterface) Find(context *fi.Context) (*RouterInterface, error) {
cloud := context.Cloud.(openstack.OpenstackCloud)
opt := ports.ListOpts{
NetworkID: fi.StringValue(i.Subnet.Network.ID),
DeviceOwner: "network:router_interface",
DeviceID: fi.StringValue(i.Router.ID),
ID: fi.StringValue(i.ID),
}
ps, err := cloud.ListPorts(opt)
if err != nil {
return nil, err
}
if ps == nil {
return nil, nil
}
subnetID := fi.StringValue(i.Subnet.ID)
iID := ""
n := 0
for _, p := range ps {
for _, ip := range p.FixedIPs {
if ip.SubnetID == subnetID {
n += 1
iID = p.ID
break
}
}
}
switch n {
case 0:
return nil, nil
case 1:
actual := &RouterInterface{
ID: fi.String(iID),
Name: i.Name,
Router: i.Router,
Subnet: i.Subnet,
Lifecycle: i.Lifecycle,
}
return actual, nil
default:
return nil, fmt.Errorf("find multiple interfaces which subnet:%s attach to", subnetID)
}
}
func (i *RouterInterface) Run(context *fi.Context) error {
return fi.DefaultDeltaRunMethod(i, context)
}
func (_ *RouterInterface) CheckChanges(a, e, changes *RouterInterface) error {
if a == nil {
if e.Router == nil {
return fi.RequiredField("Router")
}
if e.Subnet == nil {
return fi.RequiredField("Subnet")
}
} else {
if changes.Name != nil {
return fi.CannotChangeField("Name")
}
if changes.Router != nil {
return fi.CannotChangeField("Router")
}
if changes.Subnet != nil {
return fi.CannotChangeField("Subnet")
}
}
return nil
}
func (_ *RouterInterface) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *RouterInterface) error {
if a == nil {
routerID := fi.StringValue(e.Router.ID)
subnetID := fi.StringValue(e.Subnet.ID)
glog.V(2).Infof("Creating RouterInterface for router:%s and subnet:%s", routerID, subnetID)
opt := routers.AddInterfaceOpts{SubnetID: subnetID}
v, err := t.Cloud.CreateRouterInterface(routerID, opt)
if err != nil {
return fmt.Errorf("Error creating router interface: %v", err)
}
e.ID = fi.String(v.PortID)
glog.V(2).Infof("Creating a new Openstack router interface, id=%s", v.PortID)
return nil
}
e.ID = a.ID
glog.V(2).Infof("Using an existing Openstack router interface, id=%s", fi.StringValue(e.ID))
return nil
}

View File

@ -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=RouterInterface"; DO NOT EDIT
package openstacktasks
import (
"encoding/json"
"k8s.io/kops/upup/pkg/fi"
)
// RouterInterface
// JSON marshalling boilerplate
type realRouterInterface RouterInterface
// UnmarshalJSON implements conversion to JSON, supporitng an alternate specification of the object as a string
func (o *RouterInterface) UnmarshalJSON(data []byte) error {
var jsonName string
if err := json.Unmarshal(data, &jsonName); err == nil {
o.Name = &jsonName
return nil
}
var r realRouterInterface
if err := json.Unmarshal(data, &r); err != nil {
return err
}
*o = RouterInterface(r)
return nil
}
var _ fi.HasLifecycle = &RouterInterface{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *RouterInterface) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
func (o *RouterInterface) SetLifecycle(lifecycle fi.Lifecycle) {
o.Lifecycle = &lifecycle
}
var _ fi.HasName = &RouterInterface{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *RouterInterface) GetName() *string {
return o.Name
}
// SetName sets the Name of the object, implementing fi.SetName
func (o *RouterInterface) SetName(name string) {
o.Name = &name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *RouterInterface) String() string {
return fi.TaskAsString(o)
}

View File

@ -573,9 +573,13 @@ func (c *VFSCAStore) ListKeysets() ([]*kops.Keyset, error) {
keysets[name] = keyset
}
keyset.Spec.Keys = append(keyset.Spec.Keys, kops.KeysetItem{
Id: strings.TrimSuffix(tokens[1], ".crt"),
})
if tokens[1] == "keyset.yaml" {
// TODO: Should we load the keyset to get the actual ids?
} else {
keyset.Spec.Keys = append(keyset.Spec.Keys, kops.KeysetItem{
Id: strings.TrimSuffix(tokens[1], ".crt"),
})
}
}
}

View File

@ -0,0 +1,17 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"requests.go",
"results.go",
"urls.go",
],
importpath = "github.com/gophercloud/gophercloud/openstack/networking/v2/ports",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/pagination:go_default_library",
],
)

View File

@ -0,0 +1,73 @@
/*
Package ports contains functionality for working with Neutron port resources.
A port represents a virtual switch port on a logical network switch. Virtual
instances attach their interfaces into ports. The logical port also defines
the MAC address and the IP address(es) to be assigned to the interfaces
plugged into them. When IP addresses are associated to a port, this also
implies the port is associated with a subnet, as the IP address was taken
from the allocation pool for a specific subnet.
Example to List Ports
listOpts := ports.ListOpts{
DeviceID: "b0b89efe-82f8-461d-958b-adbf80f50c7d",
}
allPages, err := ports.List(networkClient, listOpts).AllPages()
if err != nil {
panic(err)
}
allPorts, err := ports.ExtractPorts(allPages)
if err != nil {
panic(err)
}
for _, port := range allPorts {
fmt.Printf("%+v\n", port)
}
Example to Create a Port
createOtps := ports.CreateOpts{
Name: "private-port",
AdminStateUp: &asu,
NetworkID: "a87cc70a-3e15-4acf-8205-9b711a3531b7",
FixedIPs: []ports.IP{
{SubnetID: "a0304c3a-4f08-4c43-88af-d796509c97d2", IPAddress: "10.0.0.2"},
},
SecurityGroups: &[]string{"foo"},
AllowedAddressPairs: []ports.AddressPair{
{IPAddress: "10.0.0.4", MACAddress: "fa:16:3e:c9:cb:f0"},
},
}
port, err := ports.Create(networkClient, createOpts).Extract()
if err != nil {
panic(err)
}
Example to Update a Port
portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8"
updateOpts := ports.UpdateOpts{
Name: "new_name",
SecurityGroups: &[]string{},
}
port, err := ports.Update(networkClient, portID, updateOpts).Extract()
if err != nil {
panic(err)
}
Example to Delete a Port
portID := "c34bae2b-7641-49b6-bf6d-d8e473620ed8"
err := ports.Delete(networkClient, portID).ExtractErr()
if err != nil {
panic(err)
}
*/
package ports

View File

@ -0,0 +1,177 @@
package ports
import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// ListOptsBuilder allows extensions to add additional parameters to the
// List request.
type ListOptsBuilder interface {
ToPortListQuery() (string, error)
}
// ListOpts allows the filtering and sorting of paginated collections through
// the API. Filtering is achieved by passing in struct field values that map to
// the port attributes you want to see returned. SortKey allows you to sort
// by a particular port attribute. SortDir sets the direction, and is either
// `asc' or `desc'. Marker and Limit are used for pagination.
type ListOpts struct {
Status string `q:"status"`
Name string `q:"name"`
AdminStateUp *bool `q:"admin_state_up"`
NetworkID string `q:"network_id"`
TenantID string `q:"tenant_id"`
DeviceOwner string `q:"device_owner"`
MACAddress string `q:"mac_address"`
ID string `q:"id"`
DeviceID string `q:"device_id"`
Limit int `q:"limit"`
Marker string `q:"marker"`
SortKey string `q:"sort_key"`
SortDir string `q:"sort_dir"`
}
// ToPortListQuery formats a ListOpts into a query string.
func (opts ListOpts) ToPortListQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}
// List returns a Pager which allows you to iterate over a collection of
// ports. It accepts a ListOpts struct, which allows you to filter and sort
// the returned collection for greater efficiency.
//
// Default policy settings return only those ports that are owned by the tenant
// who submits the request, unless the request is submitted by a user with
// administrative rights.
func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
url := listURL(c)
if opts != nil {
query, err := opts.ToPortListQuery()
if err != nil {
return pagination.Pager{Err: err}
}
url += query
}
return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
return PortPage{pagination.LinkedPageBase{PageResult: r}}
})
}
// Get retrieves a specific port based on its unique ID.
func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
_, r.Err = c.Get(getURL(c, id), &r.Body, nil)
return
}
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
type CreateOptsBuilder interface {
ToPortCreateMap() (map[string]interface{}, error)
}
// CreateOpts represents the attributes used when creating a new port.
type CreateOpts struct {
NetworkID string `json:"network_id" required:"true"`
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
MACAddress string `json:"mac_address,omitempty"`
FixedIPs interface{} `json:"fixed_ips,omitempty"`
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
SecurityGroups *[]string `json:"security_groups,omitempty"`
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs,omitempty"`
}
// ToPortCreateMap builds a request body from CreateOpts.
func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "port")
}
// Create accepts a CreateOpts struct and creates a new network using the values
// provided. You must remember to provide a NetworkID value.
func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
b, err := opts.ToPortCreateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
return
}
// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToPortUpdateMap() (map[string]interface{}, error)
}
// UpdateOpts represents the attributes used when updating an existing port.
type UpdateOpts struct {
Name string `json:"name,omitempty"`
AdminStateUp *bool `json:"admin_state_up,omitempty"`
FixedIPs interface{} `json:"fixed_ips,omitempty"`
DeviceID string `json:"device_id,omitempty"`
DeviceOwner string `json:"device_owner,omitempty"`
SecurityGroups *[]string `json:"security_groups,omitempty"`
AllowedAddressPairs *[]AddressPair `json:"allowed_address_pairs,omitempty"`
}
// ToPortUpdateMap builds a request body from UpdateOpts.
func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "port")
}
// Update accepts a UpdateOpts struct and updates an existing port using the
// values provided.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
b, err := opts.ToPortUpdateMap()
if err != nil {
r.Err = err
return
}
_, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 201},
})
return
}
// Delete accepts a unique ID and deletes the port associated with it.
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
_, r.Err = c.Delete(deleteURL(c, id), nil)
return
}
// IDFromName is a convenience function that returns a port's ID,
// given its name.
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
count := 0
id := ""
pages, err := List(client, nil).AllPages()
if err != nil {
return "", err
}
all, err := ExtractPorts(pages)
if err != nil {
return "", err
}
for _, s := range all {
if s.Name == name {
count++
id = s.ID
}
}
switch count {
case 0:
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "port"}
case 1:
return id, nil
default:
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "port"}
}
}

View File

@ -0,0 +1,140 @@
package ports
import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a port resource.
func (r commonResult) Extract() (*Port, error) {
var s Port
err := r.ExtractInto(&s)
return &s, err
}
func (r commonResult) ExtractInto(v interface{}) error {
return r.Result.ExtractIntoStructPtr(v, "port")
}
// CreateResult represents the result of a create operation. Call its Extract
// method to interpret it as a Port.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation. Call its Extract
// method to interpret it as a Port.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation. Call its Extract
// method to interpret it as a Port.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation. Call its
// ExtractErr method to determine if the request succeeded or failed.
type DeleteResult struct {
gophercloud.ErrResult
}
// IP is a sub-struct that represents an individual IP.
type IP struct {
SubnetID string `json:"subnet_id"`
IPAddress string `json:"ip_address,omitempty"`
}
// AddressPair contains the IP Address and the MAC address.
type AddressPair struct {
IPAddress string `json:"ip_address,omitempty"`
MACAddress string `json:"mac_address,omitempty"`
}
// Port represents a Neutron port. See package documentation for a top-level
// description of what this is.
type Port struct {
// UUID for the port.
ID string `json:"id"`
// Network that this port is associated with.
NetworkID string `json:"network_id"`
// Human-readable name for the port. Might not be unique.
Name string `json:"name"`
// Administrative state of port. If false (down), port does not forward
// packets.
AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional
// values.
Status string `json:"status"`
// Mac address to use on this port.
MACAddress string `json:"mac_address"`
// Specifies IP addresses for the port thus associating the port itself with
// the subnets where the IP addresses are picked from
FixedIPs []IP `json:"fixed_ips"`
// Owner of network.
TenantID string `json:"tenant_id"`
// Identifies the entity (e.g.: dhcp agent) using this port.
DeviceOwner string `json:"device_owner"`
// Specifies the IDs of any security groups associated with a port.
SecurityGroups []string `json:"security_groups"`
// Identifies the device (e.g., virtual server) using this port.
DeviceID string `json:"device_id"`
// Identifies the list of IP addresses the port will recognize/accept
AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
}
// PortPage is the page returned by a pager when traversing over a collection
// of network ports.
type PortPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of ports has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
func (r PortPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"ports_links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a PortPage struct is empty.
func (r PortPage) IsEmpty() (bool, error) {
is, err := ExtractPorts(r)
return len(is) == 0, err
}
// ExtractPorts accepts a Page struct, specifically a PortPage struct,
// and extracts the elements into a slice of Port structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPorts(r pagination.Page) ([]Port, error) {
var s []Port
err := ExtractPortsInto(r, &s)
return s, err
}
func ExtractPortsInto(r pagination.Page, v interface{}) error {
return r.(PortPage).Result.ExtractIntoSlicePtr(v, "ports")
}

View File

@ -0,0 +1,31 @@
package ports
import "github.com/gophercloud/gophercloud"
func resourceURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("ports", id)
}
func rootURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("ports")
}
func listURL(c *gophercloud.ServiceClient) string {
return rootURL(c)
}
func getURL(c *gophercloud.ServiceClient, id string) string {
return resourceURL(c, id)
}
func createURL(c *gophercloud.ServiceClient) string {
return rootURL(c)
}
func updateURL(c *gophercloud.ServiceClient, id string) string {
return resourceURL(c, id)
}
func deleteURL(c *gophercloud.ServiceClient, id string) string {
return resourceURL(c, id)
}