Add new crd to convert kubesphere network policy to k8s network policy, and then other network plugin will do the rest work. Use cache.go from calico project's kube-controller, it aim to sync nsnp with k8s np, delete unused np, and relieve the pressure on k8s restful client. If you want higher performance, you can implement interface NsNetworkPolicyProvider in pkg/controller/provider/namespace_np.go. Signed-off-by: Duan Jiong <djduanjiong@gmail.com>
110 lines
3.6 KiB
Go
110 lines
3.6 KiB
Go
// Copyright (c) 2017 Tigera, Inc. All rights reserved.
|
|
//
|
|
// 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 converter
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
api "github.com/projectcalico/libcalico-go/lib/apis/v3"
|
|
"github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion"
|
|
|
|
"k8s.io/api/core/v1"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
// WorkloadEndpointData is an internal struct used to store the various bits
|
|
// of information that the policy controller cares about on a workload endpoint.
|
|
type WorkloadEndpointData struct {
|
|
PodName string
|
|
Namespace string
|
|
Labels map[string]string
|
|
}
|
|
|
|
type podConverter struct {
|
|
}
|
|
|
|
// BuildWorkloadEndpointData generates the correct WorkloadEndpointData for the given
|
|
// WorkloadEndpoint, extracting fields that the policy controller is responsible for syncing.
|
|
func BuildWorkloadEndpointData(wep api.WorkloadEndpoint) WorkloadEndpointData {
|
|
return WorkloadEndpointData{
|
|
PodName: wep.Spec.Pod,
|
|
Namespace: wep.Namespace,
|
|
Labels: wep.Labels,
|
|
}
|
|
}
|
|
|
|
// MergeWorkloadEndpointData applies the given WorkloadEndpointData to the provided
|
|
// WorkloadEndpoint, updating relevant fields with new values.
|
|
func MergeWorkloadEndpointData(wep *api.WorkloadEndpoint, upd WorkloadEndpointData) {
|
|
if wep.Spec.Pod != upd.PodName || wep.Namespace != upd.Namespace {
|
|
log.Fatalf("Bad attempt to merge data for %s/%s into wep %s/%s", upd.PodName, upd.Namespace, wep.Name, wep.Namespace)
|
|
}
|
|
wep.Labels = upd.Labels
|
|
}
|
|
|
|
// NewPodConverter Constructor for podConverter
|
|
func NewPodConverter() Converter {
|
|
return &podConverter{}
|
|
}
|
|
|
|
func (p *podConverter) Convert(k8sObj interface{}) (interface{}, error) {
|
|
// Convert Pod into a workload endpoint.
|
|
var c conversion.Converter
|
|
pod, ok := k8sObj.(*v1.Pod)
|
|
if !ok {
|
|
tombstone, ok := k8sObj.(cache.DeletedFinalStateUnknown)
|
|
if !ok {
|
|
return nil, errors.New("couldn't get object from tombstone")
|
|
}
|
|
pod, ok = tombstone.Obj.(*v1.Pod)
|
|
if !ok {
|
|
return nil, errors.New("tombstone contained object that is not a Pod")
|
|
}
|
|
}
|
|
|
|
// The conversion logic always requires a node, but we don't always have one. We don't actually
|
|
// care about the value used for the node in this controller, so just dummy it out if it doesn't exist.
|
|
if pod.Spec.NodeName == "" {
|
|
pod.Spec.NodeName = "unknown.node"
|
|
}
|
|
|
|
kvp, err := c.PodToWorkloadEndpoint(pod)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wep := kvp.Value.(*api.WorkloadEndpoint)
|
|
|
|
// Build and return a WorkloadEndpointData struct using the data.
|
|
return BuildWorkloadEndpointData(*wep), nil
|
|
}
|
|
|
|
// GetKey takes a WorkloadEndpointData and returns the key which
|
|
// identifies it - namespace/name
|
|
func (p *podConverter) GetKey(obj interface{}) string {
|
|
e := obj.(WorkloadEndpointData)
|
|
return fmt.Sprintf("%s/%s", e.Namespace, e.PodName)
|
|
}
|
|
|
|
func (p *podConverter) DeleteArgsFromKey(key string) (string, string) {
|
|
// We don't have enough information to generate the delete args from the key that's used
|
|
// for Pods / WorkloadEndpoints, so just panic. This should never be called but is necessary
|
|
// to satisfy the interface.
|
|
log.Panicf("DeleteArgsFromKey call for WorkloadEndpoints is not allowed")
|
|
return "", ""
|
|
}
|