Add fake CRD client
Change-Id: I4748ce465b2886098cfab37277a18cc0b571c22b Implements: blueprint enhance-unit-testing Signed-off-by: mozhuli <21621232@zju.edu.cn>
This commit is contained in:
parent
23c2da8286
commit
7fed3d210b
@ -41,13 +41,13 @@ const (
|
||||
// Controller manages life cycle of namespace's rbac.
|
||||
type Controller struct {
|
||||
k8sclient *kubernetes.Clientset
|
||||
kubeCRDClient *crdClient.CRDClient
|
||||
kubeCRDClient crdClient.Interface
|
||||
userCIDR string
|
||||
userGateway string
|
||||
}
|
||||
|
||||
// NewRBACController creates a new RBAC controller.
|
||||
func NewRBACController(kubeClient *kubernetes.Clientset, kubeCRDClient *crdClient.CRDClient, userCIDR string,
|
||||
func NewRBACController(kubeClient *kubernetes.Clientset, kubeCRDClient crdClient.Interface, userCIDR string,
|
||||
userGateway string) (*Controller, error) {
|
||||
c := &Controller{
|
||||
k8sclient: kubeClient,
|
||||
|
@ -34,10 +34,10 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// TenantController manages life cycle of Tenant.
|
||||
// TenantController manages the life cycle of Tenant.
|
||||
type TenantController struct {
|
||||
k8sClient *kubernetes.Clientset
|
||||
kubeCRDClient *crdClient.CRDClient
|
||||
kubeCRDClient crdClient.Interface
|
||||
openstackClient openstack.Interface
|
||||
}
|
||||
|
||||
@ -64,16 +64,12 @@ func NewTenantController(kubeClient *kubernetes.Clientset,
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *TenantController) GetKubeCRDClient() *crdClient.CRDClient {
|
||||
return c.kubeCRDClient
|
||||
}
|
||||
|
||||
// Run the controller.
|
||||
func (c *TenantController) Run(stopCh <-chan struct{}) error {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
source := cache.NewListWatchFromClient(
|
||||
c.kubeCRDClient.Client,
|
||||
c.kubeCRDClient.Client(),
|
||||
crv1.TenantResourcePlural,
|
||||
apiv1.NamespaceAll,
|
||||
fields.Everything())
|
||||
@ -97,7 +93,7 @@ func (c *TenantController) onAdd(obj interface{}) {
|
||||
tenant := obj.(*crv1.Tenant)
|
||||
glog.V(3).Infof("Tenant controller received new object %#v\n", tenant)
|
||||
|
||||
copyObj, err := c.kubeCRDClient.Scheme.Copy(tenant)
|
||||
copyObj, err := c.kubeCRDClient.Scheme().Copy(tenant)
|
||||
if err != nil {
|
||||
glog.Errorf("ERROR creating a deep copy of tenant object: %#v\n", err)
|
||||
return
|
||||
|
@ -30,12 +30,34 @@ import (
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
type CRDClient struct {
|
||||
Client *rest.RESTClient
|
||||
Scheme *runtime.Scheme
|
||||
// Interface should be implemented by a CRD client.
|
||||
type Interface interface {
|
||||
// AddTenant adds Tenant CRD object by given object.
|
||||
AddTenant(tenant *crv1.Tenant) error
|
||||
// GetTenant returns Tenant CRD object by tenantName.
|
||||
GetTenant(tenantName string) (*crv1.Tenant, error)
|
||||
// UpdateTenant updates Tenant CRD object by given object.
|
||||
UpdateTenant(tenant *crv1.Tenant) error
|
||||
// AddNetwork adds Network CRD object by given object.
|
||||
AddNetwork(network *crv1.Network) error
|
||||
// UpdateNetwork updates Network CRD object by given object.
|
||||
UpdateNetwork(network *crv1.Network) error
|
||||
// DeleteNetwork deletes Network CRD object by networkName.
|
||||
DeleteNetwork(networkName string) error
|
||||
// Client returns the RESTClient.
|
||||
Client() *rest.RESTClient
|
||||
// Scheme returns runtime scheme.
|
||||
Scheme() *runtime.Scheme
|
||||
}
|
||||
|
||||
func NewCRDClient(cfg *rest.Config) (*CRDClient, error) {
|
||||
// CRDClient implements the Interface.
|
||||
type CRDClient struct {
|
||||
client *rest.RESTClient
|
||||
scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// NewCRDClient returns a new CRD client.
|
||||
func NewCRDClient(cfg *rest.Config) (Interface, error) {
|
||||
scheme := runtime.NewScheme()
|
||||
if err := crv1.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
@ -53,14 +75,24 @@ func NewCRDClient(cfg *rest.Config) (*CRDClient, error) {
|
||||
}
|
||||
|
||||
return &CRDClient{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
client: client,
|
||||
scheme: scheme,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateNetwork updates Network CRD object by given object
|
||||
func (c *CRDClient) UpdateNetwork(network *crv1.Network) {
|
||||
err := c.Client.Put().
|
||||
// Client returns the RESTClient.
|
||||
func (c *CRDClient) Client() *rest.RESTClient {
|
||||
return c.client
|
||||
}
|
||||
|
||||
// Scheme returns runtime scheme.
|
||||
func (c *CRDClient) Scheme() *runtime.Scheme {
|
||||
return c.scheme
|
||||
}
|
||||
|
||||
// UpdateNetwork updates Network CRD object by given object.
|
||||
func (c *CRDClient) UpdateNetwork(network *crv1.Network) error {
|
||||
err := c.client.Put().
|
||||
Name(network.Name).
|
||||
Namespace(network.Namespace).
|
||||
Resource(crv1.NetworkResourcePlural).
|
||||
@ -70,14 +102,15 @@ func (c *CRDClient) UpdateNetwork(network *crv1.Network) {
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf("ERROR updating network: %v\n", err)
|
||||
} else {
|
||||
glog.V(3).Infof("UPDATED network: %#v\n", network)
|
||||
return err
|
||||
}
|
||||
glog.V(3).Infof("UPDATED network: %#v\n", network)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateTenant updates Network CRD object by given object
|
||||
func (c *CRDClient) UpdateTenant(tenant *crv1.Tenant) {
|
||||
err := c.Client.Put().
|
||||
// UpdateTenant updates Network CRD object by given object.
|
||||
func (c *CRDClient) UpdateTenant(tenant *crv1.Tenant) error {
|
||||
err := c.client.Put().
|
||||
Name(tenant.Name).
|
||||
Namespace(util.SystemTenant).
|
||||
Resource(crv1.TenantResourcePlural).
|
||||
@ -87,17 +120,18 @@ func (c *CRDClient) UpdateTenant(tenant *crv1.Tenant) {
|
||||
|
||||
if err != nil {
|
||||
glog.Errorf("ERROR updating tenant: %v\n", err)
|
||||
} else {
|
||||
glog.V(3).Infof("UPDATED tenant: %#v\n", tenant)
|
||||
return err
|
||||
}
|
||||
glog.V(3).Infof("UPDATED tenant: %#v\n", tenant)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTenant returns tenant from CRD
|
||||
// NOTE: all tenant are stored under system namespace
|
||||
// GetTenant returns Tenant CRD object by tenantName.
|
||||
// NOTE: all tenant are stored under system namespace.
|
||||
func (c *CRDClient) GetTenant(tenantName string) (*crv1.Tenant, error) {
|
||||
tenant := crv1.Tenant{}
|
||||
// tenant always has same name and namespace
|
||||
err := c.Client.Get().
|
||||
// tenant always has the same name with namespace
|
||||
err := c.client.Get().
|
||||
Resource(crv1.TenantResourcePlural).
|
||||
Namespace(util.SystemTenant).
|
||||
Name(tenantName).
|
||||
@ -108,10 +142,10 @@ func (c *CRDClient) GetTenant(tenantName string) (*crv1.Tenant, error) {
|
||||
return &tenant, nil
|
||||
}
|
||||
|
||||
// AddTenant adds tenant to CRD
|
||||
// NOTE: all tenant are added to system namespace
|
||||
// AddTenant adds Tenant CRD object by given object.
|
||||
// NOTE: all tenant are added to system namespace.
|
||||
func (c *CRDClient) AddTenant(tenant *crv1.Tenant) error {
|
||||
err := c.Client.Post().
|
||||
err := c.client.Post().
|
||||
Namespace(util.SystemTenant).
|
||||
Resource(crv1.TenantResourcePlural).
|
||||
Body(tenant).
|
||||
@ -122,8 +156,9 @@ func (c *CRDClient) AddTenant(tenant *crv1.Tenant) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddNetwork adds Network CRD object by given object.
|
||||
func (c *CRDClient) AddNetwork(network *crv1.Network) error {
|
||||
err := c.Client.Post().
|
||||
err := c.client.Post().
|
||||
Resource(crv1.NetworkResourcePlural).
|
||||
Namespace(network.GetNamespace()).
|
||||
Body(network).
|
||||
@ -134,12 +169,13 @@ func (c *CRDClient) AddNetwork(network *crv1.Network) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CRDClient) DeleteNetwork(namespace string) error {
|
||||
// NOTE: the automatically created network for tenant use namespace as name
|
||||
err := c.Client.Delete().
|
||||
// DeleteNetwork deletes Network CRD object by networkName.
|
||||
// NOTE: the automatically created network for tenant use namespace as name.
|
||||
func (c *CRDClient) DeleteNetwork(networkName string) error {
|
||||
err := c.client.Delete().
|
||||
Resource(crv1.NetworkResourcePlural).
|
||||
Namespace(namespace).
|
||||
Name(namespace).
|
||||
Namespace(networkName).
|
||||
Name(networkName).
|
||||
Do().Error()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete Network: %v", err)
|
||||
|
245
pkg/kubecrd/crdclient_fake.go
Normal file
245
pkg/kubecrd/crdclient_fake.go
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
Copyright (c) 2017 OpenStack Foundation.
|
||||
|
||||
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 kubecrd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// CalledDetail is the struct contains called function name and arguments.
|
||||
type CalledDetail struct {
|
||||
// Name of the function called.
|
||||
Name string
|
||||
// Argument of the function called.
|
||||
Argument interface{}
|
||||
}
|
||||
|
||||
// FakeCRDClient is a simple fake CRD client, so that stackube
|
||||
// can be run for testing without requiring a real kubernetes setup.
|
||||
type FakeCRDClient struct {
|
||||
sync.Mutex
|
||||
called []CalledDetail
|
||||
errors map[string]error
|
||||
Tenants map[string]*crv1.Tenant
|
||||
Networks map[string]*crv1.Network
|
||||
scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
var _ = Interface(&FakeCRDClient{})
|
||||
|
||||
// NewFake creates a new FakeCRDClient.
|
||||
func NewFake() (*FakeCRDClient, error) {
|
||||
scheme := runtime.NewScheme()
|
||||
if err := crv1.AddToScheme(scheme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FakeCRDClient{
|
||||
errors: make(map[string]error),
|
||||
Tenants: make(map[string]*crv1.Tenant),
|
||||
Networks: make(map[string]*crv1.Network),
|
||||
scheme: scheme,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *FakeCRDClient) getError(op string) error {
|
||||
err, ok := f.errors[op]
|
||||
if ok {
|
||||
delete(f.errors, op)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InjectError inject error for call
|
||||
func (f *FakeCRDClient) InjectError(fn string, err error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.errors[fn] = err
|
||||
}
|
||||
|
||||
// InjectErrors inject errors for calls
|
||||
func (f *FakeCRDClient) InjectErrors(errs map[string]error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
for fn, err := range errs {
|
||||
f.errors[fn] = err
|
||||
}
|
||||
}
|
||||
|
||||
// ClearErrors clear errors for call
|
||||
func (f *FakeCRDClient) ClearErrors() {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.errors = make(map[string]error)
|
||||
}
|
||||
|
||||
func (f *FakeCRDClient) appendCalled(name string, argument interface{}) {
|
||||
call := CalledDetail{Name: name, Argument: argument}
|
||||
f.called = append(f.called, call)
|
||||
}
|
||||
|
||||
// GetCalledNames get names of call
|
||||
func (f *FakeCRDClient) GetCalledNames() []string {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
names := []string{}
|
||||
for _, detail := range f.called {
|
||||
names = append(names, detail.Name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// GetCalledDetails get detail of each call.
|
||||
func (f *FakeCRDClient) GetCalledDetails() []CalledDetail {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
// Copy the list and return.
|
||||
return append([]CalledDetail{}, f.called...)
|
||||
}
|
||||
|
||||
// SetTenants injects fake tenant.
|
||||
func (f *FakeCRDClient) SetTenants(tenants []*crv1.Tenant) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
for _, tenant := range tenants {
|
||||
f.Tenants[tenant.Name] = tenant
|
||||
}
|
||||
}
|
||||
|
||||
// SetNetworks injects fake network.
|
||||
func (f *FakeCRDClient) SetNetworks(networks []*crv1.Network) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
for _, network := range networks {
|
||||
f.Networks[network.Name] = network
|
||||
}
|
||||
}
|
||||
|
||||
// Client is a test implementation of Interface.Client.
|
||||
func (f *FakeCRDClient) Client() *rest.RESTClient {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scheme is a test implementation of Interface.Scheme.
|
||||
func (f *FakeCRDClient) Scheme() *runtime.Scheme {
|
||||
return f.scheme
|
||||
}
|
||||
|
||||
// AddTenant is a test implementation of Interface.AddTenant.
|
||||
func (f *FakeCRDClient) AddTenant(tenant *crv1.Tenant) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("AddTenant", tenant)
|
||||
if err := f.getError("AddTenant"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Tenants[tenant.Name]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.Tenants[tenant.Name] = tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTenant is a test implementation of Interface.GetTenant.
|
||||
func (f *FakeCRDClient) GetTenant(tenantName string) (*crv1.Tenant, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("GetTenant", tenantName)
|
||||
if err := f.getError("GetTenant"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tenant, ok := f.Tenants[tenantName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Tenant %s not found", tenantName)
|
||||
}
|
||||
|
||||
return tenant, nil
|
||||
}
|
||||
|
||||
// AddNetwork is a test implementation of Interface.AddNetwork.
|
||||
func (f *FakeCRDClient) AddNetwork(network *crv1.Network) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("AddNetwork", network)
|
||||
if err := f.getError("AddNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Networks[network.Name]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.Networks[network.Name] = network
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateTenant is a test implementation of Interface.UpdateTenant.
|
||||
func (f *FakeCRDClient) UpdateTenant(tenant *crv1.Tenant) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("UpdateTenant", tenant)
|
||||
if err := f.getError("UpdateTenant"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Tenants[tenant.Name]; !ok {
|
||||
return fmt.Errorf("Tenant %s not exist", tenant.Name)
|
||||
}
|
||||
|
||||
f.Tenants[tenant.Name] = tenant
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateNetwork is a test implementation of Interface.UpdateNetwork.
|
||||
func (f *FakeCRDClient) UpdateNetwork(network *crv1.Network) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("UpdateNetwork", network)
|
||||
if err := f.getError("UpdateNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Networks[network.Name]; !ok {
|
||||
return fmt.Errorf("Network %s not exist", network.Name)
|
||||
}
|
||||
|
||||
f.Networks[network.Name] = network
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteNetwork is a test implementation of Interface.DeleteNetwork.
|
||||
func (f *FakeCRDClient) DeleteNetwork(networkName string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("DeleteNetwork", networkName)
|
||||
if err := f.getError("DeleteNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(f.Networks, networkName)
|
||||
|
||||
return nil
|
||||
}
|
@ -48,18 +48,15 @@ const (
|
||||
defaultSideCarImage = "stackube/k8s-dns-sidecar-amd64:1.14.4"
|
||||
)
|
||||
|
||||
// Watcher is an network of watching on resource create/update/delete events
|
||||
// NetworkController manages the life cycle of Network.
|
||||
type NetworkController struct {
|
||||
k8sclient *kubernetes.Clientset
|
||||
kubeCRDClient *kubecrd.CRDClient
|
||||
kubeCRDClient kubecrd.Interface
|
||||
driver openstack.Interface
|
||||
networkInformer cache.Controller
|
||||
}
|
||||
|
||||
func (c *NetworkController) GetKubeCRDClient() *kubecrd.CRDClient {
|
||||
return c.kubeCRDClient
|
||||
}
|
||||
|
||||
// Run the network controller.
|
||||
func (c *NetworkController) Run(stopCh <-chan struct{}) error {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
@ -69,6 +66,7 @@ func (c *NetworkController) Run(stopCh <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewNetworkController creates a new NetworkController.
|
||||
func NewNetworkController(kubeClient *kubernetes.Clientset, osClient openstack.Interface, kubeExtClient *apiextensionsclient.Clientset) (*NetworkController, error) {
|
||||
// initialize CRD if it does not exist
|
||||
_, err := kubecrd.CreateNetworkCRD(kubeExtClient)
|
||||
@ -77,7 +75,7 @@ func NewNetworkController(kubeClient *kubernetes.Clientset, osClient openstack.I
|
||||
}
|
||||
|
||||
source := cache.NewListWatchFromClient(
|
||||
osClient.GetCRDClient().Client,
|
||||
osClient.GetCRDClient().Client(),
|
||||
crv1.NetworkResourcePlural,
|
||||
apiv1.NamespaceAll,
|
||||
fields.Everything())
|
||||
@ -108,7 +106,7 @@ func (c *NetworkController) onAdd(obj interface{}) {
|
||||
// NEVER modify objects from the store. It's a read-only, local cache.
|
||||
// You can use networkScheme.Copy() to make a deep copy of original object and modify this copy
|
||||
// Or create a copy manually for better performance
|
||||
copyObj, err := c.GetKubeCRDClient().Scheme.Copy(network)
|
||||
copyObj, err := c.kubeCRDClient.Scheme().Copy(network)
|
||||
if err != nil {
|
||||
glog.Errorf("ERROR creating a deep copy of network object: %v\n", err)
|
||||
return
|
||||
|
@ -106,13 +106,14 @@ type Interface interface {
|
||||
// EnsureLoadBalancerDeleted ensures a load balancer is deleted.
|
||||
EnsureLoadBalancerDeleted(name string) error
|
||||
// GetCRDClient returns the CRDClient.
|
||||
GetCRDClient() *crdClient.CRDClient
|
||||
GetCRDClient() crdClient.Interface
|
||||
// GetPluginName returns the plugin name.
|
||||
GetPluginName() string
|
||||
// GetIntegrationBridge returns the integration bridge name.
|
||||
GetIntegrationBridge() string
|
||||
}
|
||||
|
||||
// Client implements the openstack client Interface.
|
||||
type Client struct {
|
||||
Identity *gophercloud.ServiceClient
|
||||
Provider *gophercloud.ProviderClient
|
||||
@ -121,7 +122,7 @@ type Client struct {
|
||||
ExtNetID string
|
||||
PluginName string
|
||||
IntegrationBridge string
|
||||
CRDClient *crdClient.CRDClient
|
||||
CRDClient crdClient.Interface
|
||||
}
|
||||
|
||||
type PluginOpts struct {
|
||||
@ -129,6 +130,7 @@ type PluginOpts struct {
|
||||
IntegrationBridge string `gcfg:"integration-bridge"`
|
||||
}
|
||||
|
||||
// Config used to configure the openstack client.
|
||||
type Config struct {
|
||||
Global struct {
|
||||
AuthUrl string `gcfg:"auth-url"`
|
||||
@ -151,6 +153,7 @@ func toAuthOptions(cfg Config) gophercloud.AuthOptions {
|
||||
}
|
||||
}
|
||||
|
||||
// NewClient returns a new openstack client.
|
||||
func NewClient(config string, kubeConfig string) (Interface, error) {
|
||||
var opts gophercloud.AuthOptions
|
||||
cfg, err := readConfig(config)
|
||||
@ -221,7 +224,7 @@ func readConfig(config string) (Config, error) {
|
||||
}
|
||||
|
||||
// GetCRDClient returns the CRDClient.
|
||||
func (os *Client) GetCRDClient() *crdClient.CRDClient {
|
||||
func (os *Client) GetCRDClient() crdClient.Interface {
|
||||
return os.CRDClient
|
||||
}
|
||||
|
||||
@ -466,6 +469,7 @@ func (os *Client) GetNetworkByName(networkName string) (*drivertypes.Network, er
|
||||
return os.OSNetworktoProviderNetwork(osNetwork)
|
||||
}
|
||||
|
||||
// OSNetworktoProviderNetwork transfers networks.Network to drivertypes.Network.
|
||||
func (os *Client) OSNetworktoProviderNetwork(osNetwork *networks.Network) (*drivertypes.Network, error) {
|
||||
var providerNetwork drivertypes.Network
|
||||
var providerSubnets []*drivertypes.Subnet
|
||||
@ -487,6 +491,7 @@ func (os *Client) OSNetworktoProviderNetwork(osNetwork *networks.Network) (*driv
|
||||
return &providerNetwork, nil
|
||||
}
|
||||
|
||||
// ToProviderStatus transfers networks.Network's status to drivertypes.Network's status.
|
||||
func (os *Client) ToProviderStatus(status string) string {
|
||||
switch status {
|
||||
case "ACTIVE":
|
||||
|
@ -18,11 +18,10 @@ package openstack
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1"
|
||||
crdClient "git.openstack.org/openstack/stackube/pkg/kubecrd"
|
||||
drivertypes "git.openstack.org/openstack/stackube/pkg/openstack/types"
|
||||
"git.openstack.org/openstack/stackube/pkg/util"
|
||||
@ -34,19 +33,27 @@ import (
|
||||
"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
|
||||
)
|
||||
|
||||
var ErrAlreadyExist = errors.New("AlreadyExist")
|
||||
// CalledDetail is the struct contains called function name and arguments.
|
||||
type CalledDetail struct {
|
||||
// Name of the function called.
|
||||
Name string
|
||||
// Argument of the function called.
|
||||
Argument []interface{}
|
||||
}
|
||||
|
||||
// FakeOSClient is a simple fake openstack client, so that stackube
|
||||
// can be run for testing without requiring a real openstack setup.
|
||||
type FakeOSClient struct {
|
||||
sync.Mutex
|
||||
called []CalledDetail
|
||||
errors map[string]error
|
||||
Tenants map[string]*tenants.Tenant
|
||||
Users map[string]*users.User
|
||||
Networks map[string]*drivertypes.Network
|
||||
Subnets map[string]*subnets.Subnet
|
||||
Routers map[string]*routers.Router
|
||||
Ports map[string][]ports.Port
|
||||
// TODO(mozhuli): Add fakeCRDClient.
|
||||
CRDClient *crdClient.CRDClient
|
||||
CRDClient crdClient.Interface
|
||||
PluginName string
|
||||
IntegrationBridge string
|
||||
}
|
||||
@ -54,50 +61,116 @@ type FakeOSClient struct {
|
||||
var _ = Interface(&FakeOSClient{})
|
||||
|
||||
// NewFake creates a new FakeOSClient.
|
||||
func NewFake() *FakeOSClient {
|
||||
func NewFake(crdClient crdClient.Interface) *FakeOSClient {
|
||||
return &FakeOSClient{
|
||||
errors: make(map[string]error),
|
||||
Tenants: make(map[string]*tenants.Tenant),
|
||||
Users: make(map[string]*users.User),
|
||||
Networks: make(map[string]*drivertypes.Network),
|
||||
Subnets: make(map[string]*subnets.Subnet),
|
||||
Routers: make(map[string]*routers.Router),
|
||||
Ports: make(map[string][]ports.Port),
|
||||
CRDClient: crdClient,
|
||||
PluginName: "ovs",
|
||||
IntegrationBridge: "bi-int",
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FakeOSClient) getError(op string) error {
|
||||
err, ok := f.errors[op]
|
||||
if ok {
|
||||
delete(f.errors, op)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InjectError inject error for call
|
||||
func (f *FakeOSClient) InjectError(fn string, err error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.errors[fn] = err
|
||||
}
|
||||
|
||||
// InjectErrors inject errors for calls
|
||||
func (f *FakeOSClient) InjectErrors(errs map[string]error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
for fn, err := range errs {
|
||||
f.errors[fn] = err
|
||||
}
|
||||
}
|
||||
|
||||
// ClearErrors clear errors for call
|
||||
func (f *FakeOSClient) ClearErrors() {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.errors = make(map[string]error)
|
||||
}
|
||||
|
||||
func (f *FakeOSClient) appendCalled(name string, argument ...interface{}) {
|
||||
call := CalledDetail{Name: name, Argument: argument}
|
||||
f.called = append(f.called, call)
|
||||
}
|
||||
|
||||
// GetCalledNames get names of call
|
||||
func (f *FakeOSClient) GetCalledNames() []string {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
names := []string{}
|
||||
for _, detail := range f.called {
|
||||
names = append(names, detail.Name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// GetCalledDetails get detail of each call.
|
||||
func (f *FakeOSClient) GetCalledDetails() []CalledDetail {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
// Copy the list and return.
|
||||
return append([]CalledDetail{}, f.called...)
|
||||
}
|
||||
|
||||
// SetTenant injects fake tenant.
|
||||
func (os *FakeOSClient) SetTenant(tenantName, tenantID string) {
|
||||
func (f *FakeOSClient) SetTenant(tenantName, tenantID string) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
tenant := &tenants.Tenant{
|
||||
Name: tenantName,
|
||||
ID: tenantID,
|
||||
}
|
||||
os.Tenants[tenantName] = tenant
|
||||
f.Tenants[tenantName] = tenant
|
||||
}
|
||||
|
||||
// SetUser injects fake user.
|
||||
func (os *FakeOSClient) SetUser(userName, userID, tenantID string) {
|
||||
func (f *FakeOSClient) SetUser(userName, userID, tenantID string) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
user := &users.User{
|
||||
Username: userName,
|
||||
ID: userID,
|
||||
TenantID: tenantID,
|
||||
}
|
||||
os.Users[tenantID] = user
|
||||
f.Users[tenantID] = user
|
||||
}
|
||||
|
||||
// SetNetwork injects fake network.
|
||||
func (os *FakeOSClient) SetNetwork(networkName, networkID string) {
|
||||
func (f *FakeOSClient) SetNetwork(networkName, networkID string) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
network := &drivertypes.Network{
|
||||
Name: networkName,
|
||||
Uid: networkID,
|
||||
}
|
||||
os.Networks[networkName] = network
|
||||
f.Networks[networkName] = network
|
||||
}
|
||||
|
||||
// SetPort injects fake port.
|
||||
func (os *FakeOSClient) SetPort(networkID, deviceOwner, deviceID string) {
|
||||
netPorts, ok := os.Ports[networkID]
|
||||
func (f *FakeOSClient) SetPort(networkID, deviceOwner, deviceID string) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
netPorts, ok := f.Ports[networkID]
|
||||
p := ports.Port{
|
||||
NetworkID: networkID,
|
||||
DeviceOwner: deviceOwner,
|
||||
@ -106,10 +179,10 @@ func (os *FakeOSClient) SetPort(networkID, deviceOwner, deviceID string) {
|
||||
if !ok {
|
||||
var ps []ports.Port
|
||||
ps = append(ps, p)
|
||||
os.Ports[networkID] = ps
|
||||
f.Ports[networkID] = ps
|
||||
}
|
||||
netPorts = append(netPorts, p)
|
||||
os.Ports[networkID] = netPorts
|
||||
f.Ports[networkID] = netPorts
|
||||
}
|
||||
|
||||
func tenantIDHash(tenantName string) string {
|
||||
@ -146,84 +219,129 @@ func idHash(data ...string) string {
|
||||
return fmt.Sprintf("%x", h.Sum(nil))[:16]
|
||||
}
|
||||
|
||||
// CreateTenant creates tenant by tenantname.
|
||||
func (os *FakeOSClient) CreateTenant(tenantName string) (string, error) {
|
||||
if t, ok := os.Tenants[tenantName]; ok {
|
||||
// CreateTenant is a test implementation of Interface.CreateTenant.
|
||||
func (f *FakeOSClient) CreateTenant(tenantName string) (string, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("CreateTenant", tenantName)
|
||||
if err := f.getError("CreateTenant"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if t, ok := f.Tenants[tenantName]; ok {
|
||||
return t.ID, nil
|
||||
}
|
||||
tenant := &tenants.Tenant{
|
||||
Name: tenantName,
|
||||
ID: tenantIDHash(tenantName),
|
||||
}
|
||||
os.Tenants[tenantName] = tenant
|
||||
f.Tenants[tenantName] = tenant
|
||||
return tenant.ID, nil
|
||||
}
|
||||
|
||||
// DeleteTenant deletes tenant by tenantName.
|
||||
func (os *FakeOSClient) DeleteTenant(tenantName string) error {
|
||||
delete(os.Tenants, tenantName)
|
||||
// DeleteTenant is a test implementation of Interface.DeleteTenant.
|
||||
func (f *FakeOSClient) DeleteTenant(tenantName string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("DeleteTenant", tenantName)
|
||||
if err := f.getError("DeleteTenant"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(f.Tenants, tenantName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTenantIDFromName gets tenantID by tenantName.
|
||||
func (os *FakeOSClient) GetTenantIDFromName(tenantName string) (string, error) {
|
||||
// GetTenantIDFromName is a test implementation of Interface.GetTenantIDFromName.
|
||||
func (f *FakeOSClient) GetTenantIDFromName(tenantName string) (string, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("GetTenantIDFromName", tenantName)
|
||||
if err := f.getError("GetTenantIDFromName"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if util.IsSystemNamespace(tenantName) {
|
||||
tenantName = util.SystemTenant
|
||||
}
|
||||
|
||||
// If tenantID is specified, return it directly
|
||||
var (
|
||||
tenant *crv1.Tenant
|
||||
err error
|
||||
)
|
||||
// TODO(mozhuli): use fakeCRDClient.
|
||||
if tenant, err = os.CRDClient.GetTenant(tenantName); err != nil {
|
||||
tenant, err := f.CRDClient.GetTenant(tenantName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if tenant.Spec.TenantID != "" {
|
||||
return tenant.Spec.TenantID, nil
|
||||
}
|
||||
|
||||
t, ok := os.Tenants[tenantName]
|
||||
t, ok := f.Tenants[tenantName]
|
||||
if !ok {
|
||||
return "", nil
|
||||
return "", fmt.Errorf("Tenant %s not exist", tenantName)
|
||||
}
|
||||
|
||||
return t.ID, nil
|
||||
}
|
||||
|
||||
// CheckTenantByID checks tenant exist or not by tenantID.
|
||||
func (os *FakeOSClient) CheckTenantByID(tenantID string) (bool, error) {
|
||||
for _, tenent := range os.Tenants {
|
||||
// CheckTenantByID is a test implementation of Interface.CheckTenantByID.
|
||||
func (f *FakeOSClient) CheckTenantByID(tenantID string) (bool, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("CheckTenantByID", tenantID)
|
||||
if err := f.getError("CheckTenantByID"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, tenent := range f.Tenants {
|
||||
if tenent.ID == tenantID {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, ErrNotFound
|
||||
return false, fmt.Errorf("Tenant %s not exist", tenantID)
|
||||
}
|
||||
|
||||
// CreateUser is a test implementation of Interface.CreateUser.
|
||||
func (f *FakeOSClient) CreateUser(username, password, tenantID string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("CreateUser", username, password, tenantID)
|
||||
if err := f.getError("CreateUser"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateUser creates user with username, password in the tenant.
|
||||
func (os *FakeOSClient) CreateUser(username, password, tenantID string) error {
|
||||
user := &users.User{
|
||||
Name: username,
|
||||
TenantID: tenantID,
|
||||
ID: userIDHash(username, tenantID),
|
||||
}
|
||||
os.Users[tenantID] = user
|
||||
f.Users[tenantID] = user
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteAllUsersOnTenant deletes all users on the tenant.
|
||||
func (os *FakeOSClient) DeleteAllUsersOnTenant(tenantName string) error {
|
||||
tenant := os.Tenants[tenantName]
|
||||
// DeleteAllUsersOnTenant is a test implementation of Interface.DeleteAllUsersOnTenant.
|
||||
func (f *FakeOSClient) DeleteAllUsersOnTenant(tenantName string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("DeleteAllUsersOnTenant", tenantName)
|
||||
if err := f.getError("DeleteAllUsersOnTenant"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(os.Users, tenant.ID)
|
||||
tenant := f.Tenants[tenantName]
|
||||
|
||||
delete(f.Users, tenant.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (os *FakeOSClient) createNetwork(networkName, tenantID string) error {
|
||||
if _, ok := os.Networks[networkName]; ok {
|
||||
return ErrAlreadyExist
|
||||
func (f *FakeOSClient) createNetwork(networkName, tenantID string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("createNetwork", networkName, tenantID)
|
||||
if err := f.getError("createNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Networks[networkName]; ok {
|
||||
return fmt.Errorf("Network %s already exist", networkName)
|
||||
}
|
||||
|
||||
network := &drivertypes.Network{
|
||||
@ -231,18 +349,32 @@ func (os *FakeOSClient) createNetwork(networkName, tenantID string) error {
|
||||
Uid: networkIDHash(networkName),
|
||||
TenantID: tenantID,
|
||||
}
|
||||
os.Networks[networkName] = network
|
||||
f.Networks[networkName] = network
|
||||
return nil
|
||||
}
|
||||
|
||||
func (os *FakeOSClient) deleteNetwork(networkName string) error {
|
||||
delete(os.Networks, networkName)
|
||||
func (f *FakeOSClient) deleteNetwork(networkName string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("deleteNetwork", networkName)
|
||||
if err := f.getError("deleteNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(f.Networks, networkName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (os *FakeOSClient) createRouter(routerName, tenantID string) error {
|
||||
if _, ok := os.Routers[routerName]; ok {
|
||||
return ErrAlreadyExist
|
||||
func (f *FakeOSClient) createRouter(routerName, tenantID string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("createRouter", routerName, tenantID)
|
||||
if err := f.getError("createRouter"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Routers[routerName]; ok {
|
||||
return fmt.Errorf("Router %s already exist", routerName)
|
||||
}
|
||||
|
||||
router := &routers.Router{
|
||||
@ -250,18 +382,32 @@ func (os *FakeOSClient) createRouter(routerName, tenantID string) error {
|
||||
TenantID: tenantID,
|
||||
ID: routerIDHash(routerName),
|
||||
}
|
||||
os.Routers[routerName] = router
|
||||
f.Routers[routerName] = router
|
||||
return nil
|
||||
}
|
||||
|
||||
func (os *FakeOSClient) deleteRouter(routerName string) error {
|
||||
delete(os.Routers, routerName)
|
||||
func (f *FakeOSClient) deleteRouter(routerName string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("deleteRouter", routerName)
|
||||
if err := f.getError("deleteRouter"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(f.Routers, routerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (os *FakeOSClient) createSubnet(subnetName, networkID, tenantID string) error {
|
||||
if _, ok := os.Subnets[subnetName]; ok {
|
||||
return ErrAlreadyExist
|
||||
func (f *FakeOSClient) createSubnet(subnetName, networkID, tenantID string) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("createSubnet", subnetName, networkID, tenantID)
|
||||
if err := f.getError("createSubnet"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := f.Subnets[subnetName]; ok {
|
||||
return fmt.Errorf("Subnet %s already exist", subnetName)
|
||||
}
|
||||
|
||||
subnet := &subnets.Subnet{
|
||||
@ -270,77 +416,98 @@ func (os *FakeOSClient) createSubnet(subnetName, networkID, tenantID string) err
|
||||
NetworkID: networkID,
|
||||
ID: subnetIDHash(subnetName),
|
||||
}
|
||||
os.Subnets[subnetName] = subnet
|
||||
f.Subnets[subnetName] = subnet
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateNetwork creates network.
|
||||
// TODO(mozhuli): make it more general.
|
||||
func (os *FakeOSClient) CreateNetwork(network *drivertypes.Network) error {
|
||||
// CreateNetwork is a test implementation of Interface.CreateNetwork.
|
||||
func (f *FakeOSClient) CreateNetwork(network *drivertypes.Network) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("CreateNetwork", network)
|
||||
if err := f.getError("CreateNetwork"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(network.Subnets) == 0 {
|
||||
return errors.New("Subnets is null")
|
||||
return fmt.Errorf("Subnets is null")
|
||||
}
|
||||
|
||||
// create network
|
||||
err := os.createNetwork(network.Name, network.TenantID)
|
||||
err := f.createNetwork(network.Name, network.TenantID)
|
||||
if err != nil {
|
||||
return errors.New("Create network failed")
|
||||
return err
|
||||
}
|
||||
// create router, and use network name as router name for convenience.
|
||||
err = os.createRouter(network.Name, network.TenantID)
|
||||
err = f.createRouter(network.Name, network.TenantID)
|
||||
if err != nil {
|
||||
os.deleteNetwork(network.Name)
|
||||
return errors.New("Create router failed")
|
||||
f.deleteNetwork(network.Name)
|
||||
return err
|
||||
}
|
||||
// create subnets and connect them to router
|
||||
err = os.createSubnet(network.Subnets[0].Name, network.Uid, network.TenantID)
|
||||
err = f.createSubnet(network.Subnets[0].Name, network.Uid, network.TenantID)
|
||||
if err != nil {
|
||||
os.deleteRouter(network.Name)
|
||||
os.deleteNetwork(network.Name)
|
||||
return errors.New("Create subnet failed")
|
||||
f.deleteRouter(network.Name)
|
||||
f.deleteNetwork(network.Name)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkByID gets network by networkID.
|
||||
func (os *FakeOSClient) GetNetworkByID(networkID string) (*drivertypes.Network, error) {
|
||||
// CreateTenant is a test implementation of Interface.CreateTenant.
|
||||
func (f *FakeOSClient) GetNetworkByID(networkID string) (*drivertypes.Network, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetNetworkByName get network by networkName
|
||||
func (os *FakeOSClient) GetNetworkByName(networkName string) (*drivertypes.Network, error) {
|
||||
network, ok := os.Networks[networkName]
|
||||
// GetNetworkByName is a test implementation of Interface.GetNetworkByName.
|
||||
func (f *FakeOSClient) GetNetworkByName(networkName string) (*drivertypes.Network, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("GetNetworkByName", networkName)
|
||||
if err := f.getError("GetNetworkByName"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
network, ok := f.Networks[networkName]
|
||||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
return nil, fmt.Errorf("Network %s not exist", networkName)
|
||||
}
|
||||
|
||||
return network, nil
|
||||
}
|
||||
|
||||
// DeleteNetwork deletes network by networkName.
|
||||
func (os *FakeOSClient) DeleteNetwork(networkName string) error {
|
||||
// DeleteNetwork is a test implementation of Interface.DeleteNetwork.
|
||||
func (f *FakeOSClient) DeleteNetwork(networkName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetProviderSubnet gets provider subnet by id
|
||||
func (os *FakeOSClient) GetProviderSubnet(osSubnetID string) (*drivertypes.Subnet, error) {
|
||||
// GetProviderSubnet is a test implementation of Interface.GetProviderSubnet.
|
||||
func (f *FakeOSClient) GetProviderSubnet(osSubnetID string) (*drivertypes.Subnet, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// CreatePort creates port by neworkID, tenantID and portName.
|
||||
func (os *FakeOSClient) CreatePort(networkID, tenantID, portName string) (*portsbinding.Port, error) {
|
||||
// CreatePort is a test implementation of Interface.CreatePort.
|
||||
func (f *FakeOSClient) CreatePort(networkID, tenantID, portName string) (*portsbinding.Port, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetPort gets port by portName.
|
||||
func (os *FakeOSClient) GetPort(name string) (*ports.Port, error) {
|
||||
// GetPort is a test implementation of Interface.GetPort.
|
||||
func (f *FakeOSClient) GetPort(name string) (*ports.Port, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ListPorts list all ports which have the deviceOwner in the network.
|
||||
func (os *FakeOSClient) ListPorts(networkID, deviceOwner string) ([]ports.Port, error) {
|
||||
// ListPorts is a test implementation of Interface.ListPorts.
|
||||
func (f *FakeOSClient) ListPorts(networkID, deviceOwner string) ([]ports.Port, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.appendCalled("ListPorts", networkID, deviceOwner)
|
||||
if err := f.getError("ListPorts"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var results []ports.Port
|
||||
portList, ok := os.Ports[networkID]
|
||||
portList, ok := f.Ports[networkID]
|
||||
if !ok {
|
||||
return results, nil
|
||||
}
|
||||
@ -353,48 +520,47 @@ func (os *FakeOSClient) ListPorts(networkID, deviceOwner string) ([]ports.Port,
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// DeletePortByName deletes port by portName.
|
||||
func (os *FakeOSClient) DeletePortByName(portName string) error {
|
||||
// DeletePortByName is a test implementation of Interface.DeletePortByName.
|
||||
func (f *FakeOSClient) DeletePortByName(portName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePortByID deletes port by portID.
|
||||
func (os *FakeOSClient) DeletePortByID(portID string) error {
|
||||
// DeletePortByID is a test implementation of Interface.DeletePortByID.
|
||||
func (f *FakeOSClient) DeletePortByID(portID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePortsBinding updates port binding.
|
||||
func (os *FakeOSClient) UpdatePortsBinding(portID, deviceOwner string) error {
|
||||
// UpdatePortsBinding is a test implementation of Interface.UpdatePortsBinding.
|
||||
func (f *FakeOSClient) UpdatePortsBinding(portID, deviceOwner string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadBalancerExist returns whether a load balancer has already been exist.
|
||||
func (os *FakeOSClient) LoadBalancerExist(name string) (bool, error) {
|
||||
// LoadBalancerExist is a test implementation of Interface.LoadBalancerExist.
|
||||
func (f *FakeOSClient) LoadBalancerExist(name string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// EnsureLoadBalancer ensures a load balancer is created.
|
||||
func (os *FakeOSClient) EnsureLoadBalancer(lb *LoadBalancer) (*LoadBalancerStatus, error) {
|
||||
// EnsureLoadBalancer is a test implementation of Interface.EnsureLoadBalancer.
|
||||
func (f *FakeOSClient) EnsureLoadBalancer(lb *LoadBalancer) (*LoadBalancerStatus, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// EnsureLoadBalancerDeleted ensures a load balancer is deleted.
|
||||
func (os *FakeOSClient) EnsureLoadBalancerDeleted(name string) error {
|
||||
// EnsureLoadBalancerDeleted is a test implementation of Interface.EnsureLoadBalancerDeleted.
|
||||
func (f *FakeOSClient) EnsureLoadBalancerDeleted(name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCRDClient returns the CRDClient.
|
||||
// TODO(mozhuli): use fakeCRDClient.
|
||||
func (os *FakeOSClient) GetCRDClient() *crdClient.CRDClient {
|
||||
return os.CRDClient
|
||||
// GetCRDClient is a test implementation of Interface.GetCRDClient.
|
||||
func (f *FakeOSClient) GetCRDClient() crdClient.Interface {
|
||||
return f.CRDClient
|
||||
}
|
||||
|
||||
// GetPluginName returns the plugin name.
|
||||
func (os *FakeOSClient) GetPluginName() string {
|
||||
return os.PluginName
|
||||
// GetPluginName is a test implementation of Interface.GetPluginName.
|
||||
func (f *FakeOSClient) GetPluginName() string {
|
||||
return f.PluginName
|
||||
}
|
||||
|
||||
// GetIntegrationBridge returns the integration bridge name.
|
||||
func (os *FakeOSClient) GetIntegrationBridge() string {
|
||||
return os.IntegrationBridge
|
||||
// GetIntegrationBridge is a test implementation of Interface.GetIntegrationBridge.
|
||||
func (f *FakeOSClient) GetIntegrationBridge() string {
|
||||
return f.IntegrationBridge
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package proxy
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -35,6 +36,7 @@ type Rule map[string]string
|
||||
|
||||
// FakeIPTables have noop implementation of fake iptables function.
|
||||
type FakeIPTables struct {
|
||||
sync.Mutex
|
||||
namespace string
|
||||
NSLines map[string][]byte
|
||||
}
|
||||
@ -55,6 +57,8 @@ func (f *FakeIPTables) ensureRule(op, chain string, args []string) error {
|
||||
}
|
||||
|
||||
func (f *FakeIPTables) restoreAll(data []byte) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
d := make([]byte, len(data))
|
||||
copy(d, data)
|
||||
f.NSLines[f.namespace] = d
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
crdClient "git.openstack.org/openstack/stackube/pkg/kubecrd"
|
||||
"git.openstack.org/openstack/stackube/pkg/openstack"
|
||||
"git.openstack.org/openstack/stackube/pkg/util"
|
||||
|
||||
@ -192,8 +193,13 @@ func TestClusterNoEndpoint(t *testing.T) {
|
||||
|
||||
// Creates fake iptables.
|
||||
ipt := NewFake()
|
||||
// Creates fake CRD client.
|
||||
crdClient, err := crdClient.NewFake()
|
||||
if err != nil {
|
||||
t.Fatal("Failed init fake CRD client")
|
||||
}
|
||||
// Create a fake openstack client.
|
||||
osClient := openstack.NewFake()
|
||||
osClient := openstack.NewFake(crdClient)
|
||||
// Injects fake network.
|
||||
networkName := util.BuildNetworkName(testNamespace, testNamespace)
|
||||
osClient.SetNetwork(networkName, "123")
|
||||
@ -226,7 +232,7 @@ func TestClusterNoEndpoint(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func noClusterIPType(svcType v1.ServiceType) []Rule {
|
||||
func noClusterIPType(t *testing.T, svcType v1.ServiceType) []Rule {
|
||||
testNamespace := "test"
|
||||
svcIP := "1.2.3.4"
|
||||
svcPort := 80
|
||||
@ -237,8 +243,13 @@ func noClusterIPType(svcType v1.ServiceType) []Rule {
|
||||
|
||||
// Creates fake iptables.
|
||||
ipt := NewFake()
|
||||
// Creates fake CRD client.
|
||||
crdClient, err := crdClient.NewFake()
|
||||
if err != nil {
|
||||
t.Fatal("Failed init fake CRD client")
|
||||
}
|
||||
// Create a fake openstack client.
|
||||
osClient := openstack.NewFake()
|
||||
osClient := openstack.NewFake(crdClient)
|
||||
// Injects fake network.
|
||||
networkName := util.BuildNetworkName(testNamespace, testNamespace)
|
||||
osClient.SetNetwork(networkName, "123")
|
||||
@ -277,7 +288,7 @@ func TestNoClusterIPType(t *testing.T) {
|
||||
}
|
||||
|
||||
for k, tc := range testCases {
|
||||
got := noClusterIPType(tc)
|
||||
got := noClusterIPType(t, tc)
|
||||
if len(got) != 0 {
|
||||
errorf(fmt.Sprintf("%v: unexpected rule for chain %v without ClusterIP service type", k, ChainSKPrerouting), got, t)
|
||||
}
|
||||
@ -295,8 +306,13 @@ func TestClusterIPEndpointsJump(t *testing.T) {
|
||||
|
||||
// Creates fake iptables.
|
||||
ipt := NewFake()
|
||||
// Creates fake CRD client.
|
||||
crdClient, err := crdClient.NewFake()
|
||||
if err != nil {
|
||||
t.Fatal("Failed init fake CRD client")
|
||||
}
|
||||
// Create a fake openstack client.
|
||||
osClient := openstack.NewFake()
|
||||
osClient := openstack.NewFake(crdClient)
|
||||
// Injects fake network.
|
||||
networkName := util.BuildNetworkName(testNamespace, testNamespace)
|
||||
osClient.SetNetwork(networkName, "123")
|
||||
@ -365,8 +381,13 @@ func TestMultiNamespacesService(t *testing.T) {
|
||||
|
||||
// Creates fake iptables.
|
||||
ipt := NewFake()
|
||||
// Creates fake CRD client.
|
||||
crdClient, err := crdClient.NewFake()
|
||||
if err != nil {
|
||||
t.Fatal("Failed init fake CRD client")
|
||||
}
|
||||
// Create a fake openstack client.
|
||||
osClient := openstack.NewFake()
|
||||
osClient := openstack.NewFake(crdClient)
|
||||
// Injects fake network.
|
||||
networkName1 := util.BuildNetworkName(ns1, ns1)
|
||||
osClient.SetNetwork(networkName1, "123")
|
||||
|
Loading…
Reference in New Issue
Block a user