/* 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" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/rest" crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1" "git.openstack.org/openstack/stackube/pkg/util" "github.com/golang/glog" ) type CRDClient struct { Client *rest.RESTClient Scheme *runtime.Scheme } func NewCRDClient(cfg *rest.Config) (*CRDClient, error) { scheme := runtime.NewScheme() if err := crv1.AddToScheme(scheme); err != nil { return nil, err } config := *cfg config.GroupVersion = &crv1.SchemeGroupVersion config.APIPath = "/apis" config.ContentType = runtime.ContentTypeJSON config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)} client, err := rest.RESTClientFor(&config) if err != nil { return nil, err } return &CRDClient{ Client: client, Scheme: scheme, }, nil } // UpdateNetwork updates Network CRD object by given object func (c *CRDClient) UpdateNetwork(network *crv1.Network) { err := c.Client.Put(). Name(network.Name). Namespace(network.Namespace). Resource(crv1.NetworkResourcePlural). Body(network). Do(). Error() if err != nil { glog.Errorf("ERROR updating network: %v\n", err) } else { glog.V(3).Infof("UPDATED network: %#v\n", network) } } // UpdateTenant updates Network CRD object by given object func (c *CRDClient) UpdateTenant(tenant *crv1.Tenant) { err := c.Client.Put(). Name(tenant.Name). Namespace(util.SystemTenant). Resource(crv1.TenantResourcePlural). Body(tenant). Do(). Error() if err != nil { glog.Errorf("ERROR updating tenant: %v\n", err) } else { glog.V(3).Infof("UPDATED tenant: %#v\n", tenant) } } // GetTenant returns tenant from CRD // 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(). Resource(crv1.TenantResourcePlural). Namespace(util.SystemTenant). Name(tenantName). Do().Into(&tenant) if err != nil { return nil, err } return &tenant, nil } // AddTenant adds tenant to CRD // NOTE: all tenant are added to system namespace func (c *CRDClient) AddTenant(tenant *crv1.Tenant) error { err := c.Client.Post(). Namespace(util.SystemTenant). Resource(crv1.TenantResourcePlural). Body(tenant). Do().Error() if err != nil && !apierrors.IsAlreadyExists(err) { return fmt.Errorf("failed to create Tenant: %v", err) } return nil } func (c *CRDClient) AddNetwork(network *crv1.Network) error { err := c.Client.Post(). Resource(crv1.NetworkResourcePlural). Namespace(network.GetNamespace()). Body(network). Do().Error() if err != nil && !apierrors.IsAlreadyExists(err) { return fmt.Errorf("failed to create Network: %v", err) } return nil } func (c *CRDClient) DeleteNetork(namespace string) error { // NOTE: the automatically created network for tenant use namespace as name err := c.Client.Delete(). Resource(crv1.NetworkResourcePlural). Namespace(namespace). Name(namespace). Do().Error() if err != nil { return fmt.Errorf("failed to delete Network: %v", err) } return nil }