Skip to content

Commit

Permalink
Merge pull request #9739 from olemarkus/openstack-floatingip-test
Browse files Browse the repository at this point in the history
Add an integration test for openstack floating ip
  • Loading branch information
k8s-ci-robot authored Aug 12, 2020
2 parents fefe747 + 9890839 commit c10d6c4
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 10 deletions.
2 changes: 2 additions & 0 deletions cloudmock/openstack/mocknetworking/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"api.go",
"floatingips.go",
"networks.go",
"ports.go",
"routers.go",
Expand All @@ -16,6 +17,7 @@ go_library(
deps = [
"//cloudmock/openstack:go_default_library",
"//vendor/github.com/google/uuid:go_default_library",
"//vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips: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",
Expand Down
8 changes: 8 additions & 0 deletions cloudmock/openstack/mocknetworking/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"net/http/httptest"
"sync"

"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"

"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
Expand All @@ -40,6 +42,7 @@ type MockClient struct {
securityGroups map[string]groups.SecGroup
securityGroupRules map[string]rules.SecGroupRule
subnets map[string]subnets.Subnet
floatingips map[string]floatingips.FloatingIP
}

// CreateClient will create a new mock networking client
Expand All @@ -53,6 +56,7 @@ func CreateClient() *MockClient {
m.mockSecurityGroups()
m.mockSecurityGroupRules()
m.mockSubnets()
m.mockFloatingIPs()
m.Server = httptest.NewServer(m.Mux)
return m
}
Expand All @@ -66,6 +70,7 @@ func (m *MockClient) Reset() {
m.securityGroups = make(map[string]groups.SecGroup)
m.securityGroupRules = make(map[string]rules.SecGroupRule)
m.subnets = make(map[string]subnets.Subnet)
m.floatingips = make(map[string]floatingips.FloatingIP)
}

// All returns a map of all resource IDs to their resources
Expand All @@ -92,5 +97,8 @@ func (m *MockClient) All() map[string]interface{} {
for id, s := range m.subnets {
all[id] = s
}
for id, s := range m.floatingips {
all[id] = s
}
return all
}
76 changes: 76 additions & 0 deletions cloudmock/openstack/mocknetworking/floatingips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2020 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 mocknetworking

import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"regexp"

"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
)

type floatingIPListResponse struct {
FloatingIPs []floatingips.FloatingIP `json:"floatingips"`
}

func (m *MockClient) mockFloatingIPs() {
re := regexp.MustCompile(`/floatingips/?`)

handler := func(w http.ResponseWriter, r *http.Request) {
m.mutex.Lock()
defer m.mutex.Unlock()

w.Header().Add("Content-Type", "application/json")

floatingIPID := re.ReplaceAllString(r.URL.Path, "")
switch r.Method {
case http.MethodGet:
if floatingIPID == "" {
r.ParseForm()
m.listFloatingIPs(w, r.Form)
}
default:
w.WriteHeader(http.StatusBadRequest)
}
}
m.Mux.HandleFunc("/floatingips/", handler)
m.Mux.HandleFunc("/floatingips", handler)
}

func (m *MockClient) listFloatingIPs(w http.ResponseWriter, vals url.Values) {

w.WriteHeader(http.StatusOK)

floatingips := make([]floatingips.FloatingIP, 0)
for _, p := range m.floatingips {
floatingips = append(floatingips, p)
}
resp := floatingIPListResponse{
FloatingIPs: floatingips,
}
respB, err := json.Marshal(resp)
if err != nil {
panic(fmt.Sprintf("failed to marshal %+v", resp))
}
_, err = w.Write(respB)
if err != nil {
panic("failed to write body")
}
}
13 changes: 13 additions & 0 deletions cloudmock/openstack/mocknetworking/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,22 @@ func (m *MockClient) listPorts(w http.ResponseWriter, vals url.Values) {

ports := make([]ports.Port, 0)
nameFilter := vals.Get("name")
idFilter := vals.Get("id")
networkFilter := vals.Get("network_id")
deviceFilter := vals.Get("device_id")
for _, p := range m.ports {
if nameFilter != "" && nameFilter != p.Name {
continue
}
if deviceFilter != "" && deviceFilter != p.DeviceID {
continue
}
if networkFilter != "" && networkFilter != p.NetworkID {
continue
}
if idFilter != "" && idFilter != p.ID {
continue
}
ports = append(ports, p)
}

Expand Down Expand Up @@ -152,6 +164,7 @@ func (m *MockClient) createPort(w http.ResponseWriter, r *http.Request) {
Name: create.Port.Name,
NetworkID: create.Port.NetworkID,
SecurityGroups: *create.Port.SecurityGroups,
DeviceID: create.Port.DeviceID,
FixedIPs: fixedIPs,
}
m.ports[p.ID] = p
Expand Down
22 changes: 21 additions & 1 deletion cloudmock/openstack/mocknetworking/routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"regexp"
"strings"

"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"

"github.com/google/uuid"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers"
)
Expand Down Expand Up @@ -78,10 +80,14 @@ func (m *MockClient) listRouters(w http.ResponseWriter, vals url.Values) {

routers := make([]routers.Router, 0)
nameFilter := vals.Get("name")
idFilter := vals.Get("id")
for _, r := range m.routers {
if nameFilter != "" && r.Name != nameFilter {
continue
}
if idFilter != "" && r.ID != idFilter {
continue
}
routers = append(routers, r)
}

Expand Down Expand Up @@ -177,11 +183,25 @@ func (m *MockClient) routerInterface(w http.ResponseWriter, r *http.Request) {
panic("error decoding create router interface request")
}
if parts[2] == "add_router_interface" {
subnet := m.subnets[createInterface.SubnetID]
interfaces := m.routerInterfaces[routerID]
interfaces = append(interfaces, routers.InterfaceInfo{
SubnetID: createInterface.SubnetID,
SubnetID: subnet.ID,
})
m.routerInterfaces[routerID] = interfaces
// If PortID is not sent, this creates a new port.

port := ports.Port{
ID: uuid.New().String(),
NetworkID: subnet.NetworkID,
DeviceID: routerID,
FixedIPs: []ports.IP{
{
SubnetID: subnet.ID,
},
},
}
m.ports[port.ID] = port
} else if parts[2] == "remove_router_interface" {
interfaces := make([]routers.InterfaceInfo, 0)
for _, i := range m.routerInterfaces[routerID] {
Expand Down
8 changes: 8 additions & 0 deletions cmd/kops/lifecycle_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ func TestLifecycleMinimalOpenstack(t *testing.T) {
})
}

func TestLifecycleFloatingIPOpenstack(t *testing.T) {
runLifecycleTestOpenstack(&LifecycleTestOptions{
t: t,
SrcDir: "openstack_floatingip",
ClusterName: "floatingip-openstack.k8s.local",
})
}

// TestLifecyclePrivateCalico runs the test on a private topology
func TestLifecyclePrivateCalico(t *testing.T) {
runLifecycleTestAWS(&LifecycleTestOptions{
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/kops/validation/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
)

func openstackValidateCluster(c *kops.Cluster) (errList field.ErrorList) {
if c.Spec.CloudConfig == nil || c.Spec.CloudConfig.Openstack == nil {
return errList
}
if c.Spec.CloudConfig.Openstack.Router == nil || c.Spec.CloudConfig.Openstack.Router.ExternalNetwork == nil {
topology := c.Spec.Topology
if topology == nil || topology.Nodes == kops.TopologyPublic {
Expand Down
1 change: 1 addition & 0 deletions pkg/resources/openstack/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ go_library(
importpath = "k8s.io/kops/pkg/resources/openstack",
visibility = ["//visibility:public"],
deps = [
"//pkg/dns:go_default_library",
"//pkg/resources:go_default_library",
"//upup/pkg/fi:go_default_library",
"//upup/pkg/fi/cloudup/openstack:go_default_library",
Expand Down
13 changes: 8 additions & 5 deletions pkg/resources/openstack/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package openstack
import (
"fmt"

"k8s.io/kops/pkg/dns"

"github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets"
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
"k8s.io/kops/pkg/resources"
Expand All @@ -31,15 +33,16 @@ const (
)

func (os *clusterDiscoveryOS) ListDNSRecordsets() ([]*resources.Resource, error) {
zopts := zones.ListOpts{
Name: os.clusterName,
}

// if dnsclient does not exist (designate disabled)
if os.osCloud.DNSClient() == nil {
// if dnsclient does not exist (designate disabled) or using gossip DNS
if os.osCloud.DNSClient() == nil || dns.IsGossipHostname(os.clusterName) {
return nil, nil
}

zopts := zones.ListOpts{
Name: os.clusterName,
}

zs, err := os.osCloud.ListDNSZones(zopts)
if err != nil {
return nil, fmt.Errorf("failed to list dns zones: %s", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ spec:
authorization:
alwaysAllow: {}
channel: stable
cloudConfig:
openstack: {}
cloudProvider: openstack
configBase: memfs://tests/minimal-openstack.k8s.local
etcdClusters:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCtWu40XQo8dczLsCq0OWV+hxm9uV3WxeH9Kgh4sMzQxNtoU1pvW0XdjpkBesRKGoolfWeCLXWxpyQb1IaiMkKoz7MdhQ/6UKjMjP66aFWWp3pwD0uj0HuJ7tq4gKHKRYGTaZIRWpzUiANBrjugVgA+Sd7E/mYwc/DMXkIyRZbvhQ==
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
creationTimestamp: "2017-01-01T00:00:00Z"
name: floatingip-openstack.k8s.local
spec:
api:
dns: {}
authorization:
alwaysAllow: {}
channel: stable
cloudConfig:
openstack:
router:
externalNetwork: external
cloudProvider: openstack
configBase: memfs://tests/floatingip-openstack.k8s.local
etcdClusters:
- etcdMembers:
- instanceGroup: master-us-test1-a
name: "1"
volumeType: test
name: main
- etcdMembers:
- instanceGroup: master-us-test1-a
name: "1"
volumeType: test
name: events
openstackServiceAccount: default
iam:
legacy: false
kubelet:
anonymousAuth: false
kubernetesApiAccess:
- 0.0.0.0/0
kubernetesVersion: v1.16.0
masterPublicName: api.floatingip-openstack.k8s.local
networking:
kubenet: {}
networkCIDR: 192.168.0.0/16
nonMasqueradeCIDR: 100.64.0.0/10
project: testproject
sshAccess:
- 0.0.0.0/0
subnets:
- name: us-test1
region: us-test1
type: Public
topology:
dns:
type: Private
masters: private
nodes: private

---

apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2017-01-01T00:00:00Z"
labels:
kops.k8s.io/cluster: floatingip-openstack.k8s.local
name: master-us-test1-a
spec:
image: Ubuntu-20.04
machineType: n1-standard-1
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test1
zones:
- us-test1-a

---

apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2017-01-01T00:00:00Z"
labels:
kops.k8s.io/cluster: floatingip-openstack.k8s.local
name: nodes
spec:
image: Ubuntu-20.04
machineType: n1-standard-2
maxSize: 2
minSize: 2
role: Node
subnets:
- us-test1
zones:
- us-test1-a
Loading

0 comments on commit c10d6c4

Please sign in to comment.