add ns networkpolicy
This commit is contained in:
66
pkg/controller/network/provider/fake_ns_calico.go
Normal file
66
pkg/controller/network/provider/fake_ns_calico.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/projectcalico/libcalico-go/lib/errors"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
api "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
)
|
||||
|
||||
func NewFakeCalicoNetworkProvider() *FakeCalicoNetworkProvider {
|
||||
f := new(FakeCalicoNetworkProvider)
|
||||
f.NSNPData = make(map[string]*api.NamespaceNetworkPolicy)
|
||||
return f
|
||||
}
|
||||
|
||||
type FakeCalicoNetworkProvider struct {
|
||||
NSNPData map[string]*api.NamespaceNetworkPolicy
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) Get(o *api.NamespaceNetworkPolicy) (interface{}, error) {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
obj, ok := f.NSNPData[namespacename]
|
||||
if !ok {
|
||||
return nil, errors.ErrorResourceDoesNotExist{}
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) Add(o *api.NamespaceNetworkPolicy) error {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
if _, ok := f.NSNPData[namespacename]; ok {
|
||||
return errors.ErrorResourceAlreadyExists{}
|
||||
}
|
||||
f.NSNPData[namespacename] = o
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) CheckExist(o *api.NamespaceNetworkPolicy) (bool, error) {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
if _, ok := f.NSNPData[namespacename]; ok {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) NeedUpdate(o *api.NamespaceNetworkPolicy) (bool, error) {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
store := f.NSNPData[namespacename]
|
||||
if !reflect.DeepEqual(store, o) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) Update(o *api.NamespaceNetworkPolicy) error {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
f.NSNPData[namespacename] = o
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeCalicoNetworkProvider) Delete(o *api.NamespaceNetworkPolicy) error {
|
||||
namespacename, _ := cache.MetaNamespaceKeyFunc(o)
|
||||
delete(f.NSNPData, namespacename)
|
||||
return nil
|
||||
}
|
||||
1
pkg/controller/network/provider/global_np.go
Normal file
1
pkg/controller/network/provider/global_np.go
Normal file
@@ -0,0 +1 @@
|
||||
package provider
|
||||
35
pkg/controller/network/provider/namespace_np.go
Normal file
35
pkg/controller/network/provider/namespace_np.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
k8snetworkinformer "k8s.io/client-go/informers/networking/v1"
|
||||
k8snetworklister "k8s.io/client-go/listers/networking/v1"
|
||||
api "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
)
|
||||
|
||||
// NsNetworkPolicyProvider is a interface to let different cnis to implement our api
|
||||
type NsNetworkPolicyProvider interface {
|
||||
Add(*api.NamespaceNetworkPolicy) error
|
||||
CheckExist(*api.NamespaceNetworkPolicy) (bool, error)
|
||||
NeedUpdate(*api.NamespaceNetworkPolicy) (bool, error)
|
||||
Update(*api.NamespaceNetworkPolicy) error
|
||||
Delete(*api.NamespaceNetworkPolicy) error
|
||||
Get(*api.NamespaceNetworkPolicy) (interface{}, error)
|
||||
}
|
||||
|
||||
// TODO: support no-calico CNI
|
||||
type k8sNetworkProvider struct {
|
||||
networkPolicyInformer k8snetworkinformer.NetworkPolicyInformer
|
||||
networkPolicyLister k8snetworklister.NetworkPolicyLister
|
||||
}
|
||||
|
||||
func (k *k8sNetworkProvider) Add(o *api.NamespaceNetworkPolicy) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *k8sNetworkProvider) CheckExist(o *api.NamespaceNetworkPolicy) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (k *k8sNetworkProvider) Delete(o *api.NamespaceNetworkPolicy) error {
|
||||
return nil
|
||||
}
|
||||
144
pkg/controller/network/provider/ns_calico.go
Normal file
144
pkg/controller/network/provider/ns_calico.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
v3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
|
||||
"github.com/projectcalico/libcalico-go/lib/clientv3"
|
||||
"github.com/projectcalico/libcalico-go/lib/errors"
|
||||
"github.com/projectcalico/libcalico-go/lib/options"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/klog/klogr"
|
||||
api "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1"
|
||||
)
|
||||
|
||||
var log = klogr.New().WithName("calico-client")
|
||||
var defaultBackoff = wait.Backoff{
|
||||
Steps: 4,
|
||||
Duration: 10 * time.Millisecond,
|
||||
Factor: 5.0,
|
||||
Jitter: 0.1,
|
||||
}
|
||||
|
||||
type calicoNetworkProvider struct {
|
||||
np clientv3.NetworkPolicyInterface
|
||||
}
|
||||
|
||||
func NewCalicoNetworkProvider(np clientv3.NetworkPolicyInterface) NsNetworkPolicyProvider {
|
||||
return &calicoNetworkProvider{
|
||||
np: np,
|
||||
}
|
||||
}
|
||||
func convertSpec(n *api.NamespaceNetworkPolicySpec) *v3.NetworkPolicySpec {
|
||||
bytes, err := json.Marshal(&n)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m := new(v3.NetworkPolicySpec)
|
||||
err = json.Unmarshal(bytes, m)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// ConvertAPIToCalico convert our api to calico api
|
||||
func ConvertAPIToCalico(n *api.NamespaceNetworkPolicy) *v3.NetworkPolicy {
|
||||
output := v3.NewNetworkPolicy()
|
||||
//Object Metadata
|
||||
output.ObjectMeta.Name = n.Name
|
||||
output.Namespace = n.Namespace
|
||||
output.Annotations = n.Annotations
|
||||
output.Labels = n.Labels
|
||||
//spec
|
||||
output.Spec = *(convertSpec(&n.Spec))
|
||||
return output
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) Get(o *api.NamespaceNetworkPolicy) (interface{}, error) {
|
||||
return k.np.Get(context.TODO(), o.Namespace, o.Name, options.GetOptions{})
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) Add(o *api.NamespaceNetworkPolicy) error {
|
||||
log.V(3).Info("Creating network policy", "name", o.Name, "namespace", o.Namespace)
|
||||
obj := ConvertAPIToCalico(o)
|
||||
log.V(4).Info("Show object spe detail", "name", o.Name, "namespace", o.Namespace, "Spec", obj.Spec)
|
||||
_, err := k.np.Create(context.TODO(), obj, options.SetOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) CheckExist(o *api.NamespaceNetworkPolicy) (bool, error) {
|
||||
log.V(3).Info("Checking network policy whether exsits or not", "name", o.Name, "namespace", o.Namespace)
|
||||
out, err := k.np.Get(context.Background(), o.Namespace, o.Name, options.GetOptions{})
|
||||
if err != nil {
|
||||
if _, ok := err.(errors.ErrorResourceDoesNotExist); ok {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if out != nil {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) Delete(o *api.NamespaceNetworkPolicy) error {
|
||||
log.V(3).Info("Deleting network policy", "name", o.Name, "namespace", o.Namespace)
|
||||
_, err := k.np.Delete(context.Background(), o.Namespace, o.Name, options.DeleteOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) NeedUpdate(o *api.NamespaceNetworkPolicy) (bool, error) {
|
||||
store, err := k.np.Get(context.Background(), o.Namespace, o.Name, options.GetOptions{})
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to get resource", "name", o.Name, "namespace", o.Namespace)
|
||||
}
|
||||
expected := ConvertAPIToCalico(o)
|
||||
log.V(4).Info("Comparing Spec", "store", store.Spec, "current", expected.Spec)
|
||||
if !reflect.DeepEqual(store.Spec, expected.Spec) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (k *calicoNetworkProvider) Update(o *api.NamespaceNetworkPolicy) error {
|
||||
log.V(3).Info("Updating network policy", "name", o.Name, "namespace", o.Namespace)
|
||||
updateObject, err := k.Get(o)
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to get resource in store")
|
||||
return err
|
||||
}
|
||||
up := updateObject.(*v3.NetworkPolicy)
|
||||
up.Spec = *convertSpec(&o.Spec)
|
||||
err = RetryOnConflict(defaultBackoff, func() error {
|
||||
_, err := k.np.Update(context.Background(), up, options.SetOptions{})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to update resource", "name", o.Name, "namespace", o.Namespace)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// RetryOnConflict is same as the function in k8s, but replaced with error in calico
|
||||
func RetryOnConflict(backoff wait.Backoff, fn func() error) error {
|
||||
var lastConflictErr error
|
||||
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
err := fn()
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if _, ok := err.(errors.ErrorResourceUpdateConflict); ok {
|
||||
lastConflictErr = err
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
})
|
||||
if err == wait.ErrWaitTimeout {
|
||||
err = lastConflictErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user