diff --git a/build/ks-network/Dockerfile b/build/ks-network/Dockerfile deleted file mode 100644 index fb5223cf3602b2cccdaa3b653496088ede1d7429..0000000000000000000000000000000000000000 --- a/build/ks-network/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM gcr.io/distroless/static:latest -WORKDIR / -COPY ks-network . -ENTRYPOINT ["/ks-network"] diff --git a/cmd/controller-manager/app/controllers.go b/cmd/controller-manager/app/controllers.go index 7adfecd324798edcfd4f1fc921d8e64d08993902..dc19f28de8b1ed93889053c55d77e8679a5d3c05 100644 --- a/cmd/controller-manager/app/controllers.go +++ b/cmd/controller-manager/app/controllers.go @@ -25,6 +25,8 @@ import ( "kubesphere.io/kubesphere/pkg/controller/devopscredential" "kubesphere.io/kubesphere/pkg/controller/devopsproject" "kubesphere.io/kubesphere/pkg/controller/job" + "kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy" + "kubesphere.io/kubesphere/pkg/controller/network/provider" "kubesphere.io/kubesphere/pkg/controller/pipeline" "kubesphere.io/kubesphere/pkg/controller/s2ibinary" "kubesphere.io/kubesphere/pkg/controller/s2irun" @@ -126,6 +128,16 @@ func AddControllers( kubesphereInformer.Cluster().V1alpha1().Clusters(), client.KubeSphere().ClusterV1alpha1().Clusters()) + nsnpProvider, err := provider.NewNsNetworkPolicyProvider(client.Kubernetes(), + kubernetesInformer.Networking().V1().NetworkPolicies()) + if err != nil { + return err + } + nsnpController := nsnetworkpolicy.NewNSNetworkPolicyController(client.Kubernetes(), + client.KubeSphere().NetworkV1alpha1(), kubesphereInformer.Network().V1alpha1().NamespaceNetworkPolicies(), + kubernetesInformer.Core().V1().Services(), kubesphereInformer.Tenant().V1alpha1().Workspaces(), + kubernetesInformer.Core().V1().Namespaces(), nsnpProvider) + controllers := map[string]manager.Runnable{ "virtualservice-controller": vsController, "destinationrule-controller": drController, @@ -137,8 +149,9 @@ func AddControllers( "devopsprojects-controller": devopsProjectController, "pipeline-controller": devopsPipelineController, "devopscredential-controller": devopsCredentialController, - "cluster-controller": clusterController, "user-controller": userController, + "cluster-controller": clusterController, + "nsnp-controller": nsnpController, } for name, ctrl := range controllers { diff --git a/cmd/controller-manager/app/server.go b/cmd/controller-manager/app/server.go index 5a17265851eafa3d99758a375e8c593917c2e503..899ff5c1c610d766270f424e578da1e214060fd5 100644 --- a/cmd/controller-manager/app/server.go +++ b/cmd/controller-manager/app/server.go @@ -35,6 +35,7 @@ import ( controllerconfig "kubesphere.io/kubesphere/pkg/apiserver/config" "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" "kubesphere.io/kubesphere/pkg/controller/namespace" + "kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy" "kubesphere.io/kubesphere/pkg/controller/user" "kubesphere.io/kubesphere/pkg/controller/workspace" "kubesphere.io/kubesphere/pkg/simple/client/openpitrix" @@ -160,6 +161,7 @@ func Run(s *options.KubeSphereControllerManagerOptions, stopCh <-chan struct{}) klog.Info("registering webhooks to the webhook server") hookServer.Register("/mutating-encrypt-password-iam-kubesphere-io-v1alpha2-user", &webhook.Admission{Handler: &user.PasswordCipher{Client: mgr.GetClient()}}) hookServer.Register("/validate-email-iam-kubesphere-io-v1alpha2-user", &webhook.Admission{Handler: &user.EmailValidator{Client: mgr.GetClient()}}) + hookServer.Register("/validate-service-nsnp-kubesphere-io-v1alpha1-network", &webhook.Admission{Handler: &nsnetworkpolicy.ServiceValidator{}}) klog.V(0).Info("Starting the controllers.") if err = mgr.Start(stopCh); err != nil { diff --git a/cmd/ks-network/main.go b/cmd/ks-network/main.go deleted file mode 100644 index 7b3b6683d51149b095450ced58728e4eb9ba2efb..0000000000000000000000000000000000000000 --- a/cmd/ks-network/main.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "flag" - - "k8s.io/klog" - "kubesphere.io/kubesphere/pkg/controller/network/runoption" -) - -var opt runoption.RunOption - -func init() { - flag.StringVar(&opt.ProviderName, "np-provider", "calico", "specify the network policy provider, k8s or calico") - flag.BoolVar(&opt.AllowInsecureEtcd, "allow-insecure-etcd", false, "specify allow connect to etcd using insecure http") - flag.StringVar(&opt.DataStoreType, "datastore-type", "k8s", "specify the datastore type of calico") - //TODO add more flags -} - -func main() { - klog.InitFlags(nil) - flag.Set("logtostderr", "true") - flag.Parse() - klog.V(1).Info("Preparing kubernetes client") - klog.Fatal(opt.Run()) -} diff --git a/config/crd/bases/network.kubesphere.io_workspacenetworkpolicies.yaml b/config/crd/bases/network.kubesphere.io_workspacenetworkpolicies.yaml deleted file mode 100644 index 77302069bb1f20096fe4aab08dbffae88afb73a3..0000000000000000000000000000000000000000 --- a/config/crd/bases/network.kubesphere.io_workspacenetworkpolicies.yaml +++ /dev/null @@ -1,535 +0,0 @@ - ---- -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: (devel) - creationTimestamp: null - name: workspacenetworkpolicies.network.kubesphere.io -spec: - group: network.kubesphere.io - names: - categories: - - networking - kind: WorkspaceNetworkPolicy - listKind: WorkspaceNetworkPolicyList - plural: workspacenetworkpolicies - shortNames: - - wsnp - singular: workspacenetworkpolicy - scope: Cluster - validation: - openAPIV3Schema: - description: WorkspaceNetworkPolicy is a set of network policies applied to - the scope to workspace - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: WorkspaceNetworkPolicySpec defines the desired state of WorkspaceNetworkPolicy - properties: - egress: - description: List of egress rules to be applied to the selected pods. - Outgoing traffic is allowed if there are no NetworkPolicies selecting - the pod (and cluster policy otherwise allows the traffic), OR if the - traffic matches at least one egress rule across all of the NetworkPolicy - objects whose podSelector matches the pod. If this field is empty - then this NetworkPolicy limits all outgoing traffic (and serves solely - to ensure that the pods it selects are isolated by default). This - field is beta-level in 1.8 - items: - description: WorkspaceNetworkPolicyEgressRule describes a particular - set of traffic that is allowed out of pods matched by a WorkspaceNetworkPolicySpec's - podSelector. The traffic must match both ports and to. - properties: - from: - description: List of sources which should be able to access the - pods selected for this rule. Items in this list are combined - using a logical OR operation. If this field is empty or missing, - this rule matches all sources (traffic not restricted by source). - If this field is present and contains at least on item, this - rule allows traffic only if the traffic matches at least one - item in the from list. - items: - description: WorkspaceNetworkPolicyPeer describes a peer to - allow traffic from. Only certain combinations of fields are - allowed. It is same as 'NetworkPolicyPeer' in k8s but with - an additional field 'WorkspaceSelector' - properties: - ipBlock: - description: IPBlock defines policy on a particular IPBlock. - If this field is set then neither of the other fields - can be. - properties: - cidr: - description: CIDR is a string representing the IP Block - Valid examples are "192.168.1.1/24" - type: string - except: - description: Except is a slice of CIDRs that should - not be included within an IP Block Valid examples - are "192.168.1.1/24" Except values will be rejected - if they are outside the CIDR range - items: - type: string - type: array - required: - - cidr - type: object - namespaceSelector: - description: "Selects Namespaces using cluster-scoped labels. - This field follows standard label selector semantics; - if present but empty, it selects all namespaces. \n If - PodSelector is also set, then the NetworkPolicyPeer as - a whole selects the Pods matching PodSelector in the Namespaces - selected by NamespaceSelector. Otherwise it selects all - Pods in the Namespaces selected by NamespaceSelector." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - podSelector: - description: "This is a label selector which selects Pods. - This field follows standard label selector semantics; - if present but empty, it selects all pods. \n If NamespaceSelector - is also set, then the NetworkPolicyPeer as a whole selects - the Pods matching PodSelector in the Namespaces selected - by NamespaceSelector. Otherwise it selects the Pods matching - PodSelector in the policy's own Namespace." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - workspaceSelector: - description: A label selector is a label query over a set - of resources. The result of matchLabels and matchExpressions - are ANDed. An empty label selector matches all objects. - A null label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible on - the pods selected for this rule. Each item in this list is combined - using a logical OR. If this field is empty or missing, this - rule matches all ports (traffic not restricted by port). If - this field is present and contains at least one item, then this - rule allows traffic only if the traffic matches at least one - port in the list. - items: - description: NetworkPolicyPort describes a port to allow traffic - on - properties: - port: - anyOf: - - type: integer - - type: string - description: The port on the given protocol. This can either - be a numerical or named port on a pod. If this field is - not provided, this matches all port names and numbers. - x-kubernetes-int-or-string: true - protocol: - description: The protocol (TCP, UDP, or SCTP) which traffic - must match. If not specified, this field defaults to TCP. - type: string - type: object - type: array - type: object - type: array - ingress: - description: List of ingress rules to be applied to the selected pods. - Traffic is allowed to a pod if there are no NetworkPolicies selecting - the pod (and cluster policy otherwise allows the traffic), OR if the - traffic source is the pod's local node, OR if the traffic matches - at least one ingress rule across all of the NetworkPolicy objects - whose podSelector matches the pod. If this field is empty then this - NetworkPolicy does not allow any traffic (and serves solely to ensure - that the pods it selects are isolated by default) - items: - description: WorkspaceNetworkPolicyIngressRule describes a particular - set of traffic that is allowed to the pods matched by a WorkspaceNetworkPolicySpec's - podSelector. The traffic must match both ports and from. - properties: - from: - description: List of sources which should be able to access the - pods selected for this rule. Items in this list are combined - using a logical OR operation. If this field is empty or missing, - this rule matches all sources (traffic not restricted by source). - If this field is present and contains at least on item, this - rule allows traffic only if the traffic matches at least one - item in the from list. - items: - description: WorkspaceNetworkPolicyPeer describes a peer to - allow traffic from. Only certain combinations of fields are - allowed. It is same as 'NetworkPolicyPeer' in k8s but with - an additional field 'WorkspaceSelector' - properties: - ipBlock: - description: IPBlock defines policy on a particular IPBlock. - If this field is set then neither of the other fields - can be. - properties: - cidr: - description: CIDR is a string representing the IP Block - Valid examples are "192.168.1.1/24" - type: string - except: - description: Except is a slice of CIDRs that should - not be included within an IP Block Valid examples - are "192.168.1.1/24" Except values will be rejected - if they are outside the CIDR range - items: - type: string - type: array - required: - - cidr - type: object - namespaceSelector: - description: "Selects Namespaces using cluster-scoped labels. - This field follows standard label selector semantics; - if present but empty, it selects all namespaces. \n If - PodSelector is also set, then the NetworkPolicyPeer as - a whole selects the Pods matching PodSelector in the Namespaces - selected by NamespaceSelector. Otherwise it selects all - Pods in the Namespaces selected by NamespaceSelector." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - podSelector: - description: "This is a label selector which selects Pods. - This field follows standard label selector semantics; - if present but empty, it selects all pods. \n If NamespaceSelector - is also set, then the NetworkPolicyPeer as a whole selects - the Pods matching PodSelector in the Namespaces selected - by NamespaceSelector. Otherwise it selects the Pods matching - PodSelector in the policy's own Namespace." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - workspaceSelector: - description: A label selector is a label query over a set - of resources. The result of matchLabels and matchExpressions - are ANDed. An empty label selector matches all objects. - A null label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible on - the pods selected for this rule. Each item in this list is combined - using a logical OR. If this field is empty or missing, this - rule matches all ports (traffic not restricted by port). If - this field is present and contains at least one item, then this - rule allows traffic only if the traffic matches at least one - port in the list. - items: - description: NetworkPolicyPort describes a port to allow traffic - on - properties: - port: - anyOf: - - type: integer - - type: string - description: The port on the given protocol. This can either - be a numerical or named port on a pod. If this field is - not provided, this matches all port names and numbers. - x-kubernetes-int-or-string: true - protocol: - description: The protocol (TCP, UDP, or SCTP) which traffic - must match. If not specified, this field defaults to TCP. - type: string - type: object - type: array - type: object - type: array - policyTypes: - description: List of rule types that the WorkspaceNetworkPolicy relates - to. Valid options are Ingress, Egress, or Ingress,Egress. If this - field is not specified, it will default based on the existence of - Ingress or Egress rules; policies that contain an Egress section are - assumed to affect Egress, and all policies (whether or not they contain - an Ingress section) are assumed to affect Ingress. If you want to - write an egress-only policy, you must explicitly specify policyTypes - [ "Egress" ]. Likewise, if you want to write a policy that specifies - that no egress is allowed, you must specify a policyTypes value that - include "Egress" (since such a policy would not include an Egress - section and would otherwise default to just [ "Ingress" ]). - items: - description: Policy Type string describes the NetworkPolicy type This - type is beta-level in 1.8 - type: string - type: array - workspace: - description: Workspace specify the name of ws to apply this workspace - network policy - type: string - type: object - status: - description: WorkspaceNetworkPolicyStatus defines the observed state of - WorkspaceNetworkPolicy - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/network.kubesphere.io_namespacenetworkpolicies.yaml b/config/crds/network.kubesphere.io_namespacenetworkpolicies.yaml new file mode 100644 index 0000000000000000000000000000000000000000..36ce1b4eff3040ec9338f7a56db8ae31e5d3aa9f --- /dev/null +++ b/config/crds/network.kubesphere.io_namespacenetworkpolicies.yaml @@ -0,0 +1,271 @@ +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (devel) + creationTimestamp: null + name: namespacenetworkpolicies.network.kubesphere.io +spec: + group: network.kubesphere.io + names: + categories: + - networking + kind: NamespaceNetworkPolicy + listKind: NamespaceNetworkPolicyList + plural: namespacenetworkpolicies + shortNames: + - nsnp + singular: namespacenetworkpolicy + scope: Namespaced + validation: + openAPIV3Schema: + description: NamespaceNetworkPolicy is the Schema for the namespacenetworkpolicies + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NetworkPolicySpec provides the specification of a NetworkPolicy + properties: + egress: + description: List of egress rules to be applied to the selected pods. + Outgoing traffic is allowed if there are no NetworkPolicies selecting + the pod (and cluster policy otherwise allows the traffic), OR if the + traffic matches at least one egress rule across all of the NetworkPolicy + objects whose podSelector matches the pod. If this field is empty + then this NetworkPolicy limits all outgoing traffic (and serves solely + to ensure that the pods it selects are isolated by default). This + field is beta-level in 1.8 + items: + description: NetworkPolicyEgressRule describes a particular set of + traffic that is allowed out of pods matched by a NetworkPolicySpec's + podSelector. The traffic must match both ports and to. This type + is beta-level in 1.8 + properties: + ports: + description: List of destination ports for outgoing traffic. Each + item in this list is combined using a logical OR. If this field + is empty or missing, this rule matches all ports (traffic not + restricted by port). If this field is present and contains at + least one item, then this rule allows traffic only if the traffic + matches at least one port in the list. + items: + description: NetworkPolicyPort describes a port to allow traffic + on + properties: + port: + anyOf: + - type: integer + - type: string + description: The port on the given protocol. This can either + be a numerical or named port on a pod. If this field is + not provided, this matches all port names and numbers. + x-kubernetes-int-or-string: true + protocol: + description: The protocol (TCP, UDP, or SCTP) which traffic + must match. If not specified, this field defaults to TCP. + type: string + type: object + type: array + to: + description: List of destinations for outgoing traffic of pods + selected for this rule. Items in this list are combined using + a logical OR operation. If this field is empty or missing, this + rule matches all destinations (traffic not restricted by destination). + If this field is present and contains at least one item, this + rule allows traffic only if the traffic matches at least one + item in the to list. + items: + description: NetworkPolicyPeer describes a peer to allow traffic + from. Only certain combinations of fields are allowed + properties: + ipBlock: + description: IPBlock defines policy on a particular IPBlock. + If this field is set then neither of the other fields + can be. + properties: + cidr: + description: CIDR is a string representing the IP Block + Valid examples are "192.168.1.1/24" + type: string + except: + description: Except is a slice of CIDRs that should + not be included within an IP Block Valid examples + are "192.168.1.1/24" Except values will be rejected + if they are outside the CIDR range + items: + type: string + type: array + required: + - cidr + type: object + namespace: + description: "Selects Namespaces using cluster-scoped labels. + This field follows standard label selector semantics; + if present but empty, it selects all namespaces. \n If + PodSelector is also set, then the NetworkPolicyPeer as + a whole selects the Pods matching PodSelector in the Namespaces + selected by NamespaceSelector. Otherwise it selects all + Pods in the Namespaces selected by NamespaceSelector." + properties: + name: + type: string + required: + - name + type: object + service: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + type: object + type: array + type: object + type: array + ingress: + description: List of ingress rules to be applied to the selected pods. + Traffic is allowed to a pod if there are no NetworkPolicies selecting + the pod (and cluster policy otherwise allows the traffic), OR if the + traffic source is the pod's local node, OR if the traffic matches + at least one ingress rule across all of the NetworkPolicy objects + whose podSelector matches the pod. If this field is empty then this + NetworkPolicy does not allow any traffic (and serves solely to ensure + that the pods it selects are isolated by default) + items: + description: NetworkPolicyIngressRule describes a particular set of + traffic that is allowed to the pods matched by a NetworkPolicySpec's + podSelector. The traffic must match both ports and from. + properties: + from: + description: List of sources which should be able to access the + pods selected for this rule. Items in this list are combined + using a logical OR operation. If this field is empty or missing, + this rule matches all sources (traffic not restricted by source). + If this field is present and contains at least one item, this + rule allows traffic only if the traffic matches at least one + item in the from list. + items: + description: NetworkPolicyPeer describes a peer to allow traffic + from. Only certain combinations of fields are allowed + properties: + ipBlock: + description: IPBlock defines policy on a particular IPBlock. + If this field is set then neither of the other fields + can be. + properties: + cidr: + description: CIDR is a string representing the IP Block + Valid examples are "192.168.1.1/24" + type: string + except: + description: Except is a slice of CIDRs that should + not be included within an IP Block Valid examples + are "192.168.1.1/24" Except values will be rejected + if they are outside the CIDR range + items: + type: string + type: array + required: + - cidr + type: object + namespace: + description: "Selects Namespaces using cluster-scoped labels. + This field follows standard label selector semantics; + if present but empty, it selects all namespaces. \n If + PodSelector is also set, then the NetworkPolicyPeer as + a whole selects the Pods matching PodSelector in the Namespaces + selected by NamespaceSelector. Otherwise it selects all + Pods in the Namespaces selected by NamespaceSelector." + properties: + name: + type: string + required: + - name + type: object + service: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + type: object + type: array + ports: + description: List of ports which should be made accessible on + the pods selected for this rule. Each item in this list is combined + using a logical OR. If this field is empty or missing, this + rule matches all ports (traffic not restricted by port). If + this field is present and contains at least one item, then this + rule allows traffic only if the traffic matches at least one + port in the list. + items: + description: NetworkPolicyPort describes a port to allow traffic + on + properties: + port: + anyOf: + - type: integer + - type: string + description: The port on the given protocol. This can either + be a numerical or named port on a pod. If this field is + not provided, this matches all port names and numbers. + x-kubernetes-int-or-string: true + protocol: + description: The protocol (TCP, UDP, or SCTP) which traffic + must match. If not specified, this field defaults to TCP. + type: string + type: object + type: array + type: object + type: array + policyTypes: + description: List of rule types that the NetworkPolicy relates to. Valid + options are "Ingress", "Egress", or "Ingress,Egress". If this field + is not specified, it will default based on the existence of Ingress + or Egress rules; policies that contain an Egress section are assumed + to affect Egress, and all policies (whether or not they contain an + Ingress section) are assumed to affect Ingress. If you want to write + an egress-only policy, you must explicitly specify policyTypes [ "Egress" + ]. Likewise, if you want to write a policy that specifies that no + egress is allowed, you must specify a policyTypes value that include + "Egress" (since such a policy would not include an Egress section + and would otherwise default to just [ "Ingress" ]). This field is + beta-level in 1.8 + items: + description: Policy Type string describes the NetworkPolicy type This + type is beta-level in 1.8 + type: string + type: array + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/webhook/nsnp.yaml b/config/webhook/nsnp.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d02cd5a7c9254430c182a18d515d2939ee5f4b6a --- /dev/null +++ b/config/webhook/nsnp.yaml @@ -0,0 +1,24 @@ +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: kubesphere-nsnp-validate-service +webhooks: + - clientConfig: + caBundle: + service: + name: kubesphere-controller-manager-service + namespace: kubesphere-system + path: /validate-service-nsnp-kubesphere-io-v1alpha1-network + failurePolicy: Fail + name: validate.nsnp.kubesphere.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - services diff --git a/go.mod b/go.mod index 3f05a0dec8f01d25dff0ec0bbbffe37f59be341e..fb6d1a446649f10fd232af39ec3666fbb9247b8a 100644 --- a/go.mod +++ b/go.mod @@ -30,13 +30,12 @@ require ( github.com/emirpasic/gods v1.12.0 // indirect github.com/fatih/structs v1.1.0 github.com/go-ldap/ldap v3.0.3+incompatible - github.com/go-logr/logr v0.1.0 github.com/go-logr/zapr v0.1.1 // indirect + github.com/go-openapi/jsonreference v0.19.3 // indirect github.com/go-openapi/loads v0.19.2 github.com/go-openapi/spec v0.19.3 github.com/go-openapi/strfmt v0.19.0 github.com/go-openapi/validate v0.19.2 - github.com/go-playground/universal-translator v0.16.0 // indirect github.com/go-redis/redis v6.15.2+incompatible github.com/go-sql-driver/mysql v1.4.1 github.com/gocraft/dbr v0.0.0-20180507214907-a0fd650918f6 @@ -46,32 +45,34 @@ require ( github.com/google/go-cmp v0.3.0 github.com/google/go-querystring v1.0.0 // indirect github.com/google/uuid v1.1.1 - github.com/gophercloud/gophercloud v0.3.0 // indirect github.com/gorilla/mux v1.7.1 // indirect github.com/gorilla/websocket v1.4.0 github.com/hashicorp/go-version v1.2.0 // indirect github.com/imdario/mergo v0.3.7 // indirect - github.com/json-iterator/go v1.1.9 + github.com/json-iterator/go v1.1.8 github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/kiali/kiali v0.15.1-0.20191210080139-edbbad1ef779 github.com/kubernetes-sigs/application v0.0.0-20191210100950-18cc93526ab4 github.com/kubesphere/sonargo v0.0.2 - github.com/leodido/go-urn v1.1.0 // indirect github.com/lib/pq v1.2.0 // indirect + github.com/mailru/easyjson v0.7.0 // indirect github.com/mattn/go-sqlite3 v1.11.0 // indirect github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect - github.com/onsi/ginkgo v1.12.0 - github.com/onsi/gomega v1.9.0 + github.com/onsi/ginkgo v1.8.0 + github.com/onsi/gomega v1.5.0 github.com/open-policy-agent/opa v0.18.0 github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/image-spec v1.0.1 // indirect github.com/openshift/api v0.0.0-20180801171038-322a19404e37 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/pkg/errors v0.9.1 + github.com/patrickmn/go-cache v2.1.0+incompatible + github.com/pkg/errors v0.8.1 + github.com/projectcalico/kube-controllers v3.8.8+incompatible github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce - github.com/prometheus/client_golang v1.0.0 + github.com/prometheus/client_golang v0.9.4 github.com/prometheus/common v0.4.1 github.com/prometheus/prometheus v1.8.2 + github.com/sirupsen/logrus v1.4.2 github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009 github.com/speps/go-hashids v2.0.0+incompatible github.com/spf13/cobra v0.0.5 @@ -84,28 +85,27 @@ require ( golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 google.golang.org/grpc v1.23.1 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect - gopkg.in/go-playground/validator.v9 v9.29.1 // indirect gopkg.in/src-d/go-billy.v4 v4.3.0 // indirect gopkg.in/src-d/go-git.v4 v4.11.0 - gopkg.in/yaml.v2 v2.2.8 + gopkg.in/yaml.v2 v2.2.4 istio.io/api v0.0.0-20191111210003-35e06ef8d838 istio.io/client-go v0.0.0-20191113122552-9bd0ba57c3d2 - k8s.io/api v0.17.3 - k8s.io/apiextensions-apiserver v0.17.3 - k8s.io/apimachinery v0.17.3 - k8s.io/apiserver v0.17.3 - k8s.io/client-go v0.17.3 - k8s.io/code-generator v0.17.3 - k8s.io/component-base v0.17.3 + k8s.io/api v0.0.0-20191114100352-16d7abae0d2a + k8s.io/apiextensions-apiserver v0.0.0-20191114105449-027877536833 + k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb + k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 + k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 + k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 + k8s.io/component-base v0.0.0-20191114102325-35a9586014f7 k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e // indirect k8s.io/klog v1.0.0 k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a + k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect kubesphere.io/im v0.1.0 // indirect openpitrix.io/iam v0.1.0 // indirect openpitrix.io/openpitrix v0.4.1-0.20190920134345-4d2be6e4965c - sigs.k8s.io/controller-runtime v0.5.0 + sigs.k8s.io/controller-runtime v0.4.0 sigs.k8s.io/controller-tools v0.2.4 - sigs.k8s.io/kubefed v0.2.0-alpha.1 ) replace ( @@ -119,7 +119,6 @@ replace ( github.com/Azure/go-autorest/logger => github.com/Azure/go-autorest/logger v0.1.0 github.com/Azure/go-autorest/tracing => github.com/Azure/go-autorest/tracing v0.5.0 github.com/BurntSushi/toml => github.com/BurntSushi/toml v0.3.1 - github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd github.com/Masterminds/semver => github.com/Masterminds/semver v1.5.0 github.com/Microsoft/go-winio => github.com/Microsoft/go-winio v0.4.12 github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v1.1.1 @@ -143,7 +142,6 @@ replace ( github.com/bmizerany/assert => github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 github.com/cenkalti/backoff => github.com/cenkalti/backoff v2.2.1+incompatible github.com/cespare/xxhash => github.com/cespare/xxhash v1.1.0 - github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 github.com/cheekybits/genny => github.com/cheekybits/genny v1.0.0 github.com/client9/misspell => github.com/client9/misspell v0.3.4 github.com/coreos/bbolt => github.com/coreos/bbolt v1.3.3 @@ -154,7 +152,6 @@ replace ( github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.10 github.com/davecgh/go-spew => github.com/davecgh/go-spew v1.1.1 - github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd github.com/deckarep/golang-set => github.com/deckarep/golang-set v1.7.1 github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289 github.com/dgrijalva/jwt-go => github.com/dgrijalva/jwt-go v3.2.0+incompatible @@ -176,7 +173,6 @@ replace ( github.com/emirpasic/gods => github.com/emirpasic/gods v1.12.0 github.com/erikstmartin/go-testdb => github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.5.0+incompatible - github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d github.com/fatih/camelcase => github.com/fatih/camelcase v1.0.0 github.com/fatih/color => github.com/fatih/color v1.7.0 github.com/fatih/structs => github.com/fatih/structs v1.1.0 @@ -218,9 +214,6 @@ replace ( github.com/golang/mock => github.com/golang/mock v1.2.0 github.com/golang/protobuf => github.com/golang/protobuf v1.3.2 github.com/golang/snappy => github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db - github.com/golangplus/bytes => github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 - github.com/golangplus/fmt => github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 - github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e github.com/google/btree => github.com/google/btree v1.0.0 github.com/google/go-cmp => github.com/google/go-cmp v0.3.0 github.com/google/go-querystring => github.com/google/go-querystring v1.0.0 @@ -271,14 +264,11 @@ replace ( github.com/kr/pty => github.com/kr/pty v1.1.5 github.com/kr/text => github.com/kr/text v0.1.0 github.com/kubernetes-sigs/application => github.com/kubesphere/application v0.0.0-20191210100950-18cc93526ab4 - github.com/kubernetes-sigs/federation-v2 => github.com/kubernetes-sigs/federation-v2 v0.0.10 github.com/kubesphere/s2ioperator => github.com/kubesphere/s2ioperator v0.0.14 github.com/kubesphere/sonargo => github.com/kubesphere/sonargo v0.0.2 github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 github.com/leodido/go-urn => github.com/leodido/go-urn v1.1.0 github.com/lib/pq => github.com/lib/pq v1.2.0 - github.com/liggitt/tabwriter => github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de - github.com/lithammer/dedent => github.com/lithammer/dedent v1.1.0 github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.11.1 github.com/magiconair/properties => github.com/magiconair/properties v1.8.0 github.com/mailru/easyjson => github.com/mailru/easyjson v0.7.0 @@ -292,7 +282,6 @@ replace ( github.com/mholt/certmagic => github.com/mholt/certmagic v0.5.1 github.com/miekg/dns => github.com/miekg/dns v1.1.9 github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/go-wordwrap => github.com/mitchellh/go-wordwrap v1.0.0 github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2 github.com/mna/pigeon => github.com/mna/pigeon v0.0.0-20180808201053-bb0192cfc2ae github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd @@ -312,7 +301,6 @@ replace ( github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1 github.com/openshift/api => github.com/openshift/api v0.0.0-20180801171038-322a19404e37 github.com/openshift/build-machinery-go => github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160 - github.com/openshift/generic-admission-server => github.com/openshift/generic-admission-server v1.14.0 github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0 github.com/pborman/uuid => github.com/pborman/uuid v1.2.0 github.com/pelletier/go-buffruneio => github.com/pelletier/go-buffruneio v0.2.0 @@ -364,7 +352,6 @@ replace ( github.com/urfave/cli => github.com/urfave/cli v1.20.0 github.com/xanzy/ssh-agent => github.com/xanzy/ssh-agent v0.2.1 github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 - github.com/xlab/handysort => github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1 github.com/xlab/treeprint => github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6 github.com/xordataexchange/crypt => github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 github.com/yashtewari/glob-intersection => github.com/yashtewari/glob-intersection v0.0.0-20180916065949-5c77d914dd0b @@ -422,16 +409,12 @@ replace ( k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191114105449-027877536833 k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb k8s.io/apiserver => k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.17.3 k8s.io/client-go => k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 - k8s.io/cluster-registry => k8s.io/cluster-registry v0.0.6 k8s.io/code-generator => k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 k8s.io/component-base => k8s.io/component-base v0.0.0-20191114102325-35a9586014f7 k8s.io/gengo => k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e k8s.io/klog => k8s.io/klog v1.0.0 k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a - k8s.io/kubectl => k8s.io/kubectl v0.17.3 - k8s.io/metrics => k8s.io/metrics v0.17.3 k8s.io/utils => k8s.io/utils v0.0.0-20191114184206-e782cd3c129f kubesphere.io/application => kubesphere.io/application v0.0.0-20190404151855-67ae7f915d4e kubesphere.io/im => kubesphere.io/im v0.1.0 @@ -446,10 +429,7 @@ replace ( rsc.io/goversion => rsc.io/goversion v1.0.0 sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.4.0 sigs.k8s.io/controller-tools => sigs.k8s.io/controller-tools v0.2.4 - sigs.k8s.io/kubefed => sigs.k8s.io/kubefed v0.2.0-alpha.1 - sigs.k8s.io/kustomize => sigs.k8s.io/kustomize v2.0.3+incompatible sigs.k8s.io/structured-merge-diff => sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca sigs.k8s.io/testing_frameworks => sigs.k8s.io/testing_frameworks v0.1.2 sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.1.0 - vbom.ml/util => vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc ) diff --git a/go.sum b/go.sum index e1063bda5b8a76e8f4ce825d827829a6deacf7a0..c549ed4b4cd4c0d97b631d1a30a469ca61e56b4e 100644 --- a/go.sum +++ b/go.sum @@ -323,6 +323,8 @@ github.com/openshift/api v0.0.0-20180801171038-322a19404e37/go.mod h1:dh9o4Fs58g github.com/openshift/generic-admission-server v1.14.0/go.mod h1:GD9KN/W4KxqRQGVMbqQHpHzb2XcQVvLCaBaSciqXvfM= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= @@ -344,6 +346,8 @@ github.com/projectcalico/go-yaml v0.0.0-20161201183616-955bc3e451ef h1:Di9BaA9ap github.com/projectcalico/go-yaml v0.0.0-20161201183616-955bc3e451ef/go.mod h1:1Ra2BftSa7Go38Gbq1q0bfmBFSSgUv+Cdc3SY8IL/C0= github.com/projectcalico/go-yaml-wrapper v0.0.0-20161127220527-598e54215bee h1:yVWsNSlAuYoJ0CznHsYRPiFgsotoj07k00k5rQvGlHM= github.com/projectcalico/go-yaml-wrapper v0.0.0-20161127220527-598e54215bee/go.mod h1:UgC0aTQ2KMDxlX3lU/stndk7DMUBJqzN40yFiILHgxc= +github.com/projectcalico/kube-controllers v3.8.8+incompatible h1:ZbCg0wJ+gd7i81CB6vOASiUN//oR4ZBl+wEdy0Vk1uI= +github.com/projectcalico/kube-controllers v3.8.8+incompatible/go.mod h1:ZEafKeKN5wiNARRw1LZP8l10uEfp04C7redU848MMZw= github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce h1:O/R67iwUe8TvZwgKbDB2cvF2/8L8PR4zVOcBtYEHD5Y= github.com/projectcalico/libcalico-go v1.7.2-0.20191104213956-8f81e1e344ce/go.mod h1:z4tuFqrAg/423AMSaDamY5LgqeOZ5ETui6iOxDwJ/ag= github.com/prometheus/client_golang v0.9.4 h1:Y8E/JaaPbmFSW2V81Ab/d8yZFYQQGbni1b1jPcG9Y6A= diff --git a/kustomize/network/OWNERS b/kustomize/network/OWNERS deleted file mode 100644 index 2dc932c86995ca61fc9be674b5abbbdbbfd8b85c..0000000000000000000000000000000000000000 --- a/kustomize/network/OWNERS +++ /dev/null @@ -1,11 +0,0 @@ -approvers: - - magicsong - - zheng1 - -reviewers: - - magicsong - - zheng1 - -labels: - - area/deploy - - area/networking \ No newline at end of file diff --git a/kustomize/network/calico-etcd/kustomization.yaml b/kustomize/network/calico-etcd/kustomization.yaml deleted file mode 100644 index a4f084cebee7cc2649d9648af4905cc9f70cf638..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/kustomization.yaml +++ /dev/null @@ -1,23 +0,0 @@ -bases: -- ../crds - -resources: - - network.yaml - - rbac/role.yaml - - rbac/role_binding.yaml - -generatorOptions: - disableNameSuffixHash: true - -secretGenerator: - - name: calico-etcd-secrets - files: - - etcd-ca=etcd/ca - - etcd-key=etcd/key - - etcd-cert=etcd/crt - type: Opaque - -patchesStrategicMerge: - - patch_image_name.yaml - -namespace: network-test-f22e8ea9 diff --git a/kustomize/network/calico-etcd/network.yaml b/kustomize/network/calico-etcd/network.yaml deleted file mode 100644 index 31fd47396a58c9cde90b0c6cda34fce66514fb69..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/network.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: network-system - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: network-manager - namespace: network-system - labels: - control-plane: network-manager -spec: - selector: - matchLabels: - control-plane: network-manager - replicas: 1 - template: - metadata: - labels: - control-plane: network-manager - spec: - nodeSelector: - node-role.kubernetes.io/master: "" - hostNetwork: true - tolerations: - - key: "CriticalAddonsOnly" - operator: "Exists" - - key: "node-role.kubernetes.io/master" - effect: NoSchedule - containers: - - command: - - /ks-network - args: - - -v=4 - - np-provider=calico - image: network:latest - imagePullPolicy: Always - name: manager - resources: - limits: - cpu: 100m - memory: 30Mi - requests: - cpu: 100m - memory: 20Mi - volumeMounts: - - mountPath: /calicocerts - name: etcd-certs - readOnly: true - terminationGracePeriodSeconds: 10 - volumes: - - name: etcd-certs - secret: - secretName: calico-etcd-secrets - defaultMode: 0400 diff --git a/kustomize/network/calico-etcd/patch_image_name.yaml b/kustomize/network/calico-etcd/patch_image_name.yaml deleted file mode 100644 index a6133c91bbb9b8697314a5697031b560e01c42c1..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/patch_image_name.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: network-manager - namespace: network-system -spec: - template: - spec: - containers: - # Change the value of image field below to your controller image URL - - image: magicsong/ks-network:f22e8ea9 - name: manager diff --git a/kustomize/network/calico-etcd/patch_role_binding.yaml b/kustomize/network/calico-etcd/patch_role_binding.yaml deleted file mode 100644 index d5b4a3a04bb638fbbd93b8a8e421907268af24a7..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/patch_role_binding.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: manager-rolebinding -subjects: -- kind: ServiceAccount - name: default - namespace: network-test-f22e8ea9 diff --git a/kustomize/network/calico-etcd/role.yaml b/kustomize/network/calico-etcd/role.yaml deleted file mode 100644 index 2828ab542c8a9042d5b753a7201ad8f8b4676840..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/role.yaml +++ /dev/null @@ -1,33 +0,0 @@ - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: network-manager -rules: -- apiGroups: - - network.kubesphere.io - resources: - - namespacenetworkpolicies - - workspacenetworkpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - tenant.kubesphere.io - resources: - - workspaces - verbs: - - create - - delete - - get - - list - - patch - - update - - watch diff --git a/kustomize/network/calico-etcd/role_binding.yaml b/kustomize/network/calico-etcd/role_binding.yaml deleted file mode 100644 index 9d4c056f772de150a963f56d1f81a3c31478acda..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-etcd/role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: net-manager-role -subjects: -- kind: ServiceAccount - name: default - namespace: network-system \ No newline at end of file diff --git a/kustomize/network/calico-k8s/kustomization.yaml b/kustomize/network/calico-k8s/kustomization.yaml deleted file mode 100644 index 5739564d04ec143fcd11a808dba4b2b1b1c5a328..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-k8s/kustomization.yaml +++ /dev/null @@ -1,11 +0,0 @@ -bases: -- ../crds - -resources: -- network.yaml -- role.yaml - -patchesStrategicMerge: - - patch_image_name.yaml - -namespace: network-test-f22e8ea9 diff --git a/kustomize/network/calico-k8s/network.yaml b/kustomize/network/calico-k8s/network.yaml deleted file mode 100644 index 418a01b60b92be84f5baf9548e70456fd0f97b9f..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-k8s/network.yaml +++ /dev/null @@ -1,69 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: network-system - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: network-manager - namespace: network-system - labels: - control-plane: network-manager -spec: - selector: - matchLabels: - control-plane: network-manager - replicas: 1 - template: - metadata: - labels: - control-plane: network-manager - spec: - nodeSelector: - node-role.kubernetes.io/master: "" - tolerations: - - key: "CriticalAddonsOnly" - operator: "Exists" - - key: "node-role.kubernetes.io/master" - effect: NoSchedule - serviceAccountName: network-manager - containers: - - command: - - /ks-network - args: - - -v=4 - - np-provider=calico - - datastore-type=k8s - image: network:latest - imagePullPolicy: Always - name: manager - resources: - limits: - cpu: 100m - memory: 30Mi - requests: - cpu: 100m - memory: 20Mi - terminationGracePeriodSeconds: 10 - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: net-role-binding - namespace: network-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: network-manager -subjects: -- kind: ServiceAccount - name: network-manager - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: network-manager \ No newline at end of file diff --git a/kustomize/network/calico-k8s/patch_image_name.yaml b/kustomize/network/calico-k8s/patch_image_name.yaml deleted file mode 100644 index a6133c91bbb9b8697314a5697031b560e01c42c1..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-k8s/patch_image_name.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: network-manager - namespace: network-system -spec: - template: - spec: - containers: - # Change the value of image field below to your controller image URL - - image: magicsong/ks-network:f22e8ea9 - name: manager diff --git a/kustomize/network/calico-k8s/patch_role_binding.yaml b/kustomize/network/calico-k8s/patch_role_binding.yaml deleted file mode 100644 index 07a52955d204866ed47b3d3b26a7f40fa050883c..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-k8s/patch_role_binding.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: net-role-binding -subjects: -- kind: ServiceAccount - name: network-manager - namespace: network-test-f22e8ea9 diff --git a/kustomize/network/calico-k8s/role.yaml b/kustomize/network/calico-k8s/role.yaml deleted file mode 100644 index b694ba90ae9b4cfa892657f42e9954db907f28d2..0000000000000000000000000000000000000000 --- a/kustomize/network/calico-k8s/role.yaml +++ /dev/null @@ -1,54 +0,0 @@ - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: network-manager -rules: -- apiGroups: - - crd.projectcalico.org - resources: - - clusterinformations - - felixconfigurations - - globalfelixconfigs - - globalnetworkpolicies - - globalnetworksets - - hostendpoints - - ipamblocks - - ippools - - networkpolicies - - networksets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - network.kubesphere.io - resources: - - namespacenetworkpolicies - - workspacenetworkpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - tenant.kubesphere.io - resources: - - workspaces - verbs: - - create - - delete - - get - - list - - patch - - update - - watch diff --git a/kustomize/network/crds/kustomization.yaml b/kustomize/network/crds/kustomization.yaml deleted file mode 100644 index 6b1ee9bf476c5a2089e9c278af6a5d858ad1d8e3..0000000000000000000000000000000000000000 --- a/kustomize/network/crds/kustomization.yaml +++ /dev/null @@ -1,3 +0,0 @@ -resources: - - wsnp.yaml - - nsnp.yaml \ No newline at end of file diff --git a/kustomize/network/crds/nsnp.yaml b/kustomize/network/crds/nsnp.yaml deleted file mode 100644 index 7061216a7405cf23acab7ac7fc1fb6e5c3985843..0000000000000000000000000000000000000000 --- a/kustomize/network/crds/nsnp.yaml +++ /dev/null @@ -1,711 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - creationTimestamp: null - name: namespacenetworkpolicies.network.kubesphere.io -spec: - group: network.kubesphere.io - names: - categories: - - networking - kind: NamespaceNetworkPolicy - plural: namespacenetworkpolicies - shortNames: - - nsnp - scope: Namespaced - validation: - openAPIV3Schema: - description: NamespaceNetworkPolicy is the Schema for the namespacenetworkpolicies - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: NamespaceNetworkPolicySpec defines the desired state of NamespaceNetworkPolicy - properties: - egress: - description: The ordered set of egress rules. Each rule contains a - set of packet match criteria and a corresponding action to apply. - items: - description: "A Rule encapsulates a set of match criteria and an action. - \ Both selector-based security Policy and security Profiles reference - rules - separated out as a list of rules for both ingress and egress - packet matching. \n Each positive match criteria has a negated version, - prefixed with ”Not”. All the match criteria within a rule must be - satisfied for a packet to match. A single rule can contain the positive - and negative version of a match and both must be satisfied for the - rule to match." - properties: - action: - type: string - destination: - description: Destination contains the match criteria that apply - to destination entity. - properties: - namespaceSelector: - description: "NamespaceSelector is an optional field that - contains a selector expression. Only traffic that originates - from (or terminates at) endpoints within the selected namespaces - will be matched. When both NamespaceSelector and Selector - are defined on the same rule, then only workload endpoints - that are matched by both selectors will be selected by the - rule. \n For NetworkPolicy, an empty NamespaceSelector implies - that the Selector is limited to selecting only workload - endpoints in the same namespace as the NetworkPolicy. \n - For GlobalNetworkPolicy, an empty NamespaceSelector implies - the Selector applies to workload endpoints across all namespaces." - type: string - nets: - description: Nets is an optional field that restricts the - rule to only apply to traffic that originates from (or terminates - at) IP addresses in any of the given subnets. - items: - type: string - type: array - notNets: - description: NotNets is the negated version of the Nets field. - items: - type: string - type: array - notPorts: - items: - type: object - x-kubernetes-int-or-string: true - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - description: NotPorts is the negated version of the Ports - field. Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to "TCP" or "UDP". - type: array - notSelector: - description: NotSelector is the negated version of the Selector - field. See Selector field for subtleties with negated selectors. - type: string - ports: - description: "Ports is an optional field that restricts the - rule to only apply to traffic that has a source (destination) - port that matches one of these ranges/values. This value - is a list of integers or strings that represent ranges of - ports. \n Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to \"TCP\" or \"UDP\"." - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - type: object - type: array - selector: - description: "Selector is an optional field that contains - a selector expression (see Policy for sample syntax). Only - traffic that originates from (terminates at) endpoints matching - the selector will be matched. \n Note that: in addition - to the negated version of the Selector (see NotSelector - below), the selector expression syntax itself supports negation. - \ The two types of negation are subtly different. One negates - the set of matched endpoints, the other negates the whole - match: \n \tSelector = \"!has(my_label)\" matches packets - that are from other Calico-controlled \tendpoints that do - not have the label “my_label”. \n \tNotSelector = \"has(my_label)\" - matches packets that are not from Calico-controlled \tendpoints - that do have the label “my_label”. \n The effect is that - the latter will accept packets from non-Calico sources whereas - the former is limited to packets from Calico-controlled - endpoints." - type: string - serviceAccounts: - description: ServiceAccounts is an optional field that restricts - the rule to only apply to traffic that originates from (or - terminates at) a pod running as a matching service account. - properties: - names: - description: Names is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - whose name is in the list. - items: - type: string - type: array - selector: - description: Selector is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - that matches the given label selector. If both Names - and Selector are specified then they are AND'ed. - type: string - type: object - type: object - http: - description: HTTP contains match criteria that apply to HTTP requests. - properties: - methods: - description: Methods is an optional field that restricts the - rule to apply only to HTTP requests that use one of the - listed HTTP Methods (e.g. GET, PUT, etc.) Multiple methods - are OR'd together. - items: - type: string - type: array - paths: - description: 'Paths is an optional field that restricts the - rule to apply to HTTP requests that use one of the listed - HTTP Paths. Multiple paths are OR''d together. e.g: - exact: - /foo - prefix: /bar NOTE: Each entry may ONLY specify either - a `exact` or a `prefix` match. The validator will check - for it.' - items: - description: 'HTTPPath specifies an HTTP path to match. - It may be either of the form: exact: : which matches - the path exactly or prefix: : which matches - the path prefix' - properties: - exact: - type: string - prefix: - type: string - type: object - type: array - type: object - icmp: - description: ICMP is an optional field that restricts the rule - to apply to a specific type and code of ICMP traffic. This - should only be specified if the Protocol field is set to "ICMP" - or "ICMPv6". - properties: - code: - description: Match on a specific ICMP code. If specified, - the Type value must also be specified. This is a technical - limitation imposed by the kernel’s iptables firewall, which - Calico uses to enforce the rule. - type: integer - type: - description: Match on a specific ICMP type. For example a - value of 8 refers to ICMP Echo Request (i.e. pings). - type: integer - type: object - ipVersion: - description: IPVersion is an optional field that restricts the - rule to only match a specific IP version. - type: integer - notICMP: - description: NotICMP is the negated version of the ICMP field. - properties: - code: - description: Match on a specific ICMP code. If specified, - the Type value must also be specified. This is a technical - limitation imposed by the kernel’s iptables firewall, which - Calico uses to enforce the rule. - type: integer - type: - description: Match on a specific ICMP type. For example a - value of 8 refers to ICMP Echo Request (i.e. pings). - type: integer - type: object - notProtocol: - description: NotProtocol is the negated version of the Protocol - field. - type: string - protocol: - description: "Protocol is an optional field that restricts the - rule to only apply to traffic of a specific IP protocol. Required - if any of the EntityRules contain Ports (because ports only - apply to certain protocols). \n Must be one of these string - values: \"TCP\", \"UDP\", \"ICMP\", \"ICMPv6\", \"SCTP\", \"UDPLite\" - or an integer in the range 1-255." - type: string - source: - description: Source contains the match criteria that apply to - source entity. - properties: - namespaceSelector: - description: "NamespaceSelector is an optional field that - contains a selector expression. Only traffic that originates - from (or terminates at) endpoints within the selected namespaces - will be matched. When both NamespaceSelector and Selector - are defined on the same rule, then only workload endpoints - that are matched by both selectors will be selected by the - rule. \n For NetworkPolicy, an empty NamespaceSelector implies - that the Selector is limited to selecting only workload - endpoints in the same namespace as the NetworkPolicy. \n - For GlobalNetworkPolicy, an empty NamespaceSelector implies - the Selector applies to workload endpoints across all namespaces." - type: string - nets: - description: Nets is an optional field that restricts the - rule to only apply to traffic that originates from (or terminates - at) IP addresses in any of the given subnets. - items: - type: string - type: array - notNets: - description: NotNets is the negated version of the Nets field. - items: - type: string - type: array - notPorts: - description: NotPorts is the negated version of the Ports - field. Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to "TCP" or "UDP". - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - type: object - type: array - notSelector: - description: NotSelector is the negated version of the Selector - field. See Selector field for subtleties with negated selectors. - type: string - ports: - description: "Ports is an optional field that restricts the - rule to only apply to traffic that has a source (destination) - port that matches one of these ranges/values. This value - is a list of integers or strings that represent ranges of - ports. \n Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to \"TCP\" or \"UDP\"." - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - type: object - type: array - selector: - description: "Selector is an optional field that contains - a selector expression (see Policy for sample syntax). Only - traffic that originates from (terminates at) endpoints matching - the selector will be matched. \n Note that: in addition - to the negated version of the Selector (see NotSelector - below), the selector expression syntax itself supports negation. - \ The two types of negation are subtly different. One negates - the set of matched endpoints, the other negates the whole - match: \n \tSelector = \"!has(my_label)\" matches packets - that are from other Calico-controlled \tendpoints that do - not have the label “my_label”. \n \tNotSelector = \"has(my_label)\" - matches packets that are not from Calico-controlled \tendpoints - that do have the label “my_label”. \n The effect is that - the latter will accept packets from non-Calico sources whereas - the former is limited to packets from Calico-controlled - endpoints." - type: string - serviceAccounts: - description: ServiceAccounts is an optional field that restricts - the rule to only apply to traffic that originates from (or - terminates at) a pod running as a matching service account. - properties: - names: - description: Names is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - whose name is in the list. - items: - type: string - type: array - selector: - description: Selector is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - that matches the given label selector. If both Names - and Selector are specified then they are AND'ed. - type: string - type: object - type: object - required: - - action - type: object - type: array - ingress: - description: The ordered set of ingress rules. Each rule contains a - set of packet match criteria and a corresponding action to apply. - items: - description: "A Rule encapsulates a set of match criteria and an action. - \ Both selector-based security Policy and security Profiles reference - rules - separated out as a list of rules for both ingress and egress - packet matching. \n Each positive match criteria has a negated version, - prefixed with ”Not”. All the match criteria within a rule must be - satisfied for a packet to match. A single rule can contain the positive - and negative version of a match and both must be satisfied for the - rule to match." - properties: - action: - type: string - destination: - description: Destination contains the match criteria that apply - to destination entity. - properties: - namespaceSelector: - description: "NamespaceSelector is an optional field that - contains a selector expression. Only traffic that originates - from (or terminates at) endpoints within the selected namespaces - will be matched. When both NamespaceSelector and Selector - are defined on the same rule, then only workload endpoints - that are matched by both selectors will be selected by the - rule. \n For NetworkPolicy, an empty NamespaceSelector implies - that the Selector is limited to selecting only workload - endpoints in the same namespace as the NetworkPolicy. \n - For GlobalNetworkPolicy, an empty NamespaceSelector implies - the Selector applies to workload endpoints across all namespaces." - type: string - nets: - description: Nets is an optional field that restricts the - rule to only apply to traffic that originates from (or terminates - at) IP addresses in any of the given subnets. - items: - type: string - type: array - notNets: - description: NotNets is the negated version of the Nets field. - items: - type: string - type: array - notPorts: - description: NotPorts is the negated version of the Ports - field. Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to "TCP" or "UDP". - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - anyOf: - - type: integer - - type: string - type: array - notSelector: - description: NotSelector is the negated version of the Selector - field. See Selector field for subtleties with negated selectors. - type: string - ports: - description: "Ports is an optional field that restricts the - rule to only apply to traffic that has a source (destination) - port that matches one of these ranges/values. This value - is a list of integers or strings that represent ranges of - ports. \n Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to \"TCP\" or \"UDP\"." - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - anyOf: - - type: integer - - type: string - type: array - selector: - description: "Selector is an optional field that contains - a selector expression (see Policy for sample syntax). Only - traffic that originates from (terminates at) endpoints matching - the selector will be matched. \n Note that: in addition - to the negated version of the Selector (see NotSelector - below), the selector expression syntax itself supports negation. - \ The two types of negation are subtly different. One negates - the set of matched endpoints, the other negates the whole - match: \n \tSelector = \"!has(my_label)\" matches packets - that are from other Calico-controlled \tendpoints that do - not have the label “my_label”. \n \tNotSelector = \"has(my_label)\" - matches packets that are not from Calico-controlled \tendpoints - that do have the label “my_label”. \n The effect is that - the latter will accept packets from non-Calico sources whereas - the former is limited to packets from Calico-controlled - endpoints." - type: string - serviceAccounts: - description: ServiceAccounts is an optional field that restricts - the rule to only apply to traffic that originates from (or - terminates at) a pod running as a matching service account. - properties: - names: - description: Names is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - whose name is in the list. - items: - type: string - type: array - selector: - description: Selector is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - that matches the given label selector. If both Names - and Selector are specified then they are AND'ed. - type: string - type: object - type: object - http: - description: HTTP contains match criteria that apply to HTTP requests. - properties: - methods: - description: Methods is an optional field that restricts the - rule to apply only to HTTP requests that use one of the - listed HTTP Methods (e.g. GET, PUT, etc.) Multiple methods - are OR'd together. - items: - type: string - type: array - paths: - description: 'Paths is an optional field that restricts the - rule to apply to HTTP requests that use one of the listed - HTTP Paths. Multiple paths are OR''d together. e.g: - exact: - /foo - prefix: /bar NOTE: Each entry may ONLY specify either - a `exact` or a `prefix` match. The validator will check - for it.' - items: - description: 'HTTPPath specifies an HTTP path to match. - It may be either of the form: exact: : which matches - the path exactly or prefix: : which matches - the path prefix' - properties: - exact: - type: string - prefix: - type: string - type: object - type: array - type: object - icmp: - description: ICMP is an optional field that restricts the rule - to apply to a specific type and code of ICMP traffic. This - should only be specified if the Protocol field is set to "ICMP" - or "ICMPv6". - properties: - code: - description: Match on a specific ICMP code. If specified, - the Type value must also be specified. This is a technical - limitation imposed by the kernel’s iptables firewall, which - Calico uses to enforce the rule. - type: integer - type: - description: Match on a specific ICMP type. For example a - value of 8 refers to ICMP Echo Request (i.e. pings). - type: integer - type: object - ipVersion: - description: IPVersion is an optional field that restricts the - rule to only match a specific IP version. - type: integer - notICMP: - description: NotICMP is the negated version of the ICMP field. - properties: - code: - description: Match on a specific ICMP code. If specified, - the Type value must also be specified. This is a technical - limitation imposed by the kernel’s iptables firewall, which - Calico uses to enforce the rule. - type: integer - type: - description: Match on a specific ICMP type. For example a - value of 8 refers to ICMP Echo Request (i.e. pings). - type: integer - type: object - notProtocol: - description: NotProtocol is the negated version of the Protocol - field. - type: string - protocol: - description: "Protocol is an optional field that restricts the - rule to only apply to traffic of a specific IP protocol. Required - if any of the EntityRules contain Ports (because ports only - apply to certain protocols). \n Must be one of these string - values: \"TCP\", \"UDP\", \"ICMP\", \"ICMPv6\", \"SCTP\", \"UDPLite\" - or an integer in the range 1-255." - type: string - source: - description: Source contains the match criteria that apply to - source entity. - properties: - namespaceSelector: - description: "NamespaceSelector is an optional field that - contains a selector expression. Only traffic that originates - from (or terminates at) endpoints within the selected namespaces - will be matched. When both NamespaceSelector and Selector - are defined on the same rule, then only workload endpoints - that are matched by both selectors will be selected by the - rule. \n For NetworkPolicy, an empty NamespaceSelector implies - that the Selector is limited to selecting only workload - endpoints in the same namespace as the NetworkPolicy. \n - For GlobalNetworkPolicy, an empty NamespaceSelector implies - the Selector applies to workload endpoints across all namespaces." - type: string - nets: - description: Nets is an optional field that restricts the - rule to only apply to traffic that originates from (or terminates - at) IP addresses in any of the given subnets. - items: - type: string - type: array - notNets: - description: NotNets is the negated version of the Nets field. - items: - type: string - type: array - notPorts: - description: NotPorts is the negated version of the Ports - field. Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to "TCP" or "UDP". - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - type: object - type: array - notSelector: - description: NotSelector is the negated version of the Selector - field. See Selector field for subtleties with negated selectors. - type: string - ports: - description: "Ports is an optional field that restricts the - rule to only apply to traffic that has a source (destination) - port that matches one of these ranges/values. This value - is a list of integers or strings that represent ranges of - ports. \n Since only some protocols have ports, if any ports - are specified it requires the Protocol match in the Rule - to be set to \"TCP\" or \"UDP\"." - items: - description: "Port represents either a range of numeric - ports or a named port. \n - For a named port, set - the PortName, leaving MinPort and MaxPort as 0. - - For a port range, set MinPort and MaxPort to the (inclusive) - port numbers. Set PortName to \"\". - For a - single port, set MinPort = MaxPort and PortName = \"\"." - x-kubernetes-int-or-string: true - anyOf: - - type: integer - - type: string - type: object - type: array - selector: - description: "Selector is an optional field that contains - a selector expression (see Policy for sample syntax). Only - traffic that originates from (terminates at) endpoints matching - the selector will be matched. \n Note that: in addition - to the negated version of the Selector (see NotSelector - below), the selector expression syntax itself supports negation. - \ The two types of negation are subtly different. One negates - the set of matched endpoints, the other negates the whole - match: \n \tSelector = \"!has(my_label)\" matches packets - that are from other Calico-controlled \tendpoints that do - not have the label “my_label”. \n \tNotSelector = \"has(my_label)\" - matches packets that are not from Calico-controlled \tendpoints - that do have the label “my_label”. \n The effect is that - the latter will accept packets from non-Calico sources whereas - the former is limited to packets from Calico-controlled - endpoints." - type: string - serviceAccounts: - description: ServiceAccounts is an optional field that restricts - the rule to only apply to traffic that originates from (or - terminates at) a pod running as a matching service account. - properties: - names: - description: Names is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - whose name is in the list. - items: - type: string - type: array - selector: - description: Selector is an optional field that restricts - the rule to only apply to traffic that originates from - (or terminates at) a pod running as a service account - that matches the given label selector. If both Names - and Selector are specified then they are AND'ed. - type: string - type: object - type: object - required: - - action - type: object - type: array - order: - description: Order is an optional field that specifies the order in - which the policy is applied. Policies with higher "order" are applied - after those with lower order. If the order is omitted, it may be - considered to be "infinite" - i.e. the policy will be applied last. Policies - with identical order will be applied in alphanumerical order based - on the Policy "Name". - type: integer - selector: - description: "The selector is an expression used to pick pick out the - endpoints that the policy should be applied to. \n Selector expressions - follow this syntax: \n \tlabel == \"string_literal\" -> comparison, - e.g. my_label == \"foo bar\" \tlabel != \"string_literal\" -> not - equal; also matches if label is not present \tlabel in { \"a\", \"b\", - \"c\", ... } -> true if the value of label X is one of \"a\", \"b\", - \"c\" \tlabel not in { \"a\", \"b\", \"c\", ... } -> true if the - value of label X is not one of \"a\", \"b\", \"c\" \thas(label_name) - \ -> True if that label is present \t! expr -> negation of expr \texpr - && expr -> Short-circuit and \texpr || expr -> Short-circuit or - \t( expr ) -> parens for grouping \tall() or the empty selector -> - matches all endpoints. \n Label names are allowed to contain alphanumerics, - -, _ and /. String literals are more permissive but they do not support - escape characters. \n Examples (with made-up labels): \n \ttype == - \"webserver\" && deployment == \"prod\" \ttype in {\"frontend\", \"backend\"} - \tdeployment != \"dev\" \t! has(label_name)" - type: string - types: - description: "Types indicates whether this policy applies to ingress, - or to egress, or to both. When not explicitly specified (and so the - value on creation is empty or nil), Calico defaults Types according - to what Ingress and Egress are present in the policy. The default - is: \n - [ PolicyTypeIngress ], if there are no Egress rules (including - the case where there are also no Ingress rules) \n - [ PolicyTypeEgress - ], if there are Egress rules but no Ingress rules \n - [ PolicyTypeIngress, - PolicyTypeEgress ], if there are both Ingress and Egress rules. \n - When the policy is read back again, Types will always be one of these - values, never empty or nil." - items: - type: string - type: array - required: - - selector - type: object - type: object - version: v1alpha1 -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/kustomize/network/crds/wsnp.yaml b/kustomize/network/crds/wsnp.yaml deleted file mode 100644 index d434fe506f19962af9e8e97e4857c641b287b983..0000000000000000000000000000000000000000 --- a/kustomize/network/crds/wsnp.yaml +++ /dev/null @@ -1,523 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - creationTimestamp: null - name: workspacenetworkpolicies.network.kubesphere.io -spec: - group: network.kubesphere.io - names: - categories: - - networking - kind: WorkspaceNetworkPolicy - plural: workspacenetworkpolicies - shortNames: - - wsnp - scope: Cluster - validation: - openAPIV3Schema: - description: WorkspaceNetworkPolicy is a set of network policies applied to - the scope to workspace - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: WorkspaceNetworkPolicySpec defines the desired state of WorkspaceNetworkPolicy - properties: - egress: - description: List of egress rules to be applied to the selected pods. - Outgoing traffic is allowed if there are no NetworkPolicies selecting - the pod (and cluster policy otherwise allows the traffic), OR if the - traffic matches at least one egress rule across all of the NetworkPolicy - objects whose podSelector matches the pod. If this field is empty - then this NetworkPolicy limits all outgoing traffic (and serves solely - to ensure that the pods it selects are isolated by default). This - field is beta-level in 1.8 - items: - description: WorkspaceNetworkPolicyEgressRule describes a particular - set of traffic that is allowed out of pods matched by a WorkspaceNetworkPolicySpec's - podSelector. The traffic must match both ports and to. - properties: - from: - description: List of sources which should be able to access the - pods selected for this rule. Items in this list are combined - using a logical OR operation. If this field is empty or missing, - this rule matches all sources (traffic not restricted by source). - If this field is present and contains at least on item, this - rule allows traffic only if the traffic matches at least one - item in the from list. - items: - description: WorkspaceNetworkPolicyPeer describes a peer to - allow traffic from. Only certain combinations of fields are - allowed. It is same as 'NetworkPolicyPeer' in k8s but with - an additional field 'WorkspaceSelector' - properties: - ipBlock: - description: IPBlock defines policy on a particular IPBlock. - If this field is set then neither of the other fields - can be. - properties: - cidr: - description: CIDR is a string representing the IP Block - Valid examples are "192.168.1.1/24" - type: string - except: - description: Except is a slice of CIDRs that should - not be included within an IP Block Valid examples - are "192.168.1.1/24" Except values will be rejected - if they are outside the CIDR range - items: - type: string - type: array - required: - - cidr - type: object - namespaceSelector: - description: "Selects Namespaces using cluster-scoped labels. - This field follows standard label selector semantics; - if present but empty, it selects all namespaces. \n If - PodSelector is also set, then the NetworkPolicyPeer as - a whole selects the Pods matching PodSelector in the Namespaces - selected by NamespaceSelector. Otherwise it selects all - Pods in the Namespaces selected by NamespaceSelector." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - podSelector: - description: "This is a label selector which selects Pods. - This field follows standard label selector semantics; - if present but empty, it selects all pods. \n If NamespaceSelector - is also set, then the NetworkPolicyPeer as a whole selects - the Pods matching PodSelector in the Namespaces selected - by NamespaceSelector. Otherwise it selects the Pods matching - PodSelector in the policy's own Namespace." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - workspaceSelector: - description: A label selector is a label query over a set - of resources. The result of matchLabels and matchExpressions - are ANDed. An empty label selector matches all objects. - A null label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible on - the pods selected for this rule. Each item in this list is combined - using a logical OR. If this field is empty or missing, this - rule matches all ports (traffic not restricted by port). If - this field is present and contains at least one item, then this - rule allows traffic only if the traffic matches at least one - port in the list. - items: - description: NetworkPolicyPort describes a port to allow traffic - on - properties: - port: - anyOf: - - type: string - - type: integer - description: The port on the given protocol. This can either - be a numerical or named port on a pod. If this field is - not provided, this matches all port names and numbers. - protocol: - description: The protocol (TCP, UDP, or SCTP) which traffic - must match. If not specified, this field defaults to TCP. - type: string - type: object - type: array - type: object - type: array - ingress: - description: List of ingress rules to be applied to the selected pods. - Traffic is allowed to a pod if there are no NetworkPolicies selecting - the pod (and cluster policy otherwise allows the traffic), OR if the - traffic source is the pod's local node, OR if the traffic matches - at least one ingress rule across all of the NetworkPolicy objects - whose podSelector matches the pod. If this field is empty then this - NetworkPolicy does not allow any traffic (and serves solely to ensure - that the pods it selects are isolated by default) - items: - description: WorkspaceNetworkPolicyIngressRule describes a particular - set of traffic that is allowed to the pods matched by a WorkspaceNetworkPolicySpec's - podSelector. The traffic must match both ports and from. - properties: - from: - description: List of sources which should be able to access the - pods selected for this rule. Items in this list are combined - using a logical OR operation. If this field is empty or missing, - this rule matches all sources (traffic not restricted by source). - If this field is present and contains at least on item, this - rule allows traffic only if the traffic matches at least one - item in the from list. - items: - description: WorkspaceNetworkPolicyPeer describes a peer to - allow traffic from. Only certain combinations of fields are - allowed. It is same as 'NetworkPolicyPeer' in k8s but with - an additional field 'WorkspaceSelector' - properties: - ipBlock: - description: IPBlock defines policy on a particular IPBlock. - If this field is set then neither of the other fields - can be. - properties: - cidr: - description: CIDR is a string representing the IP Block - Valid examples are "192.168.1.1/24" - type: string - except: - description: Except is a slice of CIDRs that should - not be included within an IP Block Valid examples - are "192.168.1.1/24" Except values will be rejected - if they are outside the CIDR range - items: - type: string - type: array - required: - - cidr - type: object - namespaceSelector: - description: "Selects Namespaces using cluster-scoped labels. - This field follows standard label selector semantics; - if present but empty, it selects all namespaces. \n If - PodSelector is also set, then the NetworkPolicyPeer as - a whole selects the Pods matching PodSelector in the Namespaces - selected by NamespaceSelector. Otherwise it selects all - Pods in the Namespaces selected by NamespaceSelector." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - podSelector: - description: "This is a label selector which selects Pods. - This field follows standard label selector semantics; - if present but empty, it selects all pods. \n If NamespaceSelector - is also set, then the NetworkPolicyPeer as a whole selects - the Pods matching PodSelector in the Namespaces selected - by NamespaceSelector. Otherwise it selects the Pods matching - PodSelector in the policy's own Namespace." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - workspaceSelector: - description: A label selector is a label query over a set - of resources. The result of matchLabels and matchExpressions - are ANDed. An empty label selector matches all objects. - A null label selector matches no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists - or DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - type: object - type: array - ports: - description: List of ports which should be made accessible on - the pods selected for this rule. Each item in this list is combined - using a logical OR. If this field is empty or missing, this - rule matches all ports (traffic not restricted by port). If - this field is present and contains at least one item, then this - rule allows traffic only if the traffic matches at least one - port in the list. - items: - description: NetworkPolicyPort describes a port to allow traffic - on - properties: - port: - anyOf: - - type: string - - type: integer - description: The port on the given protocol. This can either - be a numerical or named port on a pod. If this field is - not provided, this matches all port names and numbers. - protocol: - description: The protocol (TCP, UDP, or SCTP) which traffic - must match. If not specified, this field defaults to TCP. - type: string - type: object - type: array - type: object - type: array - policyTypes: - description: List of rule types that the WorkspaceNetworkPolicy relates - to. Valid options are Ingress, Egress, or Ingress,Egress. If this - field is not specified, it will default based on the existence of - Ingress or Egress rules; policies that contain an Egress section are - assumed to affect Egress, and all policies (whether or not they contain - an Ingress section) are assumed to affect Ingress. If you want to - write an egress-only policy, you must explicitly specify policyTypes - [ "Egress" ]. Likewise, if you want to write a policy that specifies - that no egress is allowed, you must specify a policyTypes value that - include "Egress" (since such a policy would not include an Egress - section and would otherwise default to just [ "Ingress" ]). - items: - description: Policy Type string describes the NetworkPolicy type This - type is beta-level in 1.8 - type: string - type: array - workspace: - description: Workspace specify the name of ws to apply this workspace - network policy - type: string - type: object - status: - description: WorkspaceNetworkPolicyStatus defines the observed state of - WorkspaceNetworkPolicy - type: object - type: object - version: v1alpha1 -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/kustomize/network/rbac/role.yaml b/kustomize/network/rbac/role.yaml deleted file mode 100644 index 41a5a7cf5461a409aa8f7f04166abb7542bd6ad1..0000000000000000000000000000000000000000 --- a/kustomize/network/rbac/role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: net-manager-role -rules: -- apiGroups: - - network.kubesphere.io - resources: - - namespacenetworkpolicies - - workspacenetworkpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - tenant.kubesphere.io - resources: - - workspaces - verbs: - - create - - delete - - get - - list - - patch - - update - - watch diff --git a/pkg/apis/network/v1alpha1/common.go b/pkg/apis/network/v1alpha1/common.go deleted file mode 100644 index 50fa9f70622ed25a77d741178668ff21496b593e..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/common.go +++ /dev/null @@ -1,170 +0,0 @@ -package v1alpha1 - -import ( - corev1 "k8s.io/api/core/v1" - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1/numorstring" -) - -// A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy -// and security Profiles reference rules - separated out as a list of rules for both -// ingress and egress packet matching. -// -// Each positive match criteria has a negated version, prefixed with ”Not”. All the match -// criteria within a rule must be satisfied for a packet to match. A single rule can contain -// the positive and negative version of a match and both must be satisfied for the rule to match. -type Rule struct { - Action Action `json:"action" validate:"action"` - // IPVersion is an optional field that restricts the rule to only match a specific IP - // version. - IPVersion *int `json:"ipVersion,omitempty" validate:"omitempty,ipVersion"` - // Protocol is an optional field that restricts the rule to only apply to traffic of - // a specific IP protocol. Required if any of the EntityRules contain Ports - // (because ports only apply to certain protocols). - // - // Must be one of these string values: "TCP", "UDP", "ICMP", "ICMPv6", "SCTP", "UDPLite" - // or an integer in the range 1-255. - Protocol *corev1.Protocol `json:"protocol,omitempty" validate:"omitempty"` - // ICMP is an optional field that restricts the rule to apply to a specific type and - // code of ICMP traffic. This should only be specified if the Protocol field is set to - // "ICMP" or "ICMPv6". - ICMP *ICMPFields `json:"icmp,omitempty" validate:"omitempty"` - // NotProtocol is the negated version of the Protocol field. - NotProtocol *corev1.Protocol `json:"notProtocol,omitempty" validate:"omitempty"` - // NotICMP is the negated version of the ICMP field. - NotICMP *ICMPFields `json:"notICMP,omitempty" validate:"omitempty"` - // Source contains the match criteria that apply to source entity. - Source EntityRule `json:"source,omitempty" validate:"omitempty"` - // Destination contains the match criteria that apply to destination entity. - Destination EntityRule `json:"destination,omitempty" validate:"omitempty"` - - // HTTP contains match criteria that apply to HTTP requests. - HTTP *HTTPMatch `json:"http,omitempty" validate:"omitempty"` -} - -// HTTPPath specifies an HTTP path to match. It may be either of the form: -// exact: : which matches the path exactly or -// prefix: : which matches the path prefix -type HTTPPath struct { - Exact string `json:"exact,omitempty" validate:"omitempty"` - Prefix string `json:"prefix,omitempty" validate:"omitempty"` -} - -// HTTPMatch is an optional field that apply only to HTTP requests -// The Methods and Path fields are joined with AND -type HTTPMatch struct { - // Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed - // HTTP Methods (e.g. GET, PUT, etc.) - // Multiple methods are OR'd together. - Methods []string `json:"methods,omitempty" validate:"omitempty"` - // Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed - // HTTP Paths. - // Multiple paths are OR'd together. - // e.g: - // - exact: /foo - // - prefix: /bar - // NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it. - Paths []HTTPPath `json:"paths,omitempty" validate:"omitempty"` -} - -// ICMPFields defines structure for ICMP and NotICMP sub-struct for ICMP code and type -type ICMPFields struct { - // Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request - // (i.e. pings). - Type *int `json:"type,omitempty" validate:"omitempty,gte=0,lte=254"` - // Match on a specific ICMP code. If specified, the Type value must also be specified. - // This is a technical limitation imposed by the kernel’s iptables firewall, which - // Calico uses to enforce the rule. - Code *int `json:"code,omitempty" validate:"omitempty,gte=0,lte=255"` -} - -// An EntityRule is a sub-component of a Rule comprising the match criteria specific -// to a particular entity (that is either the source or destination). -// -// A source EntityRule matches the source endpoint and originating traffic. -// A destination EntityRule matches the destination endpoint and terminating traffic. -type EntityRule struct { - // Nets is an optional field that restricts the rule to only apply to traffic that - // originates from (or terminates at) IP addresses in any of the given subnets. - Nets []string `json:"nets,omitempty" validate:"omitempty,dive,net"` - - // Selector is an optional field that contains a selector expression (see Policy for - // sample syntax). Only traffic that originates from (terminates at) endpoints matching - // the selector will be matched. - // - // Note that: in addition to the negated version of the Selector (see NotSelector below), the - // selector expression syntax itself supports negation. The two types of negation are subtly - // different. One negates the set of matched endpoints, the other negates the whole match: - // - // Selector = "!has(my_label)" matches packets that are from other Calico-controlled - // endpoints that do not have the label “my_label”. - // - // NotSelector = "has(my_label)" matches packets that are not from Calico-controlled - // endpoints that do have the label “my_label”. - // - // The effect is that the latter will accept packets from non-Calico sources whereas the - // former is limited to packets from Calico-controlled endpoints. - Selector string `json:"selector,omitempty" validate:"omitempty,selector"` - - // NamespaceSelector is an optional field that contains a selector expression. Only traffic - // that originates from (or terminates at) endpoints within the selected namespaces will be - // matched. When both NamespaceSelector and Selector are defined on the same rule, then only - // workload endpoints that are matched by both selectors will be selected by the rule. - // - // For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting - // only workload endpoints in the same namespace as the NetworkPolicy. - // - // For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload - // endpoints across all namespaces. - NamespaceSelector string `json:"namespaceSelector,omitempty" validate:"omitempty,selector"` - - // Ports is an optional field that restricts the rule to only apply to traffic that has a - // source (destination) port that matches one of these ranges/values. This value is a - // list of integers or strings that represent ranges of ports. - // - // Since only some protocols have ports, if any ports are specified it requires the - // Protocol match in the Rule to be set to "TCP" or "UDP". - Ports []numorstring.Port `json:"ports,omitempty" validate:"omitempty,dive"` - - // NotNets is the negated version of the Nets field. - NotNets []string `json:"notNets,omitempty" validate:"omitempty,dive,net"` - - // NotSelector is the negated version of the Selector field. See Selector field for - // subtleties with negated selectors. - NotSelector string `json:"notSelector,omitempty" validate:"omitempty,selector"` - - // NotPorts is the negated version of the Ports field. - // Since only some protocols have ports, if any ports are specified it requires the - // Protocol match in the Rule to be set to "TCP" or "UDP". - NotPorts []numorstring.Port `json:"notPorts,omitempty" validate:"omitempty,dive"` - - // ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or - // terminates at) a pod running as a matching service account. - ServiceAccounts *ServiceAccountMatch `json:"serviceAccounts,omitempty" validate:"omitempty"` -} - -type ServiceAccountMatch struct { - // Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates - // at) a pod running as a service account whose name is in the list. - Names []string `json:"names,omitempty" validate:"omitempty"` - - // Selector is an optional field that restricts the rule to only apply to traffic that originates from - // (or terminates at) a pod running as a service account that matches the given label selector. - // If both Names and Selector are specified then they are AND'ed. - Selector string `json:"selector,omitempty" validate:"omitempty,selector"` -} - -type Action string - -const ( - Allow Action = "Allow" - Deny = "Deny" - Log = "Log" - Pass = "Pass" -) - -type PolicyType string - -const ( - PolicyTypeIngress PolicyType = "Ingress" - PolicyTypeEgress PolicyType = "Egress" -) diff --git a/pkg/apis/network/v1alpha1/namespacenetworkpolicy_types.go b/pkg/apis/network/v1alpha1/namespacenetworkpolicy_types.go index d8ab00bb62c0273c8caeb1fb023cde14a6e7e4ac..3e674e0723da4ac5bb7d4f97abc23740bb2e134c 100644 --- a/pkg/apis/network/v1alpha1/namespacenetworkpolicy_types.go +++ b/pkg/apis/network/v1alpha1/namespacenetworkpolicy_types.go @@ -17,68 +17,114 @@ limitations under the License. package v1alpha1 import ( + k8snet "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// All types in this file is copy from calicoapi as we use calico to policy +const ( + ResourceKindNamespaceNetworkPolicy = "NamespaceNetworkPolicy" + ResourceSingularNamespaceNetworkPolicy = "namespacenetworkpolicy" + ResourcePluralNamespaceNetworkPolicy = "namespacenetworkpolicies" +) -// NamespaceNetworkPolicySpec defines the desired state of NamespaceNetworkPolicy +// NamespaceNetworkPolicySpec provides the specification of a NamespaceNetworkPolicy type NamespaceNetworkPolicySpec struct { - // Order is an optional field that specifies the order in which the policy is applied. - // Policies with higher "order" are applied after those with lower - // order. If the order is omitted, it may be considered to be "infinite" - i.e. the - // policy will be applied last. Policies with identical order will be applied in - // alphanumerical order based on the Policy "Name". - Order *int `json:"order,omitempty"` - // The ordered set of ingress rules. Each rule contains a set of packet match criteria and - // a corresponding action to apply. - Ingress []Rule `json:"ingress,omitempty" validate:"omitempty,dive"` - // The ordered set of egress rules. Each rule contains a set of packet match criteria and - // a corresponding action to apply. - Egress []Rule `json:"egress,omitempty" validate:"omitempty,dive"` - // The selector is an expression used to pick pick out the endpoints that the policy should - // be applied to. - // - // Selector expressions follow this syntax: - // - // label == "string_literal" -> comparison, e.g. my_label == "foo bar" - // label != "string_literal" -> not equal; also matches if label is not present - // label in { "a", "b", "c", ... } -> true if the value of label X is one of "a", "b", "c" - // label not in { "a", "b", "c", ... } -> true if the value of label X is not one of "a", "b", "c" - // has(label_name) -> True if that label is present - // ! expr -> negation of expr - // expr && expr -> Short-circuit and - // expr || expr -> Short-circuit or - // ( expr ) -> parens for grouping - // all() or the empty selector -> matches all endpoints. - // - // Label names are allowed to contain alphanumerics, -, _ and /. String literals are more permissive - // but they do not support escape characters. - // - // Examples (with made-up labels): - // - // type == "webserver" && deployment == "prod" - // type in {"frontend", "backend"} - // deployment != "dev" - // ! has(label_name) - Selector string `json:"selector" validate:"selector"` - // Types indicates whether this policy applies to ingress, or to egress, or to both. When - // not explicitly specified (and so the value on creation is empty or nil), Calico defaults - // Types according to what Ingress and Egress are present in the policy. The - // default is: - // - // - [ PolicyTypeIngress ], if there are no Egress rules (including the case where there are - // also no Ingress rules) - // - // - [ PolicyTypeEgress ], if there are Egress rules but no Ingress rules - // - // - [ PolicyTypeIngress, PolicyTypeEgress ], if there are both Ingress and Egress rules. - // - // When the policy is read back again, Types will always be one of these values, never empty - // or nil. - Types []PolicyType `json:"types,omitempty" validate:"omitempty,dive,policyType"` - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + // List of ingress rules to be applied to the selected pods. Traffic is allowed to + // a pod if there are no NetworkPolicies selecting the pod + // (and cluster policy otherwise allows the traffic), OR if the traffic source is + // the pod's local node, OR if the traffic matches at least one ingress rule + // across all of the NetworkPolicy objects whose podSelector matches the pod. If + // this field is empty then this NetworkPolicy does not allow any traffic (and serves + // solely to ensure that the pods it selects are isolated by default) + // +optional + Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` + + // List of egress rules to be applied to the selected pods. Outgoing traffic is + // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // otherwise allows the traffic), OR if the traffic matches at least one egress rule + // across all of the NetworkPolicy objects whose podSelector matches the pod. If + // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves + // solely to ensure that the pods it selects are isolated by default). + // This field is beta-level in 1.8 + // +optional + Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,2,rep,name=egress"` + + // List of rule types that the NetworkPolicy relates to. + // Valid options are "Ingress", "Egress", or "Ingress,Egress". + // If this field is not specified, it will default based on the existence of Ingress or Egress rules; + // policies that contain an Egress section are assumed to affect Egress, and all policies + // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. + // Likewise, if you want to write a policy that specifies that no egress is allowed, + // you must specify a policyTypes value that include "Egress" (since such a policy would not include + // an Egress section and would otherwise default to just [ "Ingress" ]). + // This field is beta-level in 1.8 + // +optional + PolicyTypes []k8snet.PolicyType `json:"policyTypes,omitempty" protobuf:"bytes,3,rep,name=policyTypes,casttype=PolicyType"` +} + +// NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods +// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. +type NetworkPolicyIngressRule struct { + // List of ports which should be made accessible on the pods selected for this + // rule. Each item in this list is combined using a logical OR. If this field is + // empty or missing, this rule matches all ports (traffic not restricted by port). + // If this field is present and contains at least one item, then this rule allows + // traffic only if the traffic matches at least one port in the list. + // +optional + Ports []k8snet.NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` + + // List of sources which should be able to access the pods selected for this rule. + // Items in this list are combined using a logical OR operation. If this field is + // empty or missing, this rule matches all sources (traffic not restricted by + // source). If this field is present and contains at least one item, this rule + // allows traffic only if the traffic matches at least one item in the from list. + // +optional + From []NetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` +} + +// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods +// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. +// This type is beta-level in 1.8 +type NetworkPolicyEgressRule struct { + // List of destination ports for outgoing traffic. + // Each item in this list is combined using a logical OR. If this field is + // empty or missing, this rule matches all ports (traffic not restricted by port). + // If this field is present and contains at least one item, then this rule allows + // traffic only if the traffic matches at least one port in the list. + // +optional + Ports []k8snet.NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` + + // List of destinations for outgoing traffic of pods selected for this rule. + // Items in this list are combined using a logical OR operation. If this field is + // empty or missing, this rule matches all destinations (traffic not restricted by + // destination). If this field is present and contains at least one item, this rule + // allows traffic only if the traffic matches at least one item in the to list. + // +optional + To []NetworkPolicyPeer `json:"to,omitempty" protobuf:"bytes,2,rep,name=to"` +} + +type NamespaceSelector struct { + Name string `json:"name" protobuf:"bytes,1,name=name"` +} + +type ServiceSelector struct { + Name string `json:"name" protobuf:"bytes,1,name=name"` + Namespace string `json:"namespace" protobuf:"bytes,2,name=namespace"` +} + +// NetworkPolicyPeer describes a peer to allow traffic from. Only certain combinations of +// fields are allowed +type NetworkPolicyPeer struct { + // +optional + NamespaceSelector *NamespaceSelector `json:"namespace,omitempty" protobuf:"bytes,1,opt,name=namespace"` + + // IPBlock defines policy on a particular IPBlock. If this field is set then + // neither of the other fields can be. + // +optional + IPBlock *k8snet.IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,2,rep,name=ipBlock"` + + ServiceSelector *ServiceSelector `json:"service,omitempty" protobuf:"bytes,3,opt,name=service"` } // +genclient diff --git a/pkg/apis/network/v1alpha1/numorstring/asnumber.go b/pkg/apis/network/v1alpha1/numorstring/asnumber.go deleted file mode 100644 index 9ff706d624517dc680722eac9bb217c8cf6502f9..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/asnumber.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2016 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 numorstring - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" -) - -type ASNumber uint32 - -// ASNumberFromString creates an ASNumber struct from a string value. The -// string value may simply be a number or may be the ASN in dotted notation. -func ASNumberFromString(s string) (ASNumber, error) { - if num, err := strconv.ParseUint(s, 10, 32); err == nil { - return ASNumber(num), nil - } - - parts := strings.Split(s, ".") - if len(parts) != 2 { - msg := fmt.Sprintf("invalid AS Number format (%s)", s) - return 0, errors.New(msg) - } - - if num1, err := strconv.ParseUint(parts[0], 10, 16); err != nil { - msg := fmt.Sprintf("invalid AS Number format (%s)", s) - return 0, errors.New(msg) - } else if num2, err := strconv.ParseUint(parts[1], 10, 16); err != nil { - msg := fmt.Sprintf("invalid AS Number format (%s)", s) - return 0, errors.New(msg) - } else { - return ASNumber((num1 << 16) + num2), nil - } -} - -// UnmarshalJSON implements the json.Unmarshaller uinterface. -func (a *ASNumber) UnmarshalJSON(b []byte) error { - if err := json.Unmarshal(b, (*uint32)(a)); err == nil { - return nil - } else { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - if v, err := ASNumberFromString(s); err != nil { - return err - } else { - *a = v - return nil - } - } -} - -// String returns the string value, or the Itoa of the uint value. -func (a ASNumber) String() string { - return strconv.FormatUint(uint64(a), 10) -} diff --git a/pkg/apis/network/v1alpha1/numorstring/doc.go b/pkg/apis/network/v1alpha1/numorstring/doc.go deleted file mode 100644 index f37ce6efc34bae7fe3466bf27860f07e0fd597ef..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2016 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 numorstring implements a set of type definitions that in YAML or JSON -format may be represented by either a number or a string. -*/ -package numorstring diff --git a/pkg/apis/network/v1alpha1/numorstring/numorstring_suite_test.go b/pkg/apis/network/v1alpha1/numorstring/numorstring_suite_test.go deleted file mode 100644 index 68a29fd7295c6c418c6a9edda089a7a4f4ef7674..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/numorstring_suite_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2016,2018 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 numorstring_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "testing" -) - -func TestNumorstring(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Numorstring Suite") -} diff --git a/pkg/apis/network/v1alpha1/numorstring/numorstring_test.go b/pkg/apis/network/v1alpha1/numorstring/numorstring_test.go deleted file mode 100644 index c12270db08b577137ac95a39d9afacf4c443bf1b..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/numorstring_test.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) 2016-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 numorstring_test - -import ( - "encoding/json" - "fmt" - "reflect" - - . "github.com/onsi/ginkgo/extensions/table" - . "github.com/onsi/gomega" - "github.com/projectcalico/libcalico-go/lib/numorstring" -) - -func init() { - - asNumberType := reflect.TypeOf(numorstring.ASNumber(0)) - protocolType := reflect.TypeOf(numorstring.Protocol{}) - portType := reflect.TypeOf(numorstring.Port{}) - - // Perform tests of JSON unmarshaling of the various field types. - DescribeTable("NumOrStringJSONUnmarshaling", - func(jtext string, typ reflect.Type, expected interface{}) { - // Create a new field type and invoke the unmarshaller interface - // directly (this covers a couple more error cases than calling - // through json.Unmarshal. - new := reflect.New(typ) - u := new.Interface().(json.Unmarshaler) - err := u.UnmarshalJSON([]byte(jtext)) - - if expected != nil { - Expect(err).To(BeNil(), - "expected json unmarshal to not error") - Expect(new.Elem().Interface()).To(Equal(expected), - "expected value not same as json unmarshalled value") - } else { - Expect(err).ToNot(BeNil(), - "expected json unmarshal to error") - } - }, - // ASNumber tests. - Entry("should accept 0 AS number as int", "0", asNumberType, numorstring.ASNumber(0)), - Entry("should accept 4294967295 AS number as int", "4294967295", asNumberType, numorstring.ASNumber(4294967295)), - Entry("should accept 0 AS number as string", "\"0\"", asNumberType, numorstring.ASNumber(0)), - Entry("should accept 4294967295 AS number as string", "\"4294967295\"", asNumberType, numorstring.ASNumber(4294967295)), - Entry("should accept 1.10 AS number as string", "\"1.10\"", asNumberType, numorstring.ASNumber(65546)), - Entry("should accept 00.00 AS number as string", "\"00.00\"", asNumberType, numorstring.ASNumber(0)), - Entry("should accept 00.01 AS number as string", "\"00.01\"", asNumberType, numorstring.ASNumber(1)), - Entry("should accept 65535.65535 AS number as string", "\"65535.65535\"", asNumberType, numorstring.ASNumber(4294967295)), - Entry("should reject 1.1.1 AS number as string", "\"1.1.1\"", asNumberType, nil), - Entry("should reject 65536.65535 AS number as string", "\"65536.65535\"", asNumberType, nil), - Entry("should reject 65535.65536 AS number as string", "\"65535.65536\"", asNumberType, nil), - Entry("should reject 0.-1 AS number as string", "\"0.-1\"", asNumberType, nil), - Entry("should reject -1 AS number as int", "-1", asNumberType, nil), - Entry("should reject 4294967296 AS number as int", "4294967296", asNumberType, nil), - - // Port tests. - Entry("should accept 0 port as int", "0", portType, numorstring.SinglePort(0)), - Entry("should accept 65535 port as int", "65535", portType, numorstring.SinglePort(65535)), - Entry("should accept 0:65535 port range as string", "\"0:65535\"", portType, portFromRange(0, 65535)), - Entry("should accept 1:10 port range as string", "\"1:10\"", portType, portFromRange(1, 10)), - Entry("should accept foo-bar as named port", "\"foo-bar\"", portType, numorstring.NamedPort("foo-bar")), - Entry("should reject -1 port as int", "-1", portType, nil), - Entry("should reject 65536 port as int", "65536", portType, nil), - Entry("should reject 0:65536 port range as string", "\"0:65536\"", portType, nil), - Entry("should reject -1:65535 port range as string", "\"-1:65535\"", portType, nil), - Entry("should reject 10:1 port range as string", "\"10:1\"", portType, nil), - Entry("should reject 1:2:3 port range as string", "\"1:2:3\"", portType, nil), - Entry("should reject bad named port string", "\"*\"", portType, nil), - Entry("should reject bad port string", "\"1:2", portType, nil), - - // Protocol tests. Invalid integer values will be stored as strings. - Entry("should accept 0 protocol as int", "0", protocolType, numorstring.ProtocolFromInt(0)), - Entry("should accept 255 protocol as int", "255", protocolType, numorstring.ProtocolFromInt(255)), - Entry("should accept tcp protocol as string", "\"TCP\"", protocolType, numorstring.ProtocolFromString("TCP")), - Entry("should accept tcp protocol as string", "\"TCP\"", protocolType, numorstring.ProtocolFromString("TCP")), - Entry("should accept 0 protocol as string", "\"0\"", protocolType, numorstring.ProtocolFromInt(0)), - Entry("should accept 0 protocol as string", "\"255\"", protocolType, numorstring.ProtocolFromInt(255)), - Entry("should accept 256 protocol as string", "\"256\"", protocolType, numorstring.ProtocolFromString("256")), - Entry("should reject bad protocol string", "\"25", protocolType, nil), - ) - - // Perform tests of JSON marshaling of the various field types. - DescribeTable("NumOrStringJSONMarshaling", - func(field interface{}, jtext string) { - b, err := json.Marshal(field) - if jtext != "" { - Expect(err).To(BeNil(), - "expected json marshal to not error") - Expect(string(b)).To(Equal(jtext), - "expected json not same as marshalled value") - } else { - Expect(err).ToNot(BeNil(), - "expected json marshal to error") - } - }, - // ASNumber tests. - Entry("should marshal ASN of 0", numorstring.ASNumber(0), "0"), - Entry("should marshal ASN of 4294967295", numorstring.ASNumber(4294967295), "4294967295"), - - // Port tests. - Entry("should marshal port of 0", numorstring.SinglePort(0), "0"), - Entry("should marshal port of 65535", portFromRange(65535, 65535), "65535"), - Entry("should marshal port of 10", portFromString("10"), "10"), - Entry("should marshal port range of 10:20", portFromRange(10, 20), "\"10:20\""), - Entry("should marshal port range of 20:30", portFromRange(20, 30), "\"20:30\""), - Entry("should marshal named port", numorstring.NamedPort("foobar"), `"foobar"`), - - // Protocol tests. - Entry("should marshal protocol of 0", numorstring.ProtocolFromInt(0), "0"), - Entry("should marshal protocol of udp", numorstring.ProtocolFromString("UDP"), "\"UDP\""), - ) - - // Perform tests of Stringer interface various field types. - DescribeTable("NumOrStringStringify", - func(field interface{}, s string) { - a := fmt.Sprint(field) - Expect(a).To(Equal(s), - "expected String() value to match") - }, - // ASNumber tests. - Entry("should stringify ASN of 0", numorstring.ASNumber(0), "0"), - Entry("should stringify ASN of 4294967295", numorstring.ASNumber(4294967295), "4294967295"), - - // Port tests. - Entry("should stringify port of 20", numorstring.SinglePort(20), "20"), - Entry("should stringify port range of 10:20", portFromRange(10, 20), "10:20"), - - // Protocol tests. - Entry("should stringify protocol of 0", numorstring.ProtocolFromInt(0), "0"), - Entry("should stringify protocol of udp", numorstring.ProtocolFromString("UDP"), "UDP"), - ) - - // Perform tests of Protocols supporting ports. - DescribeTable("NumOrStringProtocolsSupportingPorts", - func(protocol numorstring.Protocol, supportsPorts bool) { - Expect(protocol.SupportsPorts()).To(Equal(supportsPorts), - "expected protocol port support to match") - }, - Entry("protocol 6 supports ports", numorstring.ProtocolFromInt(6), true), - Entry("protocol 17 supports ports", numorstring.ProtocolFromInt(17), true), - Entry("protocol udp supports ports", numorstring.ProtocolFromString("UDP"), true), - Entry("protocol udp supports ports", numorstring.ProtocolFromString("TCP"), true), - Entry("protocol foo does not support ports", numorstring.ProtocolFromString("foo"), false), - Entry("protocol 2 does not support ports", numorstring.ProtocolFromInt(2), false), - ) - - // Perform tests of Protocols FromString method. - DescribeTable("NumOrStringProtocols FromString is not case sensitive", - func(input, expected string) { - Expect(numorstring.ProtocolFromString(input).StrVal).To(Equal(expected), - "expected parsed protocol to match") - }, - Entry("protocol udp -> UDP", "udp", "UDP"), - Entry("protocol tcp -> TCP", "tcp", "TCP"), - Entry("protocol updlite -> UDPLite", "udplite", "UDPLite"), - Entry("unknown protocol xxxXXX", "xxxXXX", "xxxXXX"), - ) - - // Perform tests of Protocols FromStringV1 method. - DescribeTable("NumOrStringProtocols FromStringV1 is lowercase", - func(input, expected string) { - Expect(numorstring.ProtocolFromStringV1(input).StrVal).To(Equal(expected), - "expected parsed protocol to match") - }, - Entry("protocol udp -> UDP", "UDP", "udp"), - Entry("protocol tcp -> TCP", "TCP", "tcp"), - Entry("protocol updlite -> UDPLite", "UDPLite", "udplite"), - Entry("unknown protocol xxxXXX", "xxxXXX", "xxxxxx"), - ) - - // Perform tests of Protocols ToV1 method. - DescribeTable("NumOrStringProtocols FromStringV1 is lowercase", - func(input, expected numorstring.Protocol) { - Expect(input.ToV1()).To(Equal(expected), - "expected parsed protocol to match") - }, - // Protocol tests. - Entry("protocol udp -> UDP", numorstring.ProtocolFromInt(2), numorstring.ProtocolFromInt(2)), - Entry("protocol tcp -> TCP", numorstring.ProtocolFromString("TCP"), numorstring.ProtocolFromStringV1("TCP")), - ) -} - -func portFromRange(minPort, maxPort uint16) numorstring.Port { - p, _ := numorstring.PortFromRange(minPort, maxPort) - return p -} - -func portFromString(s string) numorstring.Port { - p, _ := numorstring.PortFromString(s) - return p -} diff --git a/pkg/apis/network/v1alpha1/numorstring/port.go b/pkg/apis/network/v1alpha1/numorstring/port.go deleted file mode 100644 index 9d737ff837c09866df533556235c375ab6cc0ec7..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/port.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2016-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 numorstring - -import ( - "encoding/json" - "errors" - "fmt" - "regexp" - "strconv" -) - -// Port represents either a range of numeric ports or a named port. -// -// - For a named port, set the PortName, leaving MinPort and MaxPort as 0. -// - For a port range, set MinPort and MaxPort to the (inclusive) port numbers. Set -// PortName to "". -// - For a single port, set MinPort = MaxPort and PortName = "". -type Port struct { - MinPort uint16 `json:"minPort,omitempty"` - MaxPort uint16 `json:"maxPort,omitempty"` - PortName string `validate:"omitempty,portName" json:"portName,omitempty"` -} - -// SinglePort creates a Port struct representing a single port. -func SinglePort(port uint16) Port { - return Port{MinPort: port, MaxPort: port} -} - -func NamedPort(name string) Port { - return Port{PortName: name} -} - -// PortFromRange creates a Port struct representing a range of ports. -func PortFromRange(minPort, maxPort uint16) (Port, error) { - port := Port{MinPort: minPort, MaxPort: maxPort} - if minPort > maxPort { - msg := fmt.Sprintf("minimum port number (%d) is greater than maximum port number (%d) in port range", minPort, maxPort) - return port, errors.New(msg) - } - return port, nil -} - -var ( - allDigits = regexp.MustCompile(`^\d+$`) - portRange = regexp.MustCompile(`^(\d+):(\d+)$`) - nameRegex = regexp.MustCompile("^[a-zA-Z0-9_.-]{1,128}$") -) - -// PortFromString creates a Port struct from its string representation. A port -// may either be single value "1234", a range of values "100:200" or a named port: "name". -func PortFromString(s string) (Port, error) { - if allDigits.MatchString(s) { - // Port is all digits, it should parse as a single port. - num, err := strconv.ParseUint(s, 10, 16) - if err != nil { - msg := fmt.Sprintf("invalid port format (%s)", s) - return Port{}, errors.New(msg) - } - return SinglePort(uint16(num)), nil - } - - if groups := portRange.FindStringSubmatch(s); len(groups) > 0 { - // Port matches :, it should parse as a range of ports. - if pmin, err := strconv.ParseUint(groups[1], 10, 16); err != nil { - msg := fmt.Sprintf("invalid minimum port number in range (%s)", s) - return Port{}, errors.New(msg) - } else if pmax, err := strconv.ParseUint(groups[2], 10, 16); err != nil { - msg := fmt.Sprintf("invalid maximum port number in range (%s)", s) - return Port{}, errors.New(msg) - } else { - return PortFromRange(uint16(pmin), uint16(pmax)) - } - } - - if !nameRegex.MatchString(s) { - msg := fmt.Sprintf("invalid name for named port (%s)", s) - return Port{}, errors.New(msg) - } - - return NamedPort(s), nil -} - -// UnmarshalJSON implements the json.Unmarshaller interface. -func (p *Port) UnmarshalJSON(b []byte) error { - if b[0] == '"' { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - if v, err := PortFromString(s); err != nil { - return err - } else { - *p = v - return nil - } - } - - // It's not a string, it must be a single int. - var i uint16 - if err := json.Unmarshal(b, &i); err != nil { - return err - } - v := SinglePort(i) - *p = v - return nil -} - -// MarshalJSON implements the json.Marshaller interface. -func (p Port) MarshalJSON() ([]byte, error) { - if p.PortName != "" { - return json.Marshal(p.PortName) - } else if p.MinPort == p.MaxPort { - return json.Marshal(p.MinPort) - } else { - return json.Marshal(p.String()) - } -} - -// String returns the string value. If the min and max port are the same -// this returns a single string representation of the port number, otherwise -// if returns a colon separated range of ports. -func (p Port) String() string { - if p.PortName != "" { - return p.PortName - } else if p.MinPort == p.MaxPort { - return strconv.FormatUint(uint64(p.MinPort), 10) - } else { - return fmt.Sprintf("%d:%d", p.MinPort, p.MaxPort) - } -} diff --git a/pkg/apis/network/v1alpha1/numorstring/protocol.go b/pkg/apis/network/v1alpha1/numorstring/protocol.go deleted file mode 100644 index d700a21c6c8d24b23cf7f42251476b6e089df650..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/protocol.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2016 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 numorstring - -import "strings" - -const ( - ProtocolUDP = "UDP" - ProtocolTCP = "TCP" - ProtocolICMP = "ICMP" - ProtocolICMPv6 = "ICMPv6" - ProtocolSCTP = "SCTP" - ProtocolUDPLite = "UDPLite" - - ProtocolUDPV1 = "udp" - ProtocolTCPV1 = "tcp" -) - -var ( - allProtocolNames = []string{ - ProtocolUDP, - ProtocolTCP, - ProtocolICMP, - ProtocolICMPv6, - ProtocolSCTP, - ProtocolUDPLite, - } -) - -type Protocol Uint8OrString - -// ProtocolFromInt creates a Protocol struct from an integer value. -func ProtocolFromInt(p uint8) Protocol { - return Protocol( - Uint8OrString{Type: NumOrStringNum, NumVal: p}, - ) -} - -// ProtocolV3FromProtocolV1 creates a v3 Protocol from a v1 Protocol, -// while handling case conversion. -func ProtocolV3FromProtocolV1(p Protocol) Protocol { - if p.Type == NumOrStringNum { - return p - } - - for _, n := range allProtocolNames { - if strings.ToLower(n) == strings.ToLower(p.StrVal) { - return Protocol( - Uint8OrString{Type: NumOrStringString, StrVal: n}, - ) - } - } - - return p -} - -// ProtocolFromString creates a Protocol struct from a string value. -func ProtocolFromString(p string) Protocol { - for _, n := range allProtocolNames { - if strings.ToLower(n) == strings.ToLower(p) { - return Protocol( - Uint8OrString{Type: NumOrStringString, StrVal: n}, - ) - } - } - - // Unknown protocol - return the value unchanged. Validation should catch this. - return Protocol( - Uint8OrString{Type: NumOrStringString, StrVal: p}, - ) -} - -// ProtocolFromStringV1 creates a Protocol struct from a string value (for the v1 API) -func ProtocolFromStringV1(p string) Protocol { - return Protocol( - Uint8OrString{Type: NumOrStringString, StrVal: strings.ToLower(p)}, - ) -} - -// UnmarshalJSON implements the json.Unmarshaller interface. -func (p *Protocol) UnmarshalJSON(b []byte) error { - return (*Uint8OrString)(p).UnmarshalJSON(b) -} - -// MarshalJSON implements the json.Marshaller interface. -func (p Protocol) MarshalJSON() ([]byte, error) { - return Uint8OrString(p).MarshalJSON() -} - -// String returns the string value, or the Itoa of the int value. -func (p Protocol) String() string { - return (Uint8OrString)(p).String() -} - -// String returns the string value, or the Itoa of the int value. -func (p Protocol) ToV1() Protocol { - if p.Type == NumOrStringNum { - return p - } - return ProtocolFromStringV1(p.StrVal) -} - -// NumValue returns the NumVal if type Int, or if -// it is a String, will attempt a conversion to int. -func (p Protocol) NumValue() (uint8, error) { - return (Uint8OrString)(p).NumValue() -} - -// SupportsProtocols returns whether this protocol supports ports. This returns true if -// the numerical or string verion of the protocol indicates TCP (6) or UDP (17). -func (p Protocol) SupportsPorts() bool { - num, err := p.NumValue() - if err == nil { - return num == 6 || num == 17 - } else { - switch p.StrVal { - case ProtocolTCP, ProtocolUDP, ProtocolTCPV1, ProtocolUDPV1: - return true - } - return false - } -} diff --git a/pkg/apis/network/v1alpha1/numorstring/type.go b/pkg/apis/network/v1alpha1/numorstring/type.go deleted file mode 100644 index ae50cba43e11eaf76a49efdc6414bd55cb3bc3dd..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/type.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2016 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 numorstring - -// Type represents the stored type of Int32OrString. -type NumOrStringType int - -const ( - NumOrStringNum NumOrStringType = iota // The structure holds a number. - NumOrStringString // The structure holds a string. -) diff --git a/pkg/apis/network/v1alpha1/numorstring/uint8orstring.go b/pkg/apis/network/v1alpha1/numorstring/uint8orstring.go deleted file mode 100644 index 626a904b68538da07691b0433328013483ecce2e..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/numorstring/uint8orstring.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2016 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 numorstring - -import ( - "encoding/json" - "strconv" -) - -// UInt8OrString is a type that can hold an uint8 or a string. When used in -// JSON or YAML marshalling and unmarshalling, it produces or consumes the -// inner type. This allows you to have, for example, a JSON field that can -// accept a name or number. -type Uint8OrString struct { - Type NumOrStringType - NumVal uint8 - StrVal string -} - -// UnmarshalJSON implements the json.Unmarshaller interface. -func (i *Uint8OrString) UnmarshalJSON(b []byte) error { - if b[0] == '"' { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - num, err := strconv.ParseUint(s, 10, 8) - if err == nil { - i.Type = NumOrStringNum - i.NumVal = uint8(num) - } else { - i.Type = NumOrStringString - i.StrVal = s - } - - return nil - } - i.Type = NumOrStringNum - return json.Unmarshal(b, &i.NumVal) -} - -// MarshalJSON implements the json.Marshaller interface. -func (i Uint8OrString) MarshalJSON() ([]byte, error) { - if num, err := i.NumValue(); err == nil { - return json.Marshal(num) - } else { - return json.Marshal(i.StrVal) - } -} - -// String returns the string value, or the Itoa of the int value. -func (i Uint8OrString) String() string { - if i.Type == NumOrStringString { - return i.StrVal - } - return strconv.FormatUint(uint64(i.NumVal), 10) -} - -// NumValue returns the NumVal if type Int, or if -// it is a String, will attempt a conversion to int. -func (i Uint8OrString) NumValue() (uint8, error) { - if i.Type == NumOrStringString { - num, err := strconv.ParseUint(i.StrVal, 10, 8) - return uint8(num), err - } - return i.NumVal, nil -} diff --git a/pkg/apis/network/v1alpha1/openapi_generated.go b/pkg/apis/network/v1alpha1/openapi_generated.go index a86c10d85c82fca3b3d1f8ac1457e7596cb864fc..0e2da3e846a23ad1ddeea43d8b5bd59ea41f399c 100644 --- a/pkg/apis/network/v1alpha1/openapi_generated.go +++ b/pkg/apis/network/v1alpha1/openapi_generated.go @@ -31,78 +31,70 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "k8s.io/api/networking/v1.IPBlock": schema_k8sio_api_networking_v1_IPBlock(ref), - "k8s.io/api/networking/v1.NetworkPolicy": schema_k8sio_api_networking_v1_NetworkPolicy(ref), - "k8s.io/api/networking/v1.NetworkPolicyEgressRule": schema_k8sio_api_networking_v1_NetworkPolicyEgressRule(ref), - "k8s.io/api/networking/v1.NetworkPolicyIngressRule": schema_k8sio_api_networking_v1_NetworkPolicyIngressRule(ref), - "k8s.io/api/networking/v1.NetworkPolicyList": schema_k8sio_api_networking_v1_NetworkPolicyList(ref), - "k8s.io/api/networking/v1.NetworkPolicyPeer": schema_k8sio_api_networking_v1_NetworkPolicyPeer(ref), - "k8s.io/api/networking/v1.NetworkPolicyPort": schema_k8sio_api_networking_v1_NetworkPolicyPort(ref), - "k8s.io/api/networking/v1.NetworkPolicySpec": schema_k8sio_api_networking_v1_NetworkPolicySpec(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIResource": schema_pkg_apis_meta_v1_APIResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIResourceList": schema_pkg_apis_meta_v1_APIResourceList(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.APIVersions": schema_pkg_apis_meta_v1_APIVersions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.CreateOptions": schema_pkg_apis_meta_v1_CreateOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.DeleteOptions": schema_pkg_apis_meta_v1_DeleteOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Duration": schema_pkg_apis_meta_v1_Duration(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ExportOptions": schema_pkg_apis_meta_v1_ExportOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.FieldsV1": schema_pkg_apis_meta_v1_FieldsV1(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GetOptions": schema_pkg_apis_meta_v1_GetOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind": schema_pkg_apis_meta_v1_GroupKind(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupResource": schema_pkg_apis_meta_v1_GroupResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersion": schema_pkg_apis_meta_v1_GroupVersion(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionForDiscovery": schema_pkg_apis_meta_v1_GroupVersionForDiscovery(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionKind": schema_pkg_apis_meta_v1_GroupVersionKind(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionResource": schema_pkg_apis_meta_v1_GroupVersionResource(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.InternalEvent": schema_pkg_apis_meta_v1_InternalEvent(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector": schema_pkg_apis_meta_v1_LabelSelector(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelectorRequirement": schema_pkg_apis_meta_v1_LabelSelectorRequirement(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.List": schema_pkg_apis_meta_v1_List(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta": schema_pkg_apis_meta_v1_ListMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ListOptions": schema_pkg_apis_meta_v1_ListOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ManagedFieldsEntry": schema_pkg_apis_meta_v1_ManagedFieldsEntry(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime": schema_pkg_apis_meta_v1_MicroTime(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta": schema_pkg_apis_meta_v1_ObjectMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.OwnerReference": schema_pkg_apis_meta_v1_OwnerReference(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.PartialObjectMetadata": schema_pkg_apis_meta_v1_PartialObjectMetadata(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.PartialObjectMetadataList": schema_pkg_apis_meta_v1_PartialObjectMetadataList(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Patch": schema_pkg_apis_meta_v1_Patch(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.PatchOptions": schema_pkg_apis_meta_v1_PatchOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Preconditions": schema_pkg_apis_meta_v1_Preconditions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.RootPaths": schema_pkg_apis_meta_v1_RootPaths(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.ServerAddressByClientCIDR": schema_pkg_apis_meta_v1_ServerAddressByClientCIDR(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Status": schema_pkg_apis_meta_v1_Status(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.StatusCause": schema_pkg_apis_meta_v1_StatusCause(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.StatusDetails": schema_pkg_apis_meta_v1_StatusDetails(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Table": schema_pkg_apis_meta_v1_Table(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TableColumnDefinition": schema_pkg_apis_meta_v1_TableColumnDefinition(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TableOptions": schema_pkg_apis_meta_v1_TableOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TableRow": schema_pkg_apis_meta_v1_TableRow(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TableRowCondition": schema_pkg_apis_meta_v1_TableRowCondition(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Time": schema_pkg_apis_meta_v1_Time(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.Timestamp": schema_pkg_apis_meta_v1_Timestamp(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta": schema_pkg_apis_meta_v1_TypeMeta(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.UpdateOptions": schema_pkg_apis_meta_v1_UpdateOptions(ref), - "k8s.io/apimachinery/pkg/apis/meta/v1.WatchEvent": schema_pkg_apis_meta_v1_WatchEvent(ref), - "k8s.io/apimachinery/pkg/util/intstr.IntOrString": schema_apimachinery_pkg_util_intstr_IntOrString(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.EntityRule": schema_pkg_apis_network_v1alpha1_EntityRule(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPMatch": schema_pkg_apis_network_v1alpha1_HTTPMatch(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPPath": schema_pkg_apis_network_v1alpha1_HTTPPath(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ICMPFields": schema_pkg_apis_network_v1alpha1_ICMPFields(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicy": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicy(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicyList": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicyList(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicySpec": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicySpec(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.Rule": schema_pkg_apis_network_v1alpha1_Rule(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceAccountMatch": schema_pkg_apis_network_v1alpha1_ServiceAccountMatch(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicy": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicy(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyEgressRule": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyEgressRule(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyIngressRule": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyIngressRule(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyList": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyList(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyPeer": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyPeer(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicySpec": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicySpec(ref), - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyStatus": schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyStatus(ref), + "k8s.io/api/networking/v1.IPBlock": schema_k8sio_api_networking_v1_IPBlock(ref), + "k8s.io/api/networking/v1.NetworkPolicy": schema_k8sio_api_networking_v1_NetworkPolicy(ref), + "k8s.io/api/networking/v1.NetworkPolicyEgressRule": schema_k8sio_api_networking_v1_NetworkPolicyEgressRule(ref), + "k8s.io/api/networking/v1.NetworkPolicyIngressRule": schema_k8sio_api_networking_v1_NetworkPolicyIngressRule(ref), + "k8s.io/api/networking/v1.NetworkPolicyList": schema_k8sio_api_networking_v1_NetworkPolicyList(ref), + "k8s.io/api/networking/v1.NetworkPolicyPeer": schema_k8sio_api_networking_v1_NetworkPolicyPeer(ref), + "k8s.io/api/networking/v1.NetworkPolicyPort": schema_k8sio_api_networking_v1_NetworkPolicyPort(ref), + "k8s.io/api/networking/v1.NetworkPolicySpec": schema_k8sio_api_networking_v1_NetworkPolicySpec(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroup": schema_pkg_apis_meta_v1_APIGroup(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIGroupList": schema_pkg_apis_meta_v1_APIGroupList(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIResource": schema_pkg_apis_meta_v1_APIResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIResourceList": schema_pkg_apis_meta_v1_APIResourceList(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.APIVersions": schema_pkg_apis_meta_v1_APIVersions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.CreateOptions": schema_pkg_apis_meta_v1_CreateOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.DeleteOptions": schema_pkg_apis_meta_v1_DeleteOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Duration": schema_pkg_apis_meta_v1_Duration(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ExportOptions": schema_pkg_apis_meta_v1_ExportOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.FieldsV1": schema_pkg_apis_meta_v1_FieldsV1(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GetOptions": schema_pkg_apis_meta_v1_GetOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupKind": schema_pkg_apis_meta_v1_GroupKind(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupResource": schema_pkg_apis_meta_v1_GroupResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersion": schema_pkg_apis_meta_v1_GroupVersion(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionForDiscovery": schema_pkg_apis_meta_v1_GroupVersionForDiscovery(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionKind": schema_pkg_apis_meta_v1_GroupVersionKind(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.GroupVersionResource": schema_pkg_apis_meta_v1_GroupVersionResource(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.InternalEvent": schema_pkg_apis_meta_v1_InternalEvent(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector": schema_pkg_apis_meta_v1_LabelSelector(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelectorRequirement": schema_pkg_apis_meta_v1_LabelSelectorRequirement(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.List": schema_pkg_apis_meta_v1_List(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta": schema_pkg_apis_meta_v1_ListMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ListOptions": schema_pkg_apis_meta_v1_ListOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ManagedFieldsEntry": schema_pkg_apis_meta_v1_ManagedFieldsEntry(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.MicroTime": schema_pkg_apis_meta_v1_MicroTime(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta": schema_pkg_apis_meta_v1_ObjectMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.OwnerReference": schema_pkg_apis_meta_v1_OwnerReference(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.PartialObjectMetadata": schema_pkg_apis_meta_v1_PartialObjectMetadata(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.PartialObjectMetadataList": schema_pkg_apis_meta_v1_PartialObjectMetadataList(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Patch": schema_pkg_apis_meta_v1_Patch(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.PatchOptions": schema_pkg_apis_meta_v1_PatchOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Preconditions": schema_pkg_apis_meta_v1_Preconditions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.RootPaths": schema_pkg_apis_meta_v1_RootPaths(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.ServerAddressByClientCIDR": schema_pkg_apis_meta_v1_ServerAddressByClientCIDR(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Status": schema_pkg_apis_meta_v1_Status(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.StatusCause": schema_pkg_apis_meta_v1_StatusCause(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.StatusDetails": schema_pkg_apis_meta_v1_StatusDetails(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Table": schema_pkg_apis_meta_v1_Table(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TableColumnDefinition": schema_pkg_apis_meta_v1_TableColumnDefinition(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TableOptions": schema_pkg_apis_meta_v1_TableOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TableRow": schema_pkg_apis_meta_v1_TableRow(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TableRowCondition": schema_pkg_apis_meta_v1_TableRowCondition(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Time": schema_pkg_apis_meta_v1_Time(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.Timestamp": schema_pkg_apis_meta_v1_Timestamp(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta": schema_pkg_apis_meta_v1_TypeMeta(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.UpdateOptions": schema_pkg_apis_meta_v1_UpdateOptions(ref), + "k8s.io/apimachinery/pkg/apis/meta/v1.WatchEvent": schema_pkg_apis_meta_v1_WatchEvent(ref), + "k8s.io/apimachinery/pkg/util/intstr.IntOrString": schema_apimachinery_pkg_util_intstr_IntOrString(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicy": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicy(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicyList": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicyList(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceNetworkPolicySpec": schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicySpec(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceSelector": schema_pkg_apis_network_v1alpha1_NamespaceSelector(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyEgressRule": schema_pkg_apis_network_v1alpha1_NetworkPolicyEgressRule(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyIngressRule": schema_pkg_apis_network_v1alpha1_NetworkPolicyIngressRule(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyPeer": schema_pkg_apis_network_v1alpha1_NetworkPolicyPeer(ref), + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceSelector": schema_pkg_apis_network_v1alpha1_ServiceSelector(ref), } } @@ -2523,196 +2515,6 @@ func schema_apimachinery_pkg_util_intstr_IntOrString(ref common.ReferenceCallbac } } -func schema_pkg_apis_network_v1alpha1_EntityRule(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "An EntityRule is a sub-component of a Rule comprising the match criteria specific to a particular entity (that is either the source or destination).\n\nA source EntityRule matches the source endpoint and originating traffic. A destination EntityRule matches the destination endpoint and terminating traffic.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "nets": { - SchemaProps: spec.SchemaProps{ - Description: "Nets is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) IP addresses in any of the given subnets.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "selector": { - SchemaProps: spec.SchemaProps{ - Description: "Selector is an optional field that contains a selector expression (see Policy for sample syntax). Only traffic that originates from (terminates at) endpoints matching the selector will be matched.\n\nNote that: in addition to the negated version of the Selector (see NotSelector below), the selector expression syntax itself supports negation. The two types of negation are subtly different. One negates the set of matched endpoints, the other negates the whole match:\n\n\tSelector = \"!has(my_label)\" matches packets that are from other Calico-controlled\n\tendpoints that do not have the label “my_label”.\n\n\tNotSelector = \"has(my_label)\" matches packets that are not from Calico-controlled\n\tendpoints that do have the label “my_label”.\n\nThe effect is that the latter will accept packets from non-Calico sources whereas the former is limited to packets from Calico-controlled endpoints.", - Type: []string{"string"}, - Format: "", - }, - }, - "namespaceSelector": { - SchemaProps: spec.SchemaProps{ - Description: "NamespaceSelector is an optional field that contains a selector expression. Only traffic that originates from (or terminates at) endpoints within the selected namespaces will be matched. When both NamespaceSelector and Selector are defined on the same rule, then only workload endpoints that are matched by both selectors will be selected by the rule.\n\nFor NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting only workload endpoints in the same namespace as the NetworkPolicy.\n\nFor GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload endpoints across all namespaces.", - Type: []string{"string"}, - Format: "", - }, - }, - "ports": { - SchemaProps: spec.SchemaProps{ - Description: "Ports is an optional field that restricts the rule to only apply to traffic that has a source (destination) port that matches one of these ranges/values. This value is a list of integers or strings that represent ranges of ports.\n\nSince only some protocols have ports, if any ports are specified it requires the Protocol match in the Rule to be set to \"TCP\" or \"UDP\".", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1/numorstring.Port"), - }, - }, - }, - }, - }, - "notNets": { - SchemaProps: spec.SchemaProps{ - Description: "NotNets is the negated version of the Nets field.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "notSelector": { - SchemaProps: spec.SchemaProps{ - Description: "NotSelector is the negated version of the Selector field. See Selector field for subtleties with negated selectors.", - Type: []string{"string"}, - Format: "", - }, - }, - "notPorts": { - SchemaProps: spec.SchemaProps{ - Description: "NotPorts is the negated version of the Ports field. Since only some protocols have ports, if any ports are specified it requires the Protocol match in the Rule to be set to \"TCP\" or \"UDP\".", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1/numorstring.Port"), - }, - }, - }, - }, - }, - "serviceAccounts": { - SchemaProps: spec.SchemaProps{ - Description: "ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a matching service account.", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceAccountMatch"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceAccountMatch", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1/numorstring.Port"}, - } -} - -func schema_pkg_apis_network_v1alpha1_HTTPMatch(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "HTTPMatch is an optional field that apply only to HTTP requests The Methods and Path fields are joined with AND", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "methods": { - SchemaProps: spec.SchemaProps{ - Description: "Methods is an optional field that restricts the rule to apply only to HTTP requests that use one of the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple methods are OR'd together.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "paths": { - SchemaProps: spec.SchemaProps{ - Description: "Paths is an optional field that restricts the rule to apply to HTTP requests that use one of the listed HTTP Paths. Multiple paths are OR'd together. e.g: - exact: /foo - prefix: /bar NOTE: Each entry may ONLY specify either a `exact` or a `prefix` match. The validator will check for it.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPPath"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPPath"}, - } -} - -func schema_pkg_apis_network_v1alpha1_HTTPPath(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "HTTPPath specifies an HTTP path to match. It may be either of the form: exact: : which matches the path exactly or prefix: : which matches the path prefix", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "exact": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "prefix": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_network_v1alpha1_ICMPFields(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "ICMPFields defines structure for ICMP and NotICMP sub-struct for ICMP code and type", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "type": { - SchemaProps: spec.SchemaProps{ - Description: "Match on a specific ICMP type. For example a value of 8 refers to ICMP Echo Request (i.e. pings).", - Type: []string{"integer"}, - Format: "int32", - }, - }, - "code": { - SchemaProps: spec.SchemaProps{ - Description: "Match on a specific ICMP code. If specified, the Type value must also be specified. This is a technical limitation imposed by the kernel’s iptables firewall, which Calico uses to enforce the rule.", - Type: []string{"integer"}, - Format: "int32", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicy(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2803,24 +2605,17 @@ func schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicySpec(ref common.Refe return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "NamespaceNetworkPolicySpec defines the desired state of NamespaceNetworkPolicy", + Description: "NetworkPolicySpec provides the specification of a NetworkPolicy", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "order": { - SchemaProps: spec.SchemaProps{ - Description: "Order is an optional field that specifies the order in which the policy is applied. Policies with higher \"order\" are applied after those with lower order. If the order is omitted, it may be considered to be \"infinite\" - i.e. the policy will be applied last. Policies with identical order will be applied in alphanumerical order based on the Policy \"Name\".", - Type: []string{"integer"}, - Format: "int32", - }, - }, "ingress": { SchemaProps: spec.SchemaProps{ - Description: "The ordered set of ingress rules. Each rule contains a set of packet match criteria and a corresponding action to apply.", + Description: "List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.Rule"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyIngressRule"), }, }, }, @@ -2828,27 +2623,20 @@ func schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicySpec(ref common.Refe }, "egress": { SchemaProps: spec.SchemaProps{ - Description: "The ordered set of egress rules. Each rule contains a set of packet match criteria and a corresponding action to apply.", + Description: "List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.Rule"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyEgressRule"), }, }, }, }, }, - "selector": { - SchemaProps: spec.SchemaProps{ - Description: "The selector is an expression used to pick pick out the endpoints that the policy should be applied to.\n\nSelector expressions follow this syntax:\n\n\tlabel == \"string_literal\" -> comparison, e.g. my_label == \"foo bar\"\n\tlabel != \"string_literal\" -> not equal; also matches if label is not present\n\tlabel in { \"a\", \"b\", \"c\", ... } -> true if the value of label X is one of \"a\", \"b\", \"c\"\n\tlabel not in { \"a\", \"b\", \"c\", ... } -> true if the value of label X is not one of \"a\", \"b\", \"c\"\n\thas(label_name) -> True if that label is present\n\t! expr -> negation of expr\n\texpr && expr -> Short-circuit and\n\texpr || expr -> Short-circuit or\n\t( expr ) -> parens for grouping\n\tall() or the empty selector -> matches all endpoints.\n\nLabel names are allowed to contain alphanumerics, -, _ and /. String literals are more permissive but they do not support escape characters.\n\nExamples (with made-up labels):\n\n\ttype == \"webserver\" && deployment == \"prod\"\n\ttype in {\"frontend\", \"backend\"}\n\tdeployment != \"dev\"\n\t! has(label_name)", - Type: []string{"string"}, - Format: "", - }, - }, - "types": { + "policyTypes": { SchemaProps: spec.SchemaProps{ - Description: "Types indicates whether this policy applies to ingress, or to egress, or to both. When not explicitly specified (and so the value on creation is empty or nil), Calico defaults Types according to what Ingress and Egress are present in the policy. The default is:\n\n- [ PolicyTypeIngress ], if there are no Egress rules (including the case where there are\n also no Ingress rules)\n\n- [ PolicyTypeEgress ], if there are Egress rules but no Ingress rules\n\n- [ PolicyTypeIngress, PolicyTypeEgress ], if there are both Ingress and Egress rules.\n\nWhen the policy is read back again, Types will always be one of these values, never empty or nil.", + Description: "List of rule types that the NetworkPolicy relates to. Valid options are \"Ingress\", \"Egress\", or \"Ingress,Egress\". If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an Egress section and would otherwise default to just [ \"Ingress\" ]). This field is beta-level in 1.8", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -2861,174 +2649,42 @@ func schema_pkg_apis_network_v1alpha1_NamespaceNetworkPolicySpec(ref common.Refe }, }, }, - Required: []string{"selector"}, }, }, Dependencies: []string{ - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.Rule"}, + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyEgressRule", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyIngressRule"}, } } -func schema_pkg_apis_network_v1alpha1_Rule(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_network_v1alpha1_NamespaceSelector(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "A Rule encapsulates a set of match criteria and an action. Both selector-based security Policy and security Profiles reference rules - separated out as a list of rules for both ingress and egress packet matching.\n\nEach positive match criteria has a negated version, prefixed with ”Not”. All the match criteria within a rule must be satisfied for a packet to match. A single rule can contain the positive and negative version of a match and both must be satisfied for the rule to match.", - Type: []string{"object"}, + Type: []string{"object"}, Properties: map[string]spec.Schema{ - "action": { + "name": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, Format: "", }, }, - "ipVersion": { - SchemaProps: spec.SchemaProps{ - Description: "IPVersion is an optional field that restricts the rule to only match a specific IP version.", - Type: []string{"integer"}, - Format: "int32", - }, - }, - "protocol": { - SchemaProps: spec.SchemaProps{ - Description: "Protocol is an optional field that restricts the rule to only apply to traffic of a specific IP protocol. Required if any of the EntityRules contain Ports (because ports only apply to certain protocols).\n\nMust be one of these string values: \"TCP\", \"UDP\", \"ICMP\", \"ICMPv6\", \"SCTP\", \"UDPLite\" or an integer in the range 1-255.", - Type: []string{"string"}, - Format: "", - }, - }, - "icmp": { - SchemaProps: spec.SchemaProps{ - Description: "ICMP is an optional field that restricts the rule to apply to a specific type and code of ICMP traffic. This should only be specified if the Protocol field is set to \"ICMP\" or \"ICMPv6\".", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ICMPFields"), - }, - }, - "notProtocol": { - SchemaProps: spec.SchemaProps{ - Description: "NotProtocol is the negated version of the Protocol field.", - Type: []string{"string"}, - Format: "", - }, - }, - "notICMP": { - SchemaProps: spec.SchemaProps{ - Description: "NotICMP is the negated version of the ICMP field.", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ICMPFields"), - }, - }, - "source": { - SchemaProps: spec.SchemaProps{ - Description: "Source contains the match criteria that apply to source entity.", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.EntityRule"), - }, - }, - "destination": { - SchemaProps: spec.SchemaProps{ - Description: "Destination contains the match criteria that apply to destination entity.", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.EntityRule"), - }, - }, - "http": { - SchemaProps: spec.SchemaProps{ - Description: "HTTP contains match criteria that apply to HTTP requests.", - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPMatch"), - }, - }, }, - Required: []string{"action"}, + Required: []string{"name"}, }, }, - Dependencies: []string{ - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.EntityRule", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.HTTPMatch", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ICMPFields"}, } } -func schema_pkg_apis_network_v1alpha1_ServiceAccountMatch(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_network_v1alpha1_NetworkPolicyEgressRule(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "names": { - SchemaProps: spec.SchemaProps{ - Description: "Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a service account whose name is in the list.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "selector": { - SchemaProps: spec.SchemaProps{ - Description: "Selector is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a service account that matches the given label selector. If both Names and Selector are specified then they are AND'ed.", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicy(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicy is a set of network policies applied to the scope to workspace", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicySpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicySpec", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyStatus"}, - } -} - -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyEgressRule(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a WorkspaceNetworkPolicySpec's podSelector. The traffic must match both ports and to.", + Description: "NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8", Type: []string{"object"}, Properties: map[string]spec.Schema{ "ports": { SchemaProps: spec.SchemaProps{ - Description: "List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + Description: "List of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -3039,14 +2695,14 @@ func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyEgressRule(ref commo }, }, }, - "from": { + "to": { SchemaProps: spec.SchemaProps{ - Description: "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least on item, this rule allows traffic only if the traffic matches at least one item in the from list.", + Description: "List of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyPeer"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyPeer"), }, }, }, @@ -3056,15 +2712,15 @@ func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyEgressRule(ref commo }, }, Dependencies: []string{ - "k8s.io/api/networking/v1.NetworkPolicyPort", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyPeer"}, + "k8s.io/api/networking/v1.NetworkPolicyPort", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyPeer"}, } } -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyIngressRule(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_network_v1alpha1_NetworkPolicyIngressRule(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a WorkspaceNetworkPolicySpec's podSelector. The traffic must match both ports and from.", + Description: "NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "ports": { @@ -3082,89 +2738,36 @@ func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyIngressRule(ref comm }, "from": { SchemaProps: spec.SchemaProps{ - Description: "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least on item, this rule allows traffic only if the traffic matches at least one item in the from list.", + Description: "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyPeer"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "k8s.io/api/networking/v1.NetworkPolicyPort", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyPeer"}, - } -} - -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicyList contains a list of WorkspaceNetworkPolicy", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicy"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyPeer"), }, }, }, }, }, }, - Required: []string{"items"}, }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicy"}, + "k8s.io/api/networking/v1.NetworkPolicyPort", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NetworkPolicyPeer"}, } } -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyPeer(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_network_v1alpha1_NetworkPolicyPeer(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicyPeer describes a peer to allow traffic from. Only certain combinations of fields are allowed. It is same as 'NetworkPolicyPeer' in k8s but with an additional field 'WorkspaceSelector'", + Description: "NetworkPolicyPeer describes a peer to allow traffic from. Only certain combinations of fields are allowed", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "podSelector": { - SchemaProps: spec.SchemaProps{ - Description: "This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), - }, - }, - "namespaceSelector": { + "namespace": { SchemaProps: spec.SchemaProps{ Description: "Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.", - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceSelector"), }, }, "ipBlock": { @@ -3173,87 +2776,39 @@ func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyPeer(ref common.Refe Ref: ref("k8s.io/api/networking/v1.IPBlock"), }, }, - "workspaceSelector": { + "service": { SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"), + Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceSelector"), }, }, }, }, }, Dependencies: []string{ - "k8s.io/api/networking/v1.IPBlock", "k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector"}, + "k8s.io/api/networking/v1.IPBlock", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.NamespaceSelector", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.ServiceSelector"}, } } -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicySpec(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_network_v1alpha1_ServiceSelector(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicySpec defines the desired state of WorkspaceNetworkPolicy", - Type: []string{"object"}, + Type: []string{"object"}, Properties: map[string]spec.Schema{ - "workspace": { - SchemaProps: spec.SchemaProps{ - Description: "Workspace specify the name of ws to apply this workspace network policy", - Type: []string{"string"}, - Format: "", - }, - }, - "policyTypes": { - SchemaProps: spec.SchemaProps{ - Description: "List of rule types that the WorkspaceNetworkPolicy relates to. Valid options are Ingress, Egress, or Ingress,Egress. If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an Egress section and would otherwise default to just [ \"Ingress\" ]).", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "ingress": { + "name": { SchemaProps: spec.SchemaProps{ - Description: "List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyIngressRule"), - }, - }, - }, + Type: []string{"string"}, + Format: "", }, }, - "egress": { + "namespace": { SchemaProps: spec.SchemaProps{ - Description: "List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Ref: ref("kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyEgressRule"), - }, - }, - }, + Type: []string{"string"}, + Format: "", }, }, }, - }, - }, - Dependencies: []string{ - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyEgressRule", "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1.WorkspaceNetworkPolicyIngressRule"}, - } -} - -func schema_pkg_apis_network_v1alpha1_WorkspaceNetworkPolicyStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "WorkspaceNetworkPolicyStatus defines the observed state of WorkspaceNetworkPolicy", - Type: []string{"object"}, + Required: []string{"name", "namespace"}, }, }, } diff --git a/pkg/apis/network/v1alpha1/v1alpha1_suite_test.go b/pkg/apis/network/v1alpha1/v1alpha1_suite_test.go index 96cd648d81bb234edab0b98088852750a655de48..2206160bea864483ecbbfa1faea3d5d6d0084ac5 100644 --- a/pkg/apis/network/v1alpha1/v1alpha1_suite_test.go +++ b/pkg/apis/network/v1alpha1/v1alpha1_suite_test.go @@ -33,7 +33,7 @@ var c client.Client func TestMain(m *testing.M) { t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "kustomize", "network", "crds")}, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")}, } err := SchemeBuilder.AddToScheme(scheme.Scheme) diff --git a/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types.go b/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types.go deleted file mode 100644 index ba37f7df262713d5fa25555d68ee69b215bdb5a6..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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 v1alpha1 - -import ( - k8snetworkv1 "k8s.io/api/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - ResourceKindWorkspaceNetworkPolicy = "WorkspaceNetworkPolicy" - ResourceSingularWorkspaceNetworkPolicy = "workspacenetworkpolicy" - ResourcePluralWorkspaceNetworkPolicy = "workspacenetworkpolicies" -) - -// WorkspaceNetworkPolicySpec defines the desired state of WorkspaceNetworkPolicy -type WorkspaceNetworkPolicySpec struct { - // Workspace specify the name of ws to apply this workspace network policy - Workspace string `json:"workspace,omitempty"` - // List of rule types that the WorkspaceNetworkPolicy relates to. - // Valid options are Ingress, Egress, or Ingress,Egress. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. - // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. - // Likewise, if you want to write a policy that specifies that no egress is allowed, - // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). - // +optional - PolicyTypes []k8snetworkv1.PolicyType `json:"policyTypes,omitempty" protobuf:"bytes,4,rep,name=policyTypes,casttype=PolicyType"` - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod - // (and cluster policy otherwise allows the traffic), OR if the traffic source is - // the pod's local node, OR if the traffic matches at least one ingress rule - // across all of the NetworkPolicy objects whose podSelector matches the pod. If - // this field is empty then this NetworkPolicy does not allow any traffic (and serves - // solely to ensure that the pods it selects are isolated by default) - // +optional - Ingress []WorkspaceNetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` - - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy - // otherwise allows the traffic), OR if the traffic matches at least one egress rule - // across all of the NetworkPolicy objects whose podSelector matches the pod. If - // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves - // solely to ensure that the pods it selects are isolated by default). - // This field is beta-level in 1.8 - // +optional - Egress []WorkspaceNetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` -} - -// WorkspaceNetworkPolicyStatus defines the observed state of WorkspaceNetworkPolicy -type WorkspaceNetworkPolicyStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file -} - -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// WorkspaceNetworkPolicy is a set of network policies applied to the scope to workspace -// +k8s:openapi-gen=true -// +kubebuilder:resource:categories="networking",scope="Cluster",shortName="wsnp" -type WorkspaceNetworkPolicy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec WorkspaceNetworkPolicySpec `json:"spec,omitempty"` - Status WorkspaceNetworkPolicyStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// WorkspaceNetworkPolicyList contains a list of WorkspaceNetworkPolicy -type WorkspaceNetworkPolicyList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []WorkspaceNetworkPolicy `json:"items"` -} - -// WorkspaceNetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods -// matched by a WorkspaceNetworkPolicySpec's podSelector. The traffic must match both ports and from. -type WorkspaceNetworkPolicyIngressRule struct { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is - // empty or missing, this rule matches all ports (traffic not restricted by port). - // If this field is present and contains at least one item, then this rule allows - // traffic only if the traffic matches at least one port in the list. - // +optional - Ports []k8snetworkv1.NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - - // List of sources which should be able to access the pods selected for this rule. - // Items in this list are combined using a logical OR operation. If this field is - // empty or missing, this rule matches all sources (traffic not restricted by - // source). If this field is present and contains at least on item, this rule - // allows traffic only if the traffic matches at least one item in the from list. - // +optional - From []WorkspaceNetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` -} - -// WorkspaceNetworkPolicyPeer describes a peer to allow traffic from. Only certain combinations of -// fields are allowed. It is same as 'NetworkPolicyPeer' in k8s but with an additional field 'WorkspaceSelector' -type WorkspaceNetworkPolicyPeer struct { - k8snetworkv1.NetworkPolicyPeer `json:",inline"` - WorkspaceSelector *metav1.LabelSelector `json:"workspaceSelector,omitempty"` -} - -// WorkspaceNetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods -// matched by a WorkspaceNetworkPolicySpec's podSelector. The traffic must match both ports and to. -type WorkspaceNetworkPolicyEgressRule struct { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is - // empty or missing, this rule matches all ports (traffic not restricted by port). - // If this field is present and contains at least one item, then this rule allows - // traffic only if the traffic matches at least one port in the list. - // +optional - Ports []k8snetworkv1.NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - - // List of sources which should be able to access the pods selected for this rule. - // Items in this list are combined using a logical OR operation. If this field is - // empty or missing, this rule matches all sources (traffic not restricted by - // source). If this field is present and contains at least on item, this rule - // allows traffic only if the traffic matches at least one item in the from list. - // +optional - To []WorkspaceNetworkPolicyPeer `json:"from,omitempty" protobuf:"bytes,2,rep,name=from"` -} - -func init() { - SchemeBuilder.Register(&WorkspaceNetworkPolicy{}, &WorkspaceNetworkPolicyList{}) -} diff --git a/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types_test.go b/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types_test.go deleted file mode 100644 index 1346551587b18854896b7cf537eb565319a55fca..0000000000000000000000000000000000000000 --- a/pkg/apis/network/v1alpha1/workspacenetworkpolicy_types_test.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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 v1alpha1 - -import ( - "testing" - - "github.com/onsi/gomega" - "golang.org/x/net/context" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -func TestStorageWorkspaceNetworkPolicy(t *testing.T) { - key := types.NamespacedName{ - Name: "foo", - } - created := &WorkspaceNetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }} - g := gomega.NewGomegaWithT(t) - - // Test Create - fetched := &WorkspaceNetworkPolicy{} - g.Expect(c.Create(context.TODO(), created)).To(gomega.Succeed()) - - g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.Succeed()) - g.Expect(fetched).To(gomega.Equal(created)) - - // Test Updating the Labels - updated := fetched.DeepCopy() - updated.Labels = map[string]string{"hello": "world"} - g.Expect(c.Update(context.TODO(), updated)).To(gomega.Succeed()) - - g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.Succeed()) - g.Expect(fetched).To(gomega.Equal(updated)) - - // Test Delete - g.Expect(c.Delete(context.TODO(), fetched)).To(gomega.Succeed()) - g.Expect(c.Get(context.TODO(), key, fetched)).ToNot(gomega.Succeed()) -} diff --git a/pkg/apis/network/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/network/v1alpha1/zz_generated.deepcopy.go index 71e01062f05023fbfe25feaa072c32847fa54c53..770ebc77f86664ba0e2156cc5a5af6c929c71a18 100644 --- a/pkg/apis/network/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/network/v1alpha1/zz_generated.deepcopy.go @@ -16,129 +16,22 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by controller-gen. DO NOT EDIT. +// Code generated by deepcopy-gen. DO NOT EDIT. package v1alpha1 import ( - "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/networking/v1" runtime "k8s.io/apimachinery/pkg/runtime" - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1/numorstring" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EntityRule) DeepCopyInto(out *EntityRule) { - *out = *in - if in.Nets != nil { - in, out := &in.Nets, &out.Nets - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Ports != nil { - in, out := &in.Ports, &out.Ports - *out = make([]numorstring.Port, len(*in)) - copy(*out, *in) - } - if in.NotNets != nil { - in, out := &in.NotNets, &out.NotNets - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.NotPorts != nil { - in, out := &in.NotPorts, &out.NotPorts - *out = make([]numorstring.Port, len(*in)) - copy(*out, *in) - } - if in.ServiceAccounts != nil { - in, out := &in.ServiceAccounts, &out.ServiceAccounts - *out = new(ServiceAccountMatch) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EntityRule. -func (in *EntityRule) DeepCopy() *EntityRule { - if in == nil { - return nil - } - out := new(EntityRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HTTPMatch) DeepCopyInto(out *HTTPMatch) { - *out = *in - if in.Methods != nil { - in, out := &in.Methods, &out.Methods - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Paths != nil { - in, out := &in.Paths, &out.Paths - *out = make([]HTTPPath, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPMatch. -func (in *HTTPMatch) DeepCopy() *HTTPMatch { - if in == nil { - return nil - } - out := new(HTTPMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HTTPPath) DeepCopyInto(out *HTTPPath) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPath. -func (in *HTTPPath) DeepCopy() *HTTPPath { - if in == nil { - return nil - } - out := new(HTTPPath) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ICMPFields) DeepCopyInto(out *ICMPFields) { - *out = *in - if in.Type != nil { - in, out := &in.Type, &out.Type - *out = new(int) - **out = **in - } - if in.Code != nil { - in, out := &in.Code, &out.Code - *out = new(int) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ICMPFields. -func (in *ICMPFields) DeepCopy() *ICMPFields { - if in == nil { - return nil - } - out := new(ICMPFields) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceNetworkPolicy) DeepCopyInto(out *NamespaceNetworkPolicy) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicy. @@ -171,6 +64,7 @@ func (in *NamespaceNetworkPolicyList) DeepCopyInto(out *NamespaceNetworkPolicyLi (*in)[i].DeepCopyInto(&(*out)[i]) } } + return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicyList. @@ -194,30 +88,26 @@ func (in *NamespaceNetworkPolicyList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceNetworkPolicySpec) DeepCopyInto(out *NamespaceNetworkPolicySpec) { *out = *in - if in.Order != nil { - in, out := &in.Order, &out.Order - *out = new(int) - **out = **in - } if in.Ingress != nil { in, out := &in.Ingress, &out.Ingress - *out = make([]Rule, len(*in)) + *out = make([]NetworkPolicyIngressRule, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Egress != nil { in, out := &in.Egress, &out.Egress - *out = make([]Rule, len(*in)) + *out = make([]NetworkPolicyEgressRule, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.Types != nil { - in, out := &in.Types, &out.Types - *out = make([]PolicyType, len(*in)) + if in.PolicyTypes != nil { + in, out := &in.PolicyTypes, &out.PolicyTypes + *out = make([]v1.PolicyType, len(*in)) copy(*out, *in) } + return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceNetworkPolicySpec. @@ -231,255 +121,124 @@ func (in *NamespaceNetworkPolicySpec) DeepCopy() *NamespaceNetworkPolicySpec { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Rule) DeepCopyInto(out *Rule) { +func (in *NamespaceSelector) DeepCopyInto(out *NamespaceSelector) { *out = *in - if in.IPVersion != nil { - in, out := &in.IPVersion, &out.IPVersion - *out = new(int) - **out = **in - } - if in.Protocol != nil { - in, out := &in.Protocol, &out.Protocol - *out = new(v1.Protocol) - **out = **in - } - if in.ICMP != nil { - in, out := &in.ICMP, &out.ICMP - *out = new(ICMPFields) - (*in).DeepCopyInto(*out) - } - if in.NotProtocol != nil { - in, out := &in.NotProtocol, &out.NotProtocol - *out = new(v1.Protocol) - **out = **in - } - if in.NotICMP != nil { - in, out := &in.NotICMP, &out.NotICMP - *out = new(ICMPFields) - (*in).DeepCopyInto(*out) - } - in.Source.DeepCopyInto(&out.Source) - in.Destination.DeepCopyInto(&out.Destination) - if in.HTTP != nil { - in, out := &in.HTTP, &out.HTTP - *out = new(HTTPMatch) - (*in).DeepCopyInto(*out) - } + return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule. -func (in *Rule) DeepCopy() *Rule { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceSelector. +func (in *NamespaceSelector) DeepCopy() *NamespaceSelector { if in == nil { return nil } - out := new(Rule) + out := new(NamespaceSelector) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceAccountMatch) DeepCopyInto(out *ServiceAccountMatch) { - *out = *in - if in.Names != nil { - in, out := &in.Names, &out.Names - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountMatch. -func (in *ServiceAccountMatch) DeepCopy() *ServiceAccountMatch { - if in == nil { - return nil - } - out := new(ServiceAccountMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicy) DeepCopyInto(out *WorkspaceNetworkPolicy) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicy. -func (in *WorkspaceNetworkPolicy) DeepCopy() *WorkspaceNetworkPolicy { - if in == nil { - return nil - } - out := new(WorkspaceNetworkPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WorkspaceNetworkPolicy) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicyEgressRule) DeepCopyInto(out *WorkspaceNetworkPolicyEgressRule) { +func (in *NetworkPolicyEgressRule) DeepCopyInto(out *NetworkPolicyEgressRule) { *out = *in if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]networkingv1.NetworkPolicyPort, len(*in)) + *out = make([]v1.NetworkPolicyPort, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.To != nil { in, out := &in.To, &out.To - *out = make([]WorkspaceNetworkPolicyPeer, len(*in)) + *out = make([]NetworkPolicyPeer, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } + return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicyEgressRule. -func (in *WorkspaceNetworkPolicyEgressRule) DeepCopy() *WorkspaceNetworkPolicyEgressRule { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyEgressRule. +func (in *NetworkPolicyEgressRule) DeepCopy() *NetworkPolicyEgressRule { if in == nil { return nil } - out := new(WorkspaceNetworkPolicyEgressRule) + out := new(NetworkPolicyEgressRule) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicyIngressRule) DeepCopyInto(out *WorkspaceNetworkPolicyIngressRule) { +func (in *NetworkPolicyIngressRule) DeepCopyInto(out *NetworkPolicyIngressRule) { *out = *in if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]networkingv1.NetworkPolicyPort, len(*in)) + *out = make([]v1.NetworkPolicyPort, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.From != nil { in, out := &in.From, &out.From - *out = make([]WorkspaceNetworkPolicyPeer, len(*in)) + *out = make([]NetworkPolicyPeer, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } + return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicyIngressRule. -func (in *WorkspaceNetworkPolicyIngressRule) DeepCopy() *WorkspaceNetworkPolicyIngressRule { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyIngressRule. +func (in *NetworkPolicyIngressRule) DeepCopy() *NetworkPolicyIngressRule { if in == nil { return nil } - out := new(WorkspaceNetworkPolicyIngressRule) + out := new(NetworkPolicyIngressRule) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicyList) DeepCopyInto(out *WorkspaceNetworkPolicyList) { +func (in *NetworkPolicyPeer) DeepCopyInto(out *NetworkPolicyPeer) { *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]WorkspaceNetworkPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicyList. -func (in *WorkspaceNetworkPolicyList) DeepCopy() *WorkspaceNetworkPolicyList { - if in == nil { - return nil - } - out := new(WorkspaceNetworkPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *WorkspaceNetworkPolicyList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c + if in.NamespaceSelector != nil { + in, out := &in.NamespaceSelector, &out.NamespaceSelector + *out = new(NamespaceSelector) + **out = **in } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicyPeer) DeepCopyInto(out *WorkspaceNetworkPolicyPeer) { - *out = *in - in.NetworkPolicyPeer.DeepCopyInto(&out.NetworkPolicyPeer) - if in.WorkspaceSelector != nil { - in, out := &in.WorkspaceSelector, &out.WorkspaceSelector - *out = new(metav1.LabelSelector) + if in.IPBlock != nil { + in, out := &in.IPBlock, &out.IPBlock + *out = new(v1.IPBlock) (*in).DeepCopyInto(*out) } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicyPeer. -func (in *WorkspaceNetworkPolicyPeer) DeepCopy() *WorkspaceNetworkPolicyPeer { - if in == nil { - return nil - } - out := new(WorkspaceNetworkPolicyPeer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicySpec) DeepCopyInto(out *WorkspaceNetworkPolicySpec) { - *out = *in - if in.PolicyTypes != nil { - in, out := &in.PolicyTypes, &out.PolicyTypes - *out = make([]networkingv1.PolicyType, len(*in)) - copy(*out, *in) - } - if in.Ingress != nil { - in, out := &in.Ingress, &out.Ingress - *out = make([]WorkspaceNetworkPolicyIngressRule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Egress != nil { - in, out := &in.Egress, &out.Egress - *out = make([]WorkspaceNetworkPolicyEgressRule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + if in.ServiceSelector != nil { + in, out := &in.ServiceSelector, &out.ServiceSelector + *out = new(ServiceSelector) + **out = **in } + return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicySpec. -func (in *WorkspaceNetworkPolicySpec) DeepCopy() *WorkspaceNetworkPolicySpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyPeer. +func (in *NetworkPolicyPeer) DeepCopy() *NetworkPolicyPeer { if in == nil { return nil } - out := new(WorkspaceNetworkPolicySpec) + out := new(NetworkPolicyPeer) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkspaceNetworkPolicyStatus) DeepCopyInto(out *WorkspaceNetworkPolicyStatus) { +func (in *ServiceSelector) DeepCopyInto(out *ServiceSelector) { *out = *in + return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkspaceNetworkPolicyStatus. -func (in *WorkspaceNetworkPolicyStatus) DeepCopy() *WorkspaceNetworkPolicyStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSelector. +func (in *ServiceSelector) DeepCopy() *ServiceSelector { if in == nil { return nil } - out := new(WorkspaceNetworkPolicyStatus) + out := new(ServiceSelector) in.DeepCopyInto(out) return out } diff --git a/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_network_client.go b/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_network_client.go index f62741d98e5bdea498150e9add4e133d9ad6e07f..571150be6848b1dc805b551bdfbe59f6edb47994 100644 --- a/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_network_client.go +++ b/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_network_client.go @@ -32,10 +32,6 @@ func (c *FakeNetworkV1alpha1) NamespaceNetworkPolicies(namespace string) v1alpha return &FakeNamespaceNetworkPolicies{c, namespace} } -func (c *FakeNetworkV1alpha1) WorkspaceNetworkPolicies() v1alpha1.WorkspaceNetworkPolicyInterface { - return &FakeWorkspaceNetworkPolicies{c} -} - // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeNetworkV1alpha1) RESTClient() rest.Interface { diff --git a/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_workspacenetworkpolicy.go b/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_workspacenetworkpolicy.go deleted file mode 100644 index 8d4b78c3fd190e91ed14cb42140ed1413d147d69..0000000000000000000000000000000000000000 --- a/pkg/client/clientset/versioned/typed/network/v1alpha1/fake/fake_workspacenetworkpolicy.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" - v1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" -) - -// FakeWorkspaceNetworkPolicies implements WorkspaceNetworkPolicyInterface -type FakeWorkspaceNetworkPolicies struct { - Fake *FakeNetworkV1alpha1 -} - -var workspacenetworkpoliciesResource = schema.GroupVersionResource{Group: "network.kubesphere.io", Version: "v1alpha1", Resource: "workspacenetworkpolicies"} - -var workspacenetworkpoliciesKind = schema.GroupVersionKind{Group: "network.kubesphere.io", Version: "v1alpha1", Kind: "WorkspaceNetworkPolicy"} - -// Get takes name of the workspaceNetworkPolicy, and returns the corresponding workspaceNetworkPolicy object, and an error if there is any. -func (c *FakeWorkspaceNetworkPolicies) Get(name string, options v1.GetOptions) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootGetAction(workspacenetworkpoliciesResource, name), &v1alpha1.WorkspaceNetworkPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), err -} - -// List takes label and field selectors, and returns the list of WorkspaceNetworkPolicies that match those selectors. -func (c *FakeWorkspaceNetworkPolicies) List(opts v1.ListOptions) (result *v1alpha1.WorkspaceNetworkPolicyList, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootListAction(workspacenetworkpoliciesResource, workspacenetworkpoliciesKind, opts), &v1alpha1.WorkspaceNetworkPolicyList{}) - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.WorkspaceNetworkPolicyList{ListMeta: obj.(*v1alpha1.WorkspaceNetworkPolicyList).ListMeta} - for _, item := range obj.(*v1alpha1.WorkspaceNetworkPolicyList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested workspaceNetworkPolicies. -func (c *FakeWorkspaceNetworkPolicies) Watch(opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewRootWatchAction(workspacenetworkpoliciesResource, opts)) -} - -// Create takes the representation of a workspaceNetworkPolicy and creates it. Returns the server's representation of the workspaceNetworkPolicy, and an error, if there is any. -func (c *FakeWorkspaceNetworkPolicies) Create(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(workspacenetworkpoliciesResource, workspaceNetworkPolicy), &v1alpha1.WorkspaceNetworkPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), err -} - -// Update takes the representation of a workspaceNetworkPolicy and updates it. Returns the server's representation of the workspaceNetworkPolicy, and an error, if there is any. -func (c *FakeWorkspaceNetworkPolicies) Update(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(workspacenetworkpoliciesResource, workspaceNetworkPolicy), &v1alpha1.WorkspaceNetworkPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), err -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeWorkspaceNetworkPolicies) UpdateStatus(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (*v1alpha1.WorkspaceNetworkPolicy, error) { - obj, err := c.Fake. - Invokes(testing.NewRootUpdateSubresourceAction(workspacenetworkpoliciesResource, "status", workspaceNetworkPolicy), &v1alpha1.WorkspaceNetworkPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), err -} - -// Delete takes name of the workspaceNetworkPolicy and deletes it. Returns an error if one occurs. -func (c *FakeWorkspaceNetworkPolicies) Delete(name string, options *v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewRootDeleteAction(workspacenetworkpoliciesResource, name), &v1alpha1.WorkspaceNetworkPolicy{}) - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeWorkspaceNetworkPolicies) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewRootDeleteCollectionAction(workspacenetworkpoliciesResource, listOptions) - - _, err := c.Fake.Invokes(action, &v1alpha1.WorkspaceNetworkPolicyList{}) - return err -} - -// Patch applies the patch and returns the patched workspaceNetworkPolicy. -func (c *FakeWorkspaceNetworkPolicies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(workspacenetworkpoliciesResource, name, pt, data, subresources...), &v1alpha1.WorkspaceNetworkPolicy{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), err -} diff --git a/pkg/client/clientset/versioned/typed/network/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/network/v1alpha1/generated_expansion.go index c38debbc35c88ec9bf25fecef4b93c42d4d6206f..e4de164f8045e7f10fbdd023b36c11d8282ebc65 100644 --- a/pkg/client/clientset/versioned/typed/network/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/network/v1alpha1/generated_expansion.go @@ -19,5 +19,3 @@ limitations under the License. package v1alpha1 type NamespaceNetworkPolicyExpansion interface{} - -type WorkspaceNetworkPolicyExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/network/v1alpha1/network_client.go b/pkg/client/clientset/versioned/typed/network/v1alpha1/network_client.go index 822b93e38f7c84a68f0141e9e9045527f21edae0..92f0d32770dfb50771a2049bc1219911d3371aef 100644 --- a/pkg/client/clientset/versioned/typed/network/v1alpha1/network_client.go +++ b/pkg/client/clientset/versioned/typed/network/v1alpha1/network_client.go @@ -27,7 +27,6 @@ import ( type NetworkV1alpha1Interface interface { RESTClient() rest.Interface NamespaceNetworkPoliciesGetter - WorkspaceNetworkPoliciesGetter } // NetworkV1alpha1Client is used to interact with features provided by the network.kubesphere.io group. @@ -39,10 +38,6 @@ func (c *NetworkV1alpha1Client) NamespaceNetworkPolicies(namespace string) Names return newNamespaceNetworkPolicies(c, namespace) } -func (c *NetworkV1alpha1Client) WorkspaceNetworkPolicies() WorkspaceNetworkPolicyInterface { - return newWorkspaceNetworkPolicies(c) -} - // NewForConfig creates a new NetworkV1alpha1Client for the given config. func NewForConfig(c *rest.Config) (*NetworkV1alpha1Client, error) { config := *c diff --git a/pkg/client/clientset/versioned/typed/network/v1alpha1/workspacenetworkpolicy.go b/pkg/client/clientset/versioned/typed/network/v1alpha1/workspacenetworkpolicy.go deleted file mode 100644 index a8f51139e47cb657b1b2bee861f4805fc8b0db17..0000000000000000000000000000000000000000 --- a/pkg/client/clientset/versioned/typed/network/v1alpha1/workspacenetworkpolicy.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" - v1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" - scheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" -) - -// WorkspaceNetworkPoliciesGetter has a method to return a WorkspaceNetworkPolicyInterface. -// A group's client should implement this interface. -type WorkspaceNetworkPoliciesGetter interface { - WorkspaceNetworkPolicies() WorkspaceNetworkPolicyInterface -} - -// WorkspaceNetworkPolicyInterface has methods to work with WorkspaceNetworkPolicy resources. -type WorkspaceNetworkPolicyInterface interface { - Create(*v1alpha1.WorkspaceNetworkPolicy) (*v1alpha1.WorkspaceNetworkPolicy, error) - Update(*v1alpha1.WorkspaceNetworkPolicy) (*v1alpha1.WorkspaceNetworkPolicy, error) - UpdateStatus(*v1alpha1.WorkspaceNetworkPolicy) (*v1alpha1.WorkspaceNetworkPolicy, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1alpha1.WorkspaceNetworkPolicy, error) - List(opts v1.ListOptions) (*v1alpha1.WorkspaceNetworkPolicyList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.WorkspaceNetworkPolicy, err error) - WorkspaceNetworkPolicyExpansion -} - -// workspaceNetworkPolicies implements WorkspaceNetworkPolicyInterface -type workspaceNetworkPolicies struct { - client rest.Interface -} - -// newWorkspaceNetworkPolicies returns a WorkspaceNetworkPolicies -func newWorkspaceNetworkPolicies(c *NetworkV1alpha1Client) *workspaceNetworkPolicies { - return &workspaceNetworkPolicies{ - client: c.RESTClient(), - } -} - -// Get takes name of the workspaceNetworkPolicy, and returns the corresponding workspaceNetworkPolicy object, and an error if there is any. -func (c *workspaceNetworkPolicies) Get(name string, options v1.GetOptions) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - result = &v1alpha1.WorkspaceNetworkPolicy{} - err = c.client.Get(). - Resource("workspacenetworkpolicies"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of WorkspaceNetworkPolicies that match those selectors. -func (c *workspaceNetworkPolicies) List(opts v1.ListOptions) (result *v1alpha1.WorkspaceNetworkPolicyList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.WorkspaceNetworkPolicyList{} - err = c.client.Get(). - Resource("workspacenetworkpolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested workspaceNetworkPolicies. -func (c *workspaceNetworkPolicies) Watch(opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Resource("workspacenetworkpolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch() -} - -// Create takes the representation of a workspaceNetworkPolicy and creates it. Returns the server's representation of the workspaceNetworkPolicy, and an error, if there is any. -func (c *workspaceNetworkPolicies) Create(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - result = &v1alpha1.WorkspaceNetworkPolicy{} - err = c.client.Post(). - Resource("workspacenetworkpolicies"). - Body(workspaceNetworkPolicy). - Do(). - Into(result) - return -} - -// Update takes the representation of a workspaceNetworkPolicy and updates it. Returns the server's representation of the workspaceNetworkPolicy, and an error, if there is any. -func (c *workspaceNetworkPolicies) Update(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - result = &v1alpha1.WorkspaceNetworkPolicy{} - err = c.client.Put(). - Resource("workspacenetworkpolicies"). - Name(workspaceNetworkPolicy.Name). - Body(workspaceNetworkPolicy). - Do(). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - -func (c *workspaceNetworkPolicies) UpdateStatus(workspaceNetworkPolicy *v1alpha1.WorkspaceNetworkPolicy) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - result = &v1alpha1.WorkspaceNetworkPolicy{} - err = c.client.Put(). - Resource("workspacenetworkpolicies"). - Name(workspaceNetworkPolicy.Name). - SubResource("status"). - Body(workspaceNetworkPolicy). - Do(). - Into(result) - return -} - -// Delete takes name of the workspaceNetworkPolicy and deletes it. Returns an error if one occurs. -func (c *workspaceNetworkPolicies) Delete(name string, options *v1.DeleteOptions) error { - return c.client.Delete(). - Resource("workspacenetworkpolicies"). - Name(name). - Body(options). - Do(). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *workspaceNetworkPolicies) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - var timeout time.Duration - if listOptions.TimeoutSeconds != nil { - timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Resource("workspacenetworkpolicies"). - VersionedParams(&listOptions, scheme.ParameterCodec). - Timeout(timeout). - Body(options). - Do(). - Error() -} - -// Patch applies the patch and returns the patched workspaceNetworkPolicy. -func (c *workspaceNetworkPolicies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.WorkspaceNetworkPolicy, err error) { - result = &v1alpha1.WorkspaceNetworkPolicy{} - err = c.client.Patch(pt). - Resource("workspacenetworkpolicies"). - SubResource(subresources...). - Name(name). - Body(data). - Do(). - Into(result) - return -} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 34fb32f12d15b7aa4f9baed654ec899373615865..91fcec5076174b3428c7f58914adb45daf6905b3 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -91,8 +91,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=network.kubesphere.io, Version=v1alpha1 case networkv1alpha1.SchemeGroupVersion.WithResource("namespacenetworkpolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().NamespaceNetworkPolicies().Informer()}, nil - case networkv1alpha1.SchemeGroupVersion.WithResource("workspacenetworkpolicies"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Network().V1alpha1().WorkspaceNetworkPolicies().Informer()}, nil // Group=servicemesh.kubesphere.io, Version=v1alpha2 case servicemeshv1alpha2.SchemeGroupVersion.WithResource("servicepolicies"): diff --git a/pkg/client/informers/externalversions/network/v1alpha1/interface.go b/pkg/client/informers/externalversions/network/v1alpha1/interface.go index 37cbe69c7653546ef1a5d255849756309e6bcd96..5185f51af5445830806dd9b4d27f2c72757fa99c 100644 --- a/pkg/client/informers/externalversions/network/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/network/v1alpha1/interface.go @@ -26,8 +26,6 @@ import ( type Interface interface { // NamespaceNetworkPolicies returns a NamespaceNetworkPolicyInformer. NamespaceNetworkPolicies() NamespaceNetworkPolicyInformer - // WorkspaceNetworkPolicies returns a WorkspaceNetworkPolicyInformer. - WorkspaceNetworkPolicies() WorkspaceNetworkPolicyInformer } type version struct { @@ -45,8 +43,3 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (v *version) NamespaceNetworkPolicies() NamespaceNetworkPolicyInformer { return &namespaceNetworkPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } - -// WorkspaceNetworkPolicies returns a WorkspaceNetworkPolicyInformer. -func (v *version) WorkspaceNetworkPolicies() WorkspaceNetworkPolicyInformer { - return &workspaceNetworkPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} diff --git a/pkg/client/informers/externalversions/network/v1alpha1/workspacenetworkpolicy.go b/pkg/client/informers/externalversions/network/v1alpha1/workspacenetworkpolicy.go deleted file mode 100644 index b0773a40f39ef0d5568604922670b314fc384977..0000000000000000000000000000000000000000 --- a/pkg/client/informers/externalversions/network/v1alpha1/workspacenetworkpolicy.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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. -*/ - -// Code generated by informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - time "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" - networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" - versioned "kubesphere.io/kubesphere/pkg/client/clientset/versioned" - internalinterfaces "kubesphere.io/kubesphere/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "kubesphere.io/kubesphere/pkg/client/listers/network/v1alpha1" -) - -// WorkspaceNetworkPolicyInformer provides access to a shared informer and lister for -// WorkspaceNetworkPolicies. -type WorkspaceNetworkPolicyInformer interface { - Informer() cache.SharedIndexInformer - Lister() v1alpha1.WorkspaceNetworkPolicyLister -} - -type workspaceNetworkPolicyInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc -} - -// NewWorkspaceNetworkPolicyInformer constructs a new informer for WorkspaceNetworkPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewWorkspaceNetworkPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredWorkspaceNetworkPolicyInformer(client, resyncPeriod, indexers, nil) -} - -// NewFilteredWorkspaceNetworkPolicyInformer constructs a new informer for WorkspaceNetworkPolicy type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredWorkspaceNetworkPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.NetworkV1alpha1().WorkspaceNetworkPolicies().List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.NetworkV1alpha1().WorkspaceNetworkPolicies().Watch(options) - }, - }, - &networkv1alpha1.WorkspaceNetworkPolicy{}, - resyncPeriod, - indexers, - ) -} - -func (f *workspaceNetworkPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredWorkspaceNetworkPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *workspaceNetworkPolicyInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&networkv1alpha1.WorkspaceNetworkPolicy{}, f.defaultInformer) -} - -func (f *workspaceNetworkPolicyInformer) Lister() v1alpha1.WorkspaceNetworkPolicyLister { - return v1alpha1.NewWorkspaceNetworkPolicyLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/listers/network/v1alpha1/expansion_generated.go b/pkg/client/listers/network/v1alpha1/expansion_generated.go index 85c61d6d0f845e06d0be2787d861aa0600cd7fd7..664c9488c98f6e64632057def310a1fa3aabcc79 100644 --- a/pkg/client/listers/network/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/network/v1alpha1/expansion_generated.go @@ -25,7 +25,3 @@ type NamespaceNetworkPolicyListerExpansion interface{} // NamespaceNetworkPolicyNamespaceListerExpansion allows custom methods to be added to // NamespaceNetworkPolicyNamespaceLister. type NamespaceNetworkPolicyNamespaceListerExpansion interface{} - -// WorkspaceNetworkPolicyListerExpansion allows custom methods to be added to -// WorkspaceNetworkPolicyLister. -type WorkspaceNetworkPolicyListerExpansion interface{} diff --git a/pkg/client/listers/network/v1alpha1/workspacenetworkpolicy.go b/pkg/client/listers/network/v1alpha1/workspacenetworkpolicy.go deleted file mode 100644 index 16d90efc1e94dde773770622eb04651c3800fef8..0000000000000000000000000000000000000000 --- a/pkg/client/listers/network/v1alpha1/workspacenetworkpolicy.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2019 The KubeSphere 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" - v1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" -) - -// WorkspaceNetworkPolicyLister helps list WorkspaceNetworkPolicies. -type WorkspaceNetworkPolicyLister interface { - // List lists all WorkspaceNetworkPolicies in the indexer. - List(selector labels.Selector) (ret []*v1alpha1.WorkspaceNetworkPolicy, err error) - // Get retrieves the WorkspaceNetworkPolicy from the index for a given name. - Get(name string) (*v1alpha1.WorkspaceNetworkPolicy, error) - WorkspaceNetworkPolicyListerExpansion -} - -// workspaceNetworkPolicyLister implements the WorkspaceNetworkPolicyLister interface. -type workspaceNetworkPolicyLister struct { - indexer cache.Indexer -} - -// NewWorkspaceNetworkPolicyLister returns a new WorkspaceNetworkPolicyLister. -func NewWorkspaceNetworkPolicyLister(indexer cache.Indexer) WorkspaceNetworkPolicyLister { - return &workspaceNetworkPolicyLister{indexer: indexer} -} - -// List lists all WorkspaceNetworkPolicies in the indexer. -func (s *workspaceNetworkPolicyLister) List(selector labels.Selector) (ret []*v1alpha1.WorkspaceNetworkPolicy, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.WorkspaceNetworkPolicy)) - }) - return ret, err -} - -// Get retrieves the WorkspaceNetworkPolicy from the index for a given name. -func (s *workspaceNetworkPolicyLister) Get(name string) (*v1alpha1.WorkspaceNetworkPolicy, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("workspacenetworkpolicy"), name) - } - return obj.(*v1alpha1.WorkspaceNetworkPolicy), nil -} diff --git a/pkg/controller/network/controllerapi/interface.go b/pkg/controller/network/controllerapi/interface.go deleted file mode 100644 index 1c93094f47f993f46158d81497cb3d2736372be9..0000000000000000000000000000000000000000 --- a/pkg/controller/network/controllerapi/interface.go +++ /dev/null @@ -1,6 +0,0 @@ -package controllerapi - -// Controller expose Run method -type Controller interface { - Run(threadiness int, stopCh <-chan struct{}) error -} diff --git a/pkg/controller/network/doc.go b/pkg/controller/network/doc.go index 5aa1ac4063097d6e0aaa0e25fc9dc5bb21ee9188..1fc222d26a23f6a7721a934d0988ba1e55537b3c 100644 --- a/pkg/controller/network/doc.go +++ b/pkg/controller/network/doc.go @@ -1,5 +1,5 @@ -package network - -// +kubebuilder:rbac:groups=network.kubesphere.io,resources=workspacenetworkpolicies;namespacenetworkpolicies,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups:core,resource=namespaces,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups=network.kubesphere.io,resources=namespacenetworkpolicies,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=tenant.kubesphere.io,resources=workspaces,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups:core,resource=namespaces,verbs=get;list;watch;create;update;patch +// +kubebuilder:rbac:groups:core,resource=services,verbs=get;list;watch;create;update;patch +package network diff --git a/pkg/controller/network/nsnetworkpolicy/controller.go b/pkg/controller/network/nsnetworkpolicy/controller.go index 7b380aa417bcbe4787b4795e08cabcee6450415b..676b32e86948d034611d50b6393a539fade5e143 100644 --- a/pkg/controller/network/nsnetworkpolicy/controller.go +++ b/pkg/controller/network/nsnetworkpolicy/controller.go @@ -5,173 +5,511 @@ import ( "time" corev1 "k8s.io/api/core/v1" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" + netv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + typev1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + uruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + v1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" - typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/cache" - "k8s.io/client-go/tools/record" "k8s.io/client-go/util/workqueue" "k8s.io/klog" - "k8s.io/klog/klogr" - kubesphereclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned" - kubespherescheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" - networkinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network/v1alpha1" - networklister "kubesphere.io/kubesphere/pkg/client/listers/network/v1alpha1" - "kubesphere.io/kubesphere/pkg/controller/network/controllerapi" + "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" + workspacev1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" + ksnetclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned/typed/network/v1alpha1" + nspolicy "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network/v1alpha1" + workspace "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1" + "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/controller/network/provider" ) -const controllerAgentName = "nsnp-controller" - -type controller struct { - kubeClientset kubernetes.Interface - kubesphereClientset kubesphereclient.Interface - - nsnpInformer networkinformer.NamespaceNetworkPolicyInformer - nsnpLister networklister.NamespaceNetworkPolicyLister - nsnpSynced cache.InformerSynced - // workqueue is a rate limited work queue. This is used to queue work to be - // processed instead of performing it as soon as a change happens. This - // means we can ensure we only process a fixed amount of resources at a - // time, and makes it easy to ensure we are never processing the same item - // simultaneously in two different workers. - workqueue workqueue.RateLimitingInterface - // recorder is an event recorder for recording Event resources to the - // Kubernetes API. - recorder record.EventRecorder - nsNetworkPolicyProvider provider.NsNetworkPolicyProvider -} - -var ( - log = klogr.New().WithName("Controller").WithValues("Component", controllerAgentName) - errCount = 0 +const ( + //use period sync service label in NSNP + defaultSleepDuration = 60 * time.Second + + defaultThread = 5 + defaultSync = "5m" + + //whether network isolate is enable in namespace + NamespaceNPAnnotationKey = "kubesphere.io/network-isolate" + NamespaceNPAnnotationEnabled = "enabled" + + AnnotationNPNAME = "network-isolate" ) -func NewController(kubeclientset kubernetes.Interface, - kubesphereclientset kubesphereclient.Interface, - nsnpInformer networkinformer.NamespaceNetworkPolicyInformer, - nsNetworkPolicyProvider provider.NsNetworkPolicyProvider) controllerapi.Controller { - utilruntime.Must(kubespherescheme.AddToScheme(scheme.Scheme)) - log.V(4).Info("Creating event broadcaster") - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartLogging(klog.Infof) - eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")}) - recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName}) - ctl := &controller{ - kubeClientset: kubeclientset, - kubesphereClientset: kubesphereclientset, - nsnpInformer: nsnpInformer, - nsnpLister: nsnpInformer.Lister(), - nsnpSynced: nsnpInformer.Informer().HasSynced, - nsNetworkPolicyProvider: nsNetworkPolicyProvider, - - workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "NamespaceNetworkPolicies"), - recorder: recorder, - } - log.Info("Setting up event handlers") - nsnpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: ctl.enqueueNSNP, - UpdateFunc: func(old, new interface{}) { - ctl.enqueueNSNP(new) +// namespacenpController implements the Controller interface for managing kubesphere network policies +// and convery them to k8s NetworkPolicies, then syncing them to the provider. +type NSNetworkPolicyController struct { + client kubernetes.Interface + ksclient ksnetclient.NetworkV1alpha1Interface + informer nspolicy.NamespaceNetworkPolicyInformer + informerSynced cache.InformerSynced + + serviceInformer v1.ServiceInformer + serviceInformerSynced cache.InformerSynced + + workspaceInformer workspace.WorkspaceInformer + workspaceInformerSynced cache.InformerSynced + + namespaceInformer v1.NamespaceInformer + namespaceInformerSynced cache.InformerSynced + + provider provider.NsNetworkPolicyProvider + + nsQueue workqueue.RateLimitingInterface + nsnpQueue workqueue.RateLimitingInterface +} + +func (c *NSNetworkPolicyController) convertPeer(peers []v1alpha1.NetworkPolicyPeer) ([]netv1.NetworkPolicyPeer, error) { + if len(peers) <= 0 { + return nil, nil + } + + rules := make([]netv1.NetworkPolicyPeer, 0) + + for _, peer := range peers { + rule := netv1.NetworkPolicyPeer{} + + if peer.ServiceSelector != nil { + rule.PodSelector = new(metav1.LabelSelector) + rule.NamespaceSelector = new(metav1.LabelSelector) + + namespace := peer.ServiceSelector.Namespace + name := peer.ServiceSelector.Name + service, err := c.serviceInformer.Lister().Services(namespace).Get(name) + if err != nil { + return nil, err + } + + if len(service.Spec.Selector) <= 0 { + return nil, fmt.Errorf("service %s/%s has no podselect", namespace, name) + } + + rule.PodSelector.MatchLabels = make(map[string]string) + for key, value := range service.Spec.Selector { + rule.PodSelector.MatchLabels[key] = value + } + rule.NamespaceSelector.MatchLabels = make(map[string]string) + rule.NamespaceSelector.MatchLabels[constants.NamespaceLabelKey] = namespace + } else if peer.NamespaceSelector != nil { + name := peer.NamespaceSelector.Name + + rule.NamespaceSelector = new(metav1.LabelSelector) + rule.NamespaceSelector.MatchLabels = make(map[string]string) + rule.NamespaceSelector.MatchLabels[constants.NamespaceLabelKey] = name + } else if peer.IPBlock != nil { + rule.IPBlock = peer.IPBlock + } else { + klog.Errorf("Invalid nsnp peer %v\n", peer) + continue + } + rules = append(rules, rule) + } + + return rules, nil +} + +func (c *NSNetworkPolicyController) convertToK8sNP(n *v1alpha1.NamespaceNetworkPolicy) (*netv1.NetworkPolicy, error) { + np := &netv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: n.Name, + Namespace: n.Namespace, }, - DeleteFunc: ctl.enqueueNSNP, - }) - return ctl + Spec: netv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{}, + PolicyTypes: make([]netv1.PolicyType, 0), + }, + } + + if n.Spec.Egress != nil { + np.Spec.Egress = make([]netv1.NetworkPolicyEgressRule, len(n.Spec.Egress)) + for indexEgress, egress := range n.Spec.Egress { + rules, err := c.convertPeer(egress.To) + if err != nil { + return nil, err + } + np.Spec.Egress[indexEgress].To = rules + np.Spec.Egress[indexEgress].Ports = egress.Ports + } + np.Spec.PolicyTypes = append(np.Spec.PolicyTypes, netv1.PolicyTypeEgress) + } + + if n.Spec.Ingress != nil { + np.Spec.Ingress = make([]netv1.NetworkPolicyIngressRule, len(n.Spec.Ingress)) + for indexIngress, ingress := range n.Spec.Ingress { + rules, err := c.convertPeer(ingress.From) + if err != nil { + return nil, err + } + np.Spec.Ingress[indexIngress].From = rules + np.Spec.Ingress[indexIngress].Ports = ingress.Ports + } + np.Spec.PolicyTypes = append(np.Spec.PolicyTypes, netv1.PolicyTypeIngress) + } + + return np, nil } -func (c *controller) Run(threadiness int, stopCh <-chan struct{}) error { - defer utilruntime.HandleCrash() - defer c.workqueue.ShutDown() +func generateNSNP(workspace string, namespace string, matchWorkspace bool) *netv1.NetworkPolicy { + policy := &netv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: AnnotationNPNAME, + Namespace: namespace, + }, + Spec: netv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{}, + PolicyTypes: make([]netv1.PolicyType, 0), + Ingress: []netv1.NetworkPolicyIngressRule{{ + From: []netv1.NetworkPolicyPeer{{ + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }, + }}, + }}, + Egress: []netv1.NetworkPolicyEgressRule{{ + To: []netv1.NetworkPolicyPeer{{ + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }, + }}, + }}, + }, + } + + policy.Spec.PolicyTypes = append(policy.Spec.PolicyTypes, netv1.PolicyTypeIngress, netv1.PolicyTypeEgress) - //init client + if matchWorkspace { + policy.Spec.Ingress[0].From[0].NamespaceSelector.MatchLabels[constants.WorkspaceLabelKey] = workspace + policy.Spec.Egress[0].To[0].NamespaceSelector.MatchLabels[constants.WorkspaceLabelKey] = workspace + } else { + policy.Spec.Ingress[0].From[0].NamespaceSelector.MatchLabels[constants.NamespaceLabelKey] = namespace + policy.Spec.Egress[0].To[0].NamespaceSelector.MatchLabels[constants.NamespaceLabelKey] = namespace + } - // Start the informer factories to begin populating the informer caches - log.V(1).Info("Starting WSNP controller") + return policy +} - // Wait for the caches to be synced before starting workers - log.V(2).Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, c.nsnpSynced); !ok { - return fmt.Errorf("failed to wait for caches to sync") +func (c *NSNetworkPolicyController) nsEnqueue(ns *corev1.Namespace) { + key, err := cache.MetaNamespaceKeyFunc(ns) + if err != nil { + uruntime.HandleError(fmt.Errorf("Get namespace key %s failed", ns.Name)) + return } - log.Info("Starting workers") - // Launch two workers to process Foo resources - for i := 0; i < threadiness; i++ { - go wait.Until(c.runWorker, time.Second, stopCh) + klog.V(4).Infof("Enqueue namespace %s", ns.Name) + c.nsQueue.Add(key) +} + +func (c *NSNetworkPolicyController) addWorkspace(newObj interface{}) { + new := newObj.(*workspacev1alpha1.Workspace) + + klog.V(4).Infof("Add workspace %s", new.Name) + + label := labels.SelectorFromSet(labels.Set{constants.WorkspaceLabelKey: new.Name}) + nsList, err := c.namespaceInformer.Lister().List(label) + if err != nil { + klog.Errorf("Error while list namespace by label %s", label.String()) + return } - klog.V(2).Info("Started workers") - <-stopCh - log.V(2).Info("Shutting down workers") - return nil + for _, ns := range nsList { + c.nsEnqueue(ns) + } } -func (c *controller) enqueueNSNP(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - utilruntime.HandleError(err) +func (c *NSNetworkPolicyController) addNamespace(obj interface{}) { + ns := obj.(*corev1.Namespace) + + workspaceName := ns.Labels[constants.WorkspaceLabelKey] + if workspaceName == "" { return } - c.workqueue.Add(key) + + klog.V(4).Infof("Add namespace %s", ns.Name) + + c.nsEnqueue(ns) } -func (c *controller) runWorker() { - for c.processNextWorkItem() { +func isNetworkIsolateEnabled(ns *corev1.Namespace) bool { + if ns.Annotations[NamespaceNPAnnotationKey] == NamespaceNPAnnotationEnabled { + return true } + + return false } -func (c *controller) processNextWorkItem() bool { - obj, shutdown := c.workqueue.Get() +func hadNamespaceLabel(ns *corev1.Namespace) bool { + if ns.Annotations[constants.NamespaceLabelKey] == ns.Name { + return true + } - if shutdown { - return false + return false +} + +func (c *NSNetworkPolicyController) syncNs(key string) error { + klog.V(4).Infof("Sync namespace %s", key) + + _, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + klog.Errorf("Not a valid controller key %s, %#v", key, err) + return err } - // We wrap this block in a func so we can defer c.workqueue.Done. - err := func(obj interface{}) error { - // We call Done here so the workqueue knows we have finished - // processing this item. We also must remember to call Forget if we - // do not want this work item being re-queued. For example, we do - // not call Forget if a transient error occurs, instead the item is - // put back on the workqueue and attempted again after a back-off - // period. - defer c.workqueue.Done(obj) - var key string - var ok bool - // We expect strings to come off the workqueue. These are of the - // form namespace/name. We do this as the delayed nature of the - // workqueue means the items in the informer cache may actually be - // more up to date that when the item was initially put onto the - // workqueue. - if key, ok = obj.(string); !ok { - // As the item in the workqueue is actually invalid, we call - // Forget here else we'd go into a loop of attempting to - // process a work item that is invalid. - c.workqueue.Forget(obj) - utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) + ns, err := c.namespaceInformer.Lister().Get(name) + if err != nil { + // not found, possibly been deleted + if errors.IsNotFound(err) { + klog.V(2).Infof("Namespace %v has been deleted", key) return nil } - // Run the reconcile, passing it the namespace/name string of the - // Foo resource to be synced. - if err := c.reconcile(key); err != nil { - // Put the item back on the workqueue to handle any transient errors. - c.workqueue.AddRateLimited(key) - return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) + + return err + } + + workspaceName := ns.Labels[constants.WorkspaceLabelKey] + if workspaceName == "" { + klog.Error("Workspace name should not be empty") + return nil + } + wksp, err := c.workspaceInformer.Lister().Get(workspaceName) + if err != nil { + //Should not be here + if errors.IsNotFound(err) { + klog.V(2).Infof("Workspace %v has been deleted", workspaceName) + return nil + } + + return err + } + + //Maybe some ns not labeled + if !hadNamespaceLabel(ns) { + ns.Labels[constants.NamespaceLabelKey] = ns.Name + _, err := c.client.CoreV1().Namespaces().Update(ns) + if err != nil { + //Just log, label can also be added by namespace controller + klog.Errorf("cannot label namespace %s", ns.Name) } - // Finally, if no error occurs we Forget this item so it does not - // get queued again until another change happens. - c.workqueue.Forget(obj) - log.Info("Successfully synced", "key", key) + } + + matchWorkspace := false + delete := false + if isNetworkIsolateEnabled(ns) { + matchWorkspace = false + } else if wksp.Spec.NetworkIsolation { + matchWorkspace = true + } else { + delete = true + } + + policy := generateNSNP(workspaceName, ns.Name, matchWorkspace) + if delete { + c.provider.Delete(c.provider.GetKey(AnnotationNPNAME, ns.Name)) + //delete all namespace np when networkisolate not active + if c.ksclient.NamespaceNetworkPolicies(ns.Name).DeleteCollection(nil, typev1.ListOptions{}) != nil { + klog.Errorf("Error when delete all nsnps in namespace %s", ns.Name) + } + } else { + err = c.provider.Set(policy) + if err != nil { + klog.Errorf("Error while converting %#v to provider's network policy.", policy) + return err + } + } + + return nil +} + +func (c *NSNetworkPolicyController) nsWorker() { + for c.processNsWorkItem() { + } +} + +func (c *NSNetworkPolicyController) processNsWorkItem() bool { + key, quit := c.nsQueue.Get() + if quit { + return false + } + defer c.nsQueue.Done(key) + + if err := c.syncNs(key.(string)); err != nil { + klog.Errorf("Error when syncns %s", err) + } + + return true +} + +func (c *NSNetworkPolicyController) nsnpEnqueue(obj interface{}) { + nsnp := obj.(*v1alpha1.NamespaceNetworkPolicy) + + key, err := cache.MetaNamespaceKeyFunc(nsnp) + if err != nil { + uruntime.HandleError(fmt.Errorf("get namespace network policy key %s failed", nsnp.Name)) + return + } + + c.nsnpQueue.Add(key) +} + +func (c *NSNetworkPolicyController) syncNSNP(key string) error { + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + klog.Errorf("Not a valid controller key %s, %#v", key, err) + return err + } + + ns, err := c.namespaceInformer.Lister().Get(namespace) + if !isNetworkIsolateEnabled(ns) { + klog.Infof("Delete NSNP %s when namespace isolate is inactive", key) + c.provider.Delete(c.provider.GetKey(name, namespace)) return nil - }(obj) + } + nsnp, err := c.informer.Lister().NamespaceNetworkPolicies(namespace).Get(name) if err != nil { - utilruntime.HandleError(err) - return true + if errors.IsNotFound(err) { + klog.V(4).Infof("NSNP %v has been deleted", key) + c.provider.Delete(c.provider.GetKey(name, namespace)) + return nil + } + + return err + } + + np, err := c.convertToK8sNP(nsnp) + if err != nil { + klog.Errorf("Error while convert nsnp to k8snp: %s", err) + return err + } + err = c.provider.Set(np) + if err != nil { + return err + } + + return nil +} + +func (c *NSNetworkPolicyController) nsNPWorker() { + for c.processNSNPWorkItem() { + } +} + +func (c *NSNetworkPolicyController) processNSNPWorkItem() bool { + key, quit := c.nsnpQueue.Get() + if quit { + return false } + defer c.nsnpQueue.Done(key) + + c.syncNSNP(key.(string)) return true } + +// NewnamespacenpController returns a controller which manages NSNSP objects. +func NewNSNetworkPolicyController( + client kubernetes.Interface, + ksclient ksnetclient.NetworkV1alpha1Interface, + nsnpInformer nspolicy.NamespaceNetworkPolicyInformer, + serviceInformer v1.ServiceInformer, + workspaceInformer workspace.WorkspaceInformer, + namespaceInformer v1.NamespaceInformer, + policyProvider provider.NsNetworkPolicyProvider) *NSNetworkPolicyController { + + controller := &NSNetworkPolicyController{ + client: client, + ksclient: ksclient, + informer: nsnpInformer, + informerSynced: nsnpInformer.Informer().HasSynced, + serviceInformer: serviceInformer, + serviceInformerSynced: serviceInformer.Informer().HasSynced, + workspaceInformer: workspaceInformer, + workspaceInformerSynced: workspaceInformer.Informer().HasSynced, + namespaceInformer: namespaceInformer, + namespaceInformerSynced: namespaceInformer.Informer().HasSynced, + provider: policyProvider, + nsQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespace"), + nsnpQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespacenp"), + } + + workspaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.addWorkspace, + UpdateFunc: func(oldObj, newObj interface{}) { + old := oldObj.(*workspacev1alpha1.Workspace) + new := oldObj.(*workspacev1alpha1.Workspace) + if old.Spec.NetworkIsolation == new.Spec.NetworkIsolation { + return + } + controller.addWorkspace(newObj) + }, + }) + + namespaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.addNamespace, + UpdateFunc: func(oldObj interface{}, newObj interface{}) { + old := oldObj.(*corev1.Namespace) + new := oldObj.(*corev1.Namespace) + if old.Annotations[NamespaceNPAnnotationKey] == new.Annotations[NamespaceNPAnnotationKey] { + return + } + controller.addNamespace(newObj) + }, + }) + + nsnpInformer.Informer().AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + klog.V(4).Infof("Got ADD event for NSNSP: %#v", obj) + controller.nsnpEnqueue(obj) + }, + UpdateFunc: func(oldObj interface{}, newObj interface{}) { + klog.V(4).Info("Got UPDATE event for NSNSP.") + klog.V(4).Infof("Old object: \n%#v\n", oldObj) + klog.V(4).Infof("New object: \n%#v\n", newObj) + controller.nsnpEnqueue(newObj) + }, + DeleteFunc: func(obj interface{}) { + klog.V(4).Infof("Got DELETE event for NSNP: %#v", obj) + controller.nsnpEnqueue(obj) + }, + }, defaultSleepDuration) + + return controller +} + +func (c *NSNetworkPolicyController) Start(stopCh <-chan struct{}) error { + return c.Run(defaultThread, defaultSync, stopCh) +} + +// Run starts the controller. +func (c *NSNetworkPolicyController) Run(threadiness int, reconcilerPeriod string, stopCh <-chan struct{}) error { + defer uruntime.HandleCrash() + + defer c.nsQueue.ShutDown() + defer c.nsnpQueue.ShutDown() + + klog.Info("Waiting to sync with Kubernetes API (NSNP)") + if ok := cache.WaitForCacheSync(stopCh, c.informerSynced, c.serviceInformerSynced, c.workspaceInformerSynced, c.namespaceInformerSynced); !ok { + return fmt.Errorf("Failed to wait for caches to sync") + } + klog.Info("Finished syncing with Kubernetes API (NSNP)") + + // Start a number of worker threads to read from the queue. Each worker + // will pull keys off the resource cache event queue and sync them to the + // K8s datastore. + for i := 0; i < threadiness; i++ { + go wait.Until(c.nsWorker, time.Second, stopCh) + go wait.Until(c.nsNPWorker, time.Second, stopCh) + } + + //Work to sync K8s NetworkPolicy + go c.provider.Start(stopCh) + + klog.Info("NSNP controller is now running") + <-stopCh + klog.Info("Stopping NSNP controller") + + return nil +} diff --git a/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_suite_test.go b/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_suite_test.go index 23e1eda18f25e66eeb81857be85d97c4549fb8f3..fe2c10c91202a98c2d7469194098289bed92ff94 100644 --- a/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_suite_test.go +++ b/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_suite_test.go @@ -11,8 +11,7 @@ import ( func TestNsnetworkpolicy(t *testing.T) { klog.InitFlags(nil) - flag.Set("logtostderr", "false") - flag.Set("alsologtostderr", "false") + flag.Set("logtostderr", "true") flag.Set("v", "4") flag.Parse() klog.SetOutput(GinkgoWriter) diff --git a/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_test.go b/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_test.go index 101fa29ce42fa82287fa0a559d1d88d627db8861..af1d5ca5fae90837401a12977a9cccc2227e83e2 100644 --- a/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_test.go +++ b/pkg/controller/network/nsnetworkpolicy/nsnetworkpolicy_test.go @@ -1,90 +1,285 @@ package nsnetworkpolicy import ( + "fmt" + "reflect" + "strings" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" - nsnplister "kubesphere.io/kubesphere/pkg/client/listers/network/v1alpha1" - "kubesphere.io/kubesphere/pkg/controller/network/controllerapi" + corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/util/yaml" + kubeinformers "k8s.io/client-go/informers" + informerv1 "k8s.io/client-go/informers/core/v1" + kubefake "k8s.io/client-go/kubernetes/fake" + netv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" + wkspv1alpha1 "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" + ksfake "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" + ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" + nsnppolicyinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network/v1alpha1" + workspaceinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1" + "kubesphere.io/kubesphere/pkg/constants" "kubesphere.io/kubesphere/pkg/controller/network/provider" - controllertesting "kubesphere.io/kubesphere/pkg/controller/network/testing" ) var ( - fakeControllerBuilder *controllertesting.FakeControllerBuilder - c controllerapi.Controller - stopCh chan struct{} - calicoProvider *provider.FakeCalicoNetworkProvider - nsnpLister nsnplister.NamespaceNetworkPolicyLister + c *NSNetworkPolicyController + stopCh chan struct{} + nsnpInformer nsnppolicyinformer.NamespaceNetworkPolicyInformer + serviceInformer informerv1.ServiceInformer + workspaceInformer workspaceinformer.WorkspaceInformer + namespaceInformer informerv1.NamespaceInformer + alwaysReady = func() bool { return true } +) + +const ( + workspaceNP = ` +apiVersion: "networking.k8s.io/v1" +kind: "NetworkPolicy" +metadata: + name: networkisolate + namespace: %s +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + %s: %s + Egress: + - To: + - namespaceSelector: + matchLabels: + %s: %s + policyTypes: + - Ingress + - Egress` + + serviceTmp = ` +apiVersion: v1 +kind: Service +metadata: + name: myservice + namespace: testns +spec: + selector: + app: mylbapp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +` + + workspaceTmp = ` +apiVersion: tenant.kubesphere.io/v1alpha1 +kind: Workspace +metadata: + annotations: + kubesphere.io/creator: admin + name: testworkspace +spec: + manager: admin + networkIsolation: true +status: {} +` + + nsTmp = ` +apiVersion: v1 +kind: Namespace +metadata: + labels: + kubesphere.io/workspace: testworkspace + name: testns +spec: + finalizers: + - kubernetes +` ) +func StringToObject(data string, obj interface{}) error { + reader := strings.NewReader(data) + return yaml.NewYAMLOrJSONDecoder(reader, 10).Decode(obj) +} + var _ = Describe("Nsnetworkpolicy", func() { BeforeEach(func() { - fakeControllerBuilder = controllertesting.NewFakeControllerBuilder() stopCh = make(chan struct{}) - informer, _ := fakeControllerBuilder.NewControllerInformer() - calicoProvider = provider.NewFakeCalicoNetworkProvider() - c = NewController(fakeControllerBuilder.KubeClient, fakeControllerBuilder.KsClient, informer.Network().V1alpha1().NamespaceNetworkPolicies(), calicoProvider) - go informer.Network().V1alpha1().NamespaceNetworkPolicies().Informer().Run(stopCh) - originalController := c.(*controller) - originalController.recorder = &record.FakeRecorder{} - go c.Run(1, stopCh) - nsnpLister = informer.Network().V1alpha1().NamespaceNetworkPolicies().Lister() + calicoProvider := provider.NewFakeNetworkProvider() + + kubeClient := kubefake.NewSimpleClientset() + ksClient := ksfake.NewSimpleClientset() + kubeInformer := kubeinformers.NewSharedInformerFactory(kubeClient, 0) + ksInformer := ksinformers.NewSharedInformerFactory(ksClient, 0) + + nsnpInformer := ksInformer.Network().V1alpha1().NamespaceNetworkPolicies() + serviceInformer := kubeInformer.Core().V1().Services() + workspaceInformer := ksInformer.Tenant().V1alpha1().Workspaces() + namespaceInformer := kubeInformer.Core().V1().Namespaces() + + c = NewNSNetworkPolicyController(kubeClient, ksClient.NetworkV1alpha1(), nsnpInformer, serviceInformer, workspaceInformer, namespaceInformer, calicoProvider) + + serviceObj := &corev1.Service{} + Expect(StringToObject(serviceTmp, serviceObj)).ShouldNot(HaveOccurred()) + Expect(serviceInformer.Informer().GetIndexer().Add(serviceObj)).ShouldNot(HaveOccurred()) + nsObj := &corev1.Namespace{} + Expect(StringToObject(nsTmp, nsObj)).ShouldNot(HaveOccurred()) + namespaceInformer.Informer().GetIndexer().Add(nsObj) + workspaceObj := &wkspv1alpha1.Workspace{} + Expect(StringToObject(workspaceTmp, workspaceObj)).ShouldNot(HaveOccurred()) + workspaceInformer.Informer().GetIndexer().Add(workspaceObj) + + c.namespaceInformerSynced = alwaysReady + c.serviceInformerSynced = alwaysReady + c.workspaceInformerSynced = alwaysReady + c.informerSynced = alwaysReady + + go c.Start(stopCh) }) - It("Should create a new calico object", func() { - objSrt := `{ - "apiVersion": "network.kubesphere.io/v1alpha1", - "kind": "NetworkPolicy", - "metadata": { - "name": "allow-tcp-6379", - "namespace": "production" - }, - "spec": { - "selector": "color == 'red'", - "ingress": [ - { - "action": "Allow", - "protocol": "TCP", - "source": { - "selector": "color == 'blue'" - }, - "destination": { - "ports": [ - 6379 - ] - } - } - ] - } - }` - obj := &v1alpha1.NamespaceNetworkPolicy{} - Expect(controllertesting.StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) - _, err := fakeControllerBuilder.KsClient.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Create(obj) + It("Should create ns networkisolate np correctly in workspace", func() { + objSrt := fmt.Sprintf(workspaceNP, "testns", constants.WorkspaceLabelKey, "testworkspace", constants.WorkspaceLabelKey, "testworkspace") + obj := &netv1.NetworkPolicy{} + Expect(StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) + + policy := generateNSNP("testworkspace", "testns", true) + Expect(reflect.DeepEqual(obj.Spec, policy.Spec)).To(BeTrue()) + }) + + It("Should create ns networkisolate np correctly in ns", func() { + objSrt := fmt.Sprintf(workspaceNP, "testns", constants.NamespaceLabelKey, "testns", constants.NamespaceLabelKey, "testns") + obj := &netv1.NetworkPolicy{} + Expect(StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) + + policy := generateNSNP("testworkspace", "testns", false) + Expect(reflect.DeepEqual(obj.Spec, policy.Spec)).To(BeTrue()) + }) + + It("test func convertToK8sNP", func() { + objSrt := ` +apiVersion: network.kubesphere.io/v1alpha1 +kind: NamespaceNetworkPolicy +metadata: + name: namespaceIPblockNP + namespace: testns +spec: + ingress: + - from: + - ipBlock: + cidr: 172.0.0.1/16 + ports: + - protocol: TCP + port: 80 +` + obj := &netv1alpha1.NamespaceNetworkPolicy{} + Expect(StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) + policy, err := c.convertToK8sNP(obj) + + objSrt = ` +apiVersion: "networking.k8s.io/v1" +kind: "NetworkPolicy" +metadata: + name: IPblockNP + namespace: testns +spec: + ingress: + - from: + - ipBlock: + cidr: 172.0.0.1/16 + ports: + - protocol: TCP + port: 80 + policyTypes: + - Ingress +` + obj2 := &netv1.NetworkPolicy{} + Expect(StringToObject(objSrt, obj2)).ShouldNot(HaveOccurred()) + Expect(err).ShouldNot(HaveOccurred()) + Expect(reflect.DeepEqual(obj2.Spec, policy.Spec)).To(BeTrue()) + }) + + It("test func convertToK8sNP with namespace", func() { + objSrt := ` +apiVersion: network.kubesphere.io/v1alpha1 +kind: NamespaceNetworkPolicy +metadata: + name: testnamespace + namespace: testns2 +spec: + ingress: + - from: + - namespace: + name: testns +` + obj := &netv1alpha1.NamespaceNetworkPolicy{} + Expect(StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) + + np, err := c.convertToK8sNP(obj) Expect(err).ShouldNot(HaveOccurred()) - Eventually(func() bool { - exist, _ := calicoProvider.CheckExist(obj) - return exist - }).Should(BeTrue()) - obj, _ = fakeControllerBuilder.KsClient.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Get(obj.Name, metav1.GetOptions{}) - Expect(obj.Finalizers).To(HaveLen(1)) - // TestUpdate - newStr := "color == 'green'" - obj.Spec.Selector = newStr - _, err = fakeControllerBuilder.KsClient.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Update(obj) + + objTmp := ` +apiVersion: "networking.k8s.io/v1" +kind: "NetworkPolicy" +metadata: + name: testnamespace + namespace: testns2 +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + %s: %s + policyTypes: + - Ingress` + objSrt = fmt.Sprintf(objTmp, constants.NamespaceLabelKey, "testns") + obj2 := &netv1.NetworkPolicy{} + Expect(StringToObject(objSrt, obj2)).ShouldNot(HaveOccurred()) + Expect(reflect.DeepEqual(np.Spec, obj2.Spec)).To(BeTrue()) + }) + + It("test func convertToK8sNP with service", func() { + objSrt := ` +apiVersion: network.kubesphere.io/v1alpha1 +kind: NamespaceNetworkPolicy +metadata: + name: testnamespace + namespace: testns2 +spec: + ingress: + - from: + - service: + name: myservice + namespace: testns +` + obj := &netv1alpha1.NamespaceNetworkPolicy{} + Expect(StringToObject(objSrt, obj)).ShouldNot(HaveOccurred()) + + np, err := c.convertToK8sNP(obj) Expect(err).ShouldNot(HaveOccurred()) - Eventually(func() string { - o, err := calicoProvider.Get(obj) - if err != nil { - return err.Error() - } - n := o.(*v1alpha1.NamespaceNetworkPolicy) - return n.Spec.Selector - }).Should(Equal(newStr)) - // TestDelete - Expect(fakeControllerBuilder.KsClient.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Delete(obj.Name, &metav1.DeleteOptions{})).ShouldNot(HaveOccurred()) + + objSrt = ` +apiVersion: "networking.k8s.io/v1" +kind: NetworkPolicy +metadata: + name: networkisolate + namespace: testns +spec: + podSelector: {} + ingress: + - from: + - podSelector: + matchLabels: + app: mylbapp + namespaceSelector: + matchLabels: + kubesphere.io/namespace: testns + policyTypes: + - Ingress +` + obj2 := &netv1.NetworkPolicy{} + Expect(StringToObject(objSrt, obj2)).ShouldNot(HaveOccurred()) + Expect(reflect.DeepEqual(np.Spec, obj2.Spec)).To(BeTrue()) }) AfterEach(func() { diff --git a/pkg/controller/network/nsnetworkpolicy/reconcile.go b/pkg/controller/network/nsnetworkpolicy/reconcile.go deleted file mode 100644 index 1b65e9c7c8ccfebbb30ba0c907f09f7af8f54f78..0000000000000000000000000000000000000000 --- a/pkg/controller/network/nsnetworkpolicy/reconcile.go +++ /dev/null @@ -1,119 +0,0 @@ -package nsnetworkpolicy - -import ( - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" - "kubesphere.io/kubesphere/pkg/controller/network/utils" -) - -const ( - controllerFinalizier = "nsnp.finalizers.networking.kubesphere.io" -) - -var clog logr.Logger - -func (c *controller) reconcile(key string) error { - namespace, name, err := cache.SplitMetaNamespaceKey(key) - if err != nil { - return err - } - clog = log.WithValues("name", name, "namespace", namespace) - clog.V(1).Info("---------Begin to reconcile--------") - defer clog.V(1).Info("---------Reconcile done--------") - obj, err := c.nsnpLister.NamespaceNetworkPolicies(namespace).Get(name) - if err != nil { - if errors.IsNotFound(err) { - clog.V(2).Info("Object is removed") - return nil - } - clog.Error(err, "Failed to get resource") - return err - } - stop, err := c.addOrRemoveFinalizer(obj) - if err != nil { - return err - } - if stop { - return nil - } - clog.V(2).Info("Check if we need a create or update") - ok, err := c.nsNetworkPolicyProvider.CheckExist(obj) - if err != nil { - clog.Error(err, "Failed to check exist of network policy") - return err - } - if !ok { - clog.V(1).Info("Create a new object in backend") - err = c.nsNetworkPolicyProvider.Add(obj) - if err != nil { - clog.Error(err, "Failed to create np") - return err - } - return nil - } - - needUpdate, err := c.nsNetworkPolicyProvider.NeedUpdate(obj) - if err != nil { - clog.Error(err, "Failed to check if object need a update") - return err - } - if needUpdate { - clog.V(1).Info("Update object in backend") - err = c.nsNetworkPolicyProvider.Update(obj) - if err != nil { - clog.Error(err, "Failed to update object") - return err - } - } - return nil -} - -func (c *controller) addOrRemoveFinalizer(obj *v1alpha1.NamespaceNetworkPolicy) (bool, error) { - if obj.ObjectMeta.DeletionTimestamp.IsZero() { - if !utils.ContainsString(obj.ObjectMeta.Finalizers, controllerFinalizier) { - clog.V(2).Info("Detect no finalizer") - obj.ObjectMeta.Finalizers = append(obj.ObjectMeta.Finalizers, controllerFinalizier) - err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - _, err := c.kubesphereClientset.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Update(obj) - return err - }) - if err != nil { - clog.Error(err, "Failed to add finalizer") - return false, err - } - return false, nil - } - } else { - // The object is being deleted - if utils.ContainsString(obj.ObjectMeta.Finalizers, controllerFinalizier) { - // our finalizer is present, so lets handle any external dependency - if err := c.deleteProviderNSNP(obj); err != nil { - // if fail to delete the external dependency here, return with error - // so that it can be retried - return false, err - } - clog.V(2).Info("Removing finalizer") - // remove our finalizer from the list and update it. - obj.ObjectMeta.Finalizers = utils.RemoveString(obj.ObjectMeta.Finalizers, controllerFinalizier) - err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { - _, err := c.kubesphereClientset.NetworkV1alpha1().NamespaceNetworkPolicies(obj.Namespace).Update(obj) - return err - }) - if err != nil { - clog.Error(err, "Failed to remove finalizer") - return false, err - } - return true, nil - } - } - return false, nil -} - -// deleteProviderNSNP delete network policy in the backend -func (c *controller) deleteProviderNSNP(obj *v1alpha1.NamespaceNetworkPolicy) error { - clog.V(2).Info("Deleting backend network policy") - return c.nsNetworkPolicyProvider.Delete(obj) -} diff --git a/pkg/controller/network/nsnetworkpolicy/webhook.go b/pkg/controller/network/nsnetworkpolicy/webhook.go new file mode 100644 index 0000000000000000000000000000000000000000..1a15345629c3ea0904fb1d9d5d846fbe3e532af3 --- /dev/null +++ b/pkg/controller/network/nsnetworkpolicy/webhook.go @@ -0,0 +1,38 @@ +package nsnetworkpolicy + +import ( + "context" + "fmt" + "net/http" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// +kubebuilder:webhook:path=/validate-service-nsnp-kubesphere-io-v1alpha1-network,name=validate-v1-service,mutating=false,failurePolicy=fail,groups="",resources=services,verbs=create;update,versions=v1 + +// serviceValidator validates service +type ServiceValidator struct { + decoder *admission.Decoder +} + +// Service must hash label, becasue nsnp will use it +func (v *ServiceValidator) Handle(ctx context.Context, req admission.Request) admission.Response { + service := &corev1.Service{} + + err := v.decoder.Decode(req, service) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + + if service.Spec.Selector == nil { + return admission.Denied(fmt.Sprintf("missing label")) + } + + return admission.Allowed("") +} + +func (a *ServiceValidator) InjectDecoder(d *admission.Decoder) error { + a.decoder = d + return nil +} diff --git a/pkg/controller/network/provider/calico_k8s.go b/pkg/controller/network/provider/calico_k8s.go deleted file mode 100644 index 137cc0494b60459dea4535acbca353d3ecd7578f..0000000000000000000000000000000000000000 --- a/pkg/controller/network/provider/calico_k8s.go +++ /dev/null @@ -1,3 +0,0 @@ -package provider - -// +kubebuilder:rbac:groups="crd.projectcalico.org",resources=globalfelixconfigs;felixconfigurations;ippools;ipamblocks;globalnetworkpolicies;globalnetworksets;networkpolicies;networksets;clusterinformations;hostendpoints,verbs=get;list;watch;create;patch;update;delete diff --git a/pkg/controller/network/provider/fake_ns.go b/pkg/controller/network/provider/fake_ns.go new file mode 100644 index 0000000000000000000000000000000000000000..a2ec4755d78f9e428e229e66261092a5e3412f47 --- /dev/null +++ b/pkg/controller/network/provider/fake_ns.go @@ -0,0 +1,49 @@ +package provider + +import ( + "fmt" + + "github.com/projectcalico/kube-controllers/pkg/converter" + api "github.com/projectcalico/libcalico-go/lib/apis/v3" + constants "github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion" + v1 "k8s.io/api/networking/v1" +) + +func NewFakeNetworkProvider() *FakeNetworkProvider { + f := new(FakeNetworkProvider) + f.NSNPData = make(map[string]*api.NetworkPolicy) + f.policyConverter = converter.NewPolicyConverter() + return f +} + +type FakeNetworkProvider struct { + NSNPData map[string]*api.NetworkPolicy + policyConverter converter.Converter +} + +func (f *FakeNetworkProvider) Delete(key string) { + delete(f.NSNPData, key) +} + +func (f *FakeNetworkProvider) Start(stopCh <-chan struct{}) { + +} + +func (f *FakeNetworkProvider) Set(np *v1.NetworkPolicy) error { + policy, err := f.policyConverter.Convert(np) + if err != nil { + return err + } + + // Add to cache. + k := f.policyConverter.GetKey(policy) + tmp := policy.(api.NetworkPolicy) + f.NSNPData[k] = &tmp + + return nil +} + +func (f *FakeNetworkProvider) GetKey(name, nsname string) string { + policyName := fmt.Sprintf(constants.K8sNetworkPolicyNamePrefix + name) + return fmt.Sprintf("%s/%s", nsname, policyName) +} diff --git a/pkg/controller/network/provider/fake_ns_calico.go b/pkg/controller/network/provider/fake_ns_calico.go deleted file mode 100644 index 973343a21d01176c7b98eb8d5d0de825d45dffc2..0000000000000000000000000000000000000000 --- a/pkg/controller/network/provider/fake_ns_calico.go +++ /dev/null @@ -1,66 +0,0 @@ -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 -} diff --git a/pkg/controller/network/provider/global_np.go b/pkg/controller/network/provider/global_np.go deleted file mode 100644 index 4f504f66886538b8beafd51a4c16dacd561fa215..0000000000000000000000000000000000000000 --- a/pkg/controller/network/provider/global_np.go +++ /dev/null @@ -1 +0,0 @@ -package provider diff --git a/pkg/controller/network/provider/namespace_np.go b/pkg/controller/network/provider/namespace_np.go index 5d63e4a1a95c60c589ee0baaafe2fe68faa3b680..bfb2fb433810a9da656aac7f3f882dfba2a12329 100644 --- a/pkg/controller/network/provider/namespace_np.go +++ b/pkg/controller/network/provider/namespace_np.go @@ -1,35 +1,11 @@ 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" -) +import netv1 "k8s.io/api/networking/v1" // 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 + Delete(key string) + Set(policy *netv1.NetworkPolicy) error + Start(stopCh <-chan struct{}) + GetKey(name, nsname string) string } diff --git a/pkg/controller/network/provider/ns_calico.go b/pkg/controller/network/provider/ns_calico.go deleted file mode 100644 index fa7a24bbae8fafbdbfd7808e107b6a8c85a3d0b1..0000000000000000000000000000000000000000 --- a/pkg/controller/network/provider/ns_calico.go +++ /dev/null @@ -1,144 +0,0 @@ -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 -} diff --git a/pkg/controller/network/provider/ns_k8s.go b/pkg/controller/network/provider/ns_k8s.go new file mode 100644 index 0000000000000000000000000000000000000000..503ac9a8a15a398830dfc2079a3ce553e364e2ea --- /dev/null +++ b/pkg/controller/network/provider/ns_k8s.go @@ -0,0 +1,250 @@ +package provider + +import ( + "context" + "fmt" + "reflect" + "strings" + "sync" + "time" + + rcache "github.com/projectcalico/kube-controllers/pkg/cache" + netv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + uruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + informerv1 "k8s.io/client-go/informers/networking/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + "k8s.io/klog" +) + +const ( + defaultSyncTime = 5 * time.Minute +) + +func (c *k8sPolicyController) GetKey(name, nsname string) string { + return fmt.Sprintf("%s/%s", nsname, name) +} + +func getkey(key string) (string, string) { + strs := strings.Split(key, "/") + return strs[0], strs[1] +} + +// policyController implements the Controller interface for managing Kubernetes network policies +// and syncing them to the k8s datastore as NetworkPolicies. +type k8sPolicyController struct { + client kubernetes.Interface + informer informerv1.NetworkPolicyInformer + ctx context.Context + resourceCache rcache.ResourceCache + hasSynced cache.InformerSynced +} + +func (c *k8sPolicyController) Start(stopCh <-chan struct{}) { + c.run(5, "5m", stopCh) +} + +func (c *k8sPolicyController) Set(np *netv1.NetworkPolicy) error { + klog.V(4).Infof("Set NetworkPolicy %s/%s %+v", np.Namespace, np.Name, np) + // Add to cache. + k := c.GetKey(np.Name, np.Namespace) + c.resourceCache.Set(k, *np) + + return nil +} + +func (c *k8sPolicyController) Delete(key string) { + klog.V(4).Infof("Delete NetworkPolicy %s", key) + c.resourceCache.Delete(key) +} + +// Run starts the controller. +func (c *k8sPolicyController) run(threadiness int, reconcilerPeriod string, stopCh <-chan struct{}) { + defer uruntime.HandleCrash() + + // Let the workers stop when we are done + workqueue := c.resourceCache.GetQueue() + defer workqueue.ShutDown() + + // Wait until we are in sync with the Kubernetes API before starting the + // resource cache. + klog.Info("Waiting to sync with Kubernetes API (NetworkPolicy)") + if ok := cache.WaitForCacheSync(stopCh, c.hasSynced); !ok { + } + klog.Infof("Finished syncing with Kubernetes API (NetworkPolicy)") + + // Start the resource cache - this will trigger the queueing of any keys + // that are out of sync onto the resource cache event queue. + c.resourceCache.Run(reconcilerPeriod) + + // Start a number of worker threads to read from the queue. Each worker + // will pull keys off the resource cache event queue and sync them to the + // k8s datastore. + for i := 0; i < threadiness; i++ { + go wait.Until(c.runWorker, time.Second, stopCh) + } + klog.Info("NetworkPolicy controller is now running") + + <-stopCh + klog.Info("Stopping NetworkPolicy controller") +} + +func (c *k8sPolicyController) runWorker() { + for c.processNextItem() { + } +} + +// processNextItem waits for an event on the output queue from the resource cache and syncs +// any received keys to the datastore. +func (c *k8sPolicyController) processNextItem() bool { + // Wait until there is a new item in the work queue. + workqueue := c.resourceCache.GetQueue() + key, quit := workqueue.Get() + if quit { + return false + } + + // Sync the object to the k8s datastore. + if err := c.syncToDatastore(key.(string)); err != nil { + c.handleErr(err, key.(string)) + } + + // Indicate that we're done processing this key, allowing for safe parallel processing such that + // two objects with the same key are never processed in parallel. + workqueue.Done(key) + return true +} + +// syncToDatastore syncs the given update to the k8s datastore. The provided key can be used to +// find the corresponding resource within the resource cache. If the resource for the provided key +// exists in the cache, then the value should be written to the datastore. If it does not exist +// in the cache, then it should be deleted from the datastore. +func (c *k8sPolicyController) syncToDatastore(key string) error { + // Check if it exists in the controller's cache. + obj, exists := c.resourceCache.Get(key) + if !exists { + // The object no longer exists - delete from the datastore. + klog.Infof("Deleting NetworkPolicy %s from k8s datastore", key) + ns, name := getkey(key) + err := c.client.NetworkingV1().NetworkPolicies(ns).Delete(name, nil) + if errors.IsNotFound(err) { + return nil + } + return err + } else { + // The object exists - update the datastore to reflect. + klog.Infof("Create/Update NetworkPolicy %s in k8s datastore", key) + p := obj.(netv1.NetworkPolicy) + + // Lookup to see if this object already exists in the datastore. + gp, err := c.informer.Lister().NetworkPolicies(p.Namespace).Get(p.Name) + if err != nil { + if !errors.IsNotFound(err) { + klog.Warningf("Failed to get NetworkPolicy %s from datastore", key) + return err + } + + // Doesn't exist - create it. + _, err := c.client.NetworkingV1().NetworkPolicies(p.Namespace).Create(&p) + if err != nil { + klog.Warningf("Failed to create NetworkPolicy %s", key) + return err + } + klog.Infof("Successfully created NetworkPolicy %s", key) + return nil + } + + klog.V(4).Infof("New NetworkPolicy %s/%s %+v\n", p.Namespace, p.Name, p.Spec) + klog.V(4).Infof("Old NetworkPolicy %s/%s %+v\n", gp.Namespace, gp.Name, gp.Spec) + + // The policy already exists, update it and write it back to the datastore. + gp.Spec = p.Spec + _, err = c.client.NetworkingV1().NetworkPolicies(p.Namespace).Update(gp) + if err != nil { + klog.Warningf("Failed to update NetworkPolicy %s", key) + return err + } + klog.Infof("Successfully updated NetworkPolicy %s", key) + return nil + } +} + +// handleErr handles errors which occur while processing a key received from the resource cache. +// For a given error, we will re-queue the key in order to retry the datastore sync up to 5 times, +// at which point the update is dropped. +func (c *k8sPolicyController) handleErr(err error, key string) { + workqueue := c.resourceCache.GetQueue() + if err == nil { + // Forget about the #AddRateLimited history of the key on every successful synchronization. + // This ensures that future processing of updates for this key is not delayed because of + // an outdated error history. + workqueue.Forget(key) + return + } + + // This controller retries 5 times if something goes wrong. After that, it stops trying. + if workqueue.NumRequeues(key) < 5 { + // Re-enqueue the key rate limited. Based on the rate limiter on the + // queue and the re-enqueue history, the key will be processed later again. + klog.Errorf("Error syncing NetworkPolicy %v: %v", key, err) + workqueue.AddRateLimited(key) + return + } + workqueue.Forget(key) + + // Report to an external entity that, even after several retries, we could not successfully process this key + uruntime.HandleError(err) + klog.Errorf("Dropping NetworkPolicy %q out of the queue: %v", key, err) +} + +//NewNsNetworkPolicyProvider sync k8s NetworkPolicy +func NewNsNetworkPolicyProvider(client kubernetes.Interface, npInformer informerv1.NetworkPolicyInformer) (NsNetworkPolicyProvider, error) { + var once sync.Once + + c := &k8sPolicyController{ + client: client, + informer: npInformer, + ctx: context.Background(), + hasSynced: npInformer.Informer().HasSynced, + } + + // Function returns map of policyName:policy stored by policy controller + // in datastore. + listFunc := func() (map[string]interface{}, error) { + //Wait cache be set by NSNP Controller, otherwise NetworkPolicy will be delete + //by mistake + once.Do(func() { + time.Sleep(defaultSyncTime) + }) + + // Get all policies from datastore + //TODO filter np not belong to kubesphere + policies, err := npInformer.Lister().List(labels.Everything()) + if err != nil { + return nil, err + } + + // Filter in only objects that are written by policy controller. + m := make(map[string]interface{}) + for _, policy := range policies { + policy.ObjectMeta = metav1.ObjectMeta{Name: policy.Name, Namespace: policy.Namespace} + k := c.GetKey(policy.Name, policy.Namespace) + m[k] = *policy + } + + klog.Infof("Found %d policies in k8s datastore:", len(m)) + return m, nil + } + + cacheArgs := rcache.ResourceCacheArgs{ + ListFunc: listFunc, + ObjectType: reflect.TypeOf(netv1.NetworkPolicy{}), + } + c.resourceCache = rcache.NewResourceCache(cacheArgs) + + return c, nil +} diff --git a/pkg/controller/network/runoption/option.go b/pkg/controller/network/runoption/option.go deleted file mode 100644 index a4c2ec23a66edefb14bbef49a487bde7df0acae1..0000000000000000000000000000000000000000 --- a/pkg/controller/network/runoption/option.go +++ /dev/null @@ -1,80 +0,0 @@ -package runoption - -import ( - "time" - - "github.com/projectcalico/libcalico-go/lib/apiconfig" - "github.com/projectcalico/libcalico-go/lib/clientv3" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "k8s.io/klog" - "kubesphere.io/kubesphere/pkg/client/clientset/versioned" - ksinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions" - "kubesphere.io/kubesphere/pkg/controller/network/nsnetworkpolicy" - "kubesphere.io/kubesphere/pkg/controller/network/provider" -) - -const ( - certPath = "/calicocerts" - - KubernetesDataStore = "k8s" - EtcdDataStore = "etcd" -) - -type RunOption struct { - ProviderName string - DataStoreType string - EtcdEndpoints string - AllowInsecureEtcd bool -} - -func (r RunOption) Run() error { - klog.V(1).Info("Check config") - if err := r.check(); err != nil { - return err - } - klog.V(1).Info("Preparing kubernetes client") - config, err := rest.InClusterConfig() - if err != nil { - panic(err.Error()) - } - // creates the clientset - k8sClientset := kubernetes.NewForConfigOrDie(config) - ksClientset := versioned.NewForConfigOrDie(config) - informer := ksinformer.NewSharedInformerFactory(ksClientset, time.Minute*10) - klog.V(1).Info("Kubernetes client initialized successfully") - var npProvider provider.NsNetworkPolicyProvider - - if r.ProviderName == "calico" { - klog.V(1).Info("Preparing calico client") - config := apiconfig.NewCalicoAPIConfig() - config.Spec.EtcdEndpoints = r.EtcdEndpoints - if !r.AllowInsecureEtcd { - config.Spec.EtcdKeyFile = certPath + "/etcd-key" - config.Spec.EtcdCertFile = certPath + "/etcd-cert" - config.Spec.EtcdCACertFile = certPath + "/etcd-ca" - } - if r.DataStoreType == KubernetesDataStore { - config.Spec.DatastoreType = apiconfig.Kubernetes - } else { - config.Spec.DatastoreType = apiconfig.EtcdV3 - } - client, err := clientv3.New(*config) - if err != nil { - klog.Fatal("Failed to initialize calico client", err) - } - npProvider = provider.NewCalicoNetworkProvider(client.NetworkPolicies()) - klog.V(1).Info("Calico client initialized successfully") - } - - //TODO: support no-calico cni - c := nsnetworkpolicy.NewController(k8sClientset, ksClientset, informer.Network().V1alpha1().NamespaceNetworkPolicies(), npProvider) - stop := make(chan struct{}) - klog.V(1).Infof("Starting controller") - go informer.Network().V1alpha1().NamespaceNetworkPolicies().Informer().Run(stop) - return c.Run(1, stop) -} - -func (r RunOption) check() error { - return nil -} diff --git a/pkg/controller/network/testing/controller.go b/pkg/controller/network/testing/controller.go deleted file mode 100644 index c958d5dc2f315c78d6ec36c8f3f2abb88910c5e1..0000000000000000000000000000000000000000 --- a/pkg/controller/network/testing/controller.go +++ /dev/null @@ -1,38 +0,0 @@ -package testing - -import ( - "time" - - "k8s.io/apimachinery/pkg/runtime" - kubeinformers "k8s.io/client-go/informers" - k8sfake "k8s.io/client-go/kubernetes/fake" - "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake" - informers "kubesphere.io/kubesphere/pkg/client/informers/externalversions" -) - -var ( - AlwaysReady = func() bool { return true } - ResyncPeriodFunc = func() time.Duration { return 1 * time.Second } -) - -type FakeControllerBuilder struct { - KsClient *fake.Clientset - KubeClient *k8sfake.Clientset - Kubeobjects []runtime.Object - CRDObjects []runtime.Object -} - -func NewFakeControllerBuilder() *FakeControllerBuilder { - return &FakeControllerBuilder{ - Kubeobjects: make([]runtime.Object, 0), - CRDObjects: make([]runtime.Object, 0), - } -} - -func (f *FakeControllerBuilder) NewControllerInformer() (informers.SharedInformerFactory, kubeinformers.SharedInformerFactory) { - f.KsClient = fake.NewSimpleClientset(f.CRDObjects...) - f.KubeClient = k8sfake.NewSimpleClientset(f.Kubeobjects...) - i := informers.NewSharedInformerFactory(f.KsClient, ResyncPeriodFunc()) - k8sI := kubeinformers.NewSharedInformerFactory(f.KubeClient, ResyncPeriodFunc()) - return i, k8sI -} diff --git a/pkg/controller/network/testing/util.go b/pkg/controller/network/testing/util.go deleted file mode 100644 index a92efd1cd56f110cf93ad675bffb8e2b579c6307..0000000000000000000000000000000000000000 --- a/pkg/controller/network/testing/util.go +++ /dev/null @@ -1,12 +0,0 @@ -package testing - -import ( - "strings" - - "k8s.io/apimachinery/pkg/util/yaml" -) - -func StringToObject(data string, obj interface{}) error { - reader := strings.NewReader(data) - return yaml.NewYAMLOrJSONDecoder(reader, 10).Decode(obj) -} diff --git a/pkg/controller/network/utils/strings.go b/pkg/controller/network/utils/strings.go deleted file mode 100644 index 86ffcf54255f7bf88d86a59b8056232d00bb4a5c..0000000000000000000000000000000000000000 --- a/pkg/controller/network/utils/strings.go +++ /dev/null @@ -1,22 +0,0 @@ -package utils - -// ContainsString report if s is in a slice -func ContainsString(slice []string, s string) bool { - for _, item := range slice { - if item == s { - return true - } - } - return false -} - -// RemoveString remove s from slice if exists -func RemoveString(slice []string, s string) (result []string) { - for _, item := range slice { - if item == s { - continue - } - result = append(result, item) - } - return -} diff --git a/pkg/controller/network/wsnetworkpolicy/controller.go b/pkg/controller/network/wsnetworkpolicy/controller.go deleted file mode 100644 index 21fd6e3c9c8f913648bf169a6470678d5c610ab3..0000000000000000000000000000000000000000 --- a/pkg/controller/network/wsnetworkpolicy/controller.go +++ /dev/null @@ -1,280 +0,0 @@ -package wsnetworkpolicy - -import ( - "fmt" - "time" - - corev1 "k8s.io/api/core/v1" - k8snetwork "k8s.io/api/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/wait" - corev1informer "k8s.io/client-go/informers/core/v1" - k8snetworkinformer "k8s.io/client-go/informers/networking/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" - typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" - corev1lister "k8s.io/client-go/listers/core/v1" - k8snetworklister "k8s.io/client-go/listers/networking/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/tools/record" - "k8s.io/client-go/util/workqueue" - "k8s.io/klog" - "k8s.io/klog/klogr" - workspaceapi "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" - kubesphereclient "kubesphere.io/kubesphere/pkg/client/clientset/versioned" - kubespherescheme "kubesphere.io/kubesphere/pkg/client/clientset/versioned/scheme" - networkinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/network/v1alpha1" - workspaceinformer "kubesphere.io/kubesphere/pkg/client/informers/externalversions/tenant/v1alpha1" - networklister "kubesphere.io/kubesphere/pkg/client/listers/network/v1alpha1" - workspacelister "kubesphere.io/kubesphere/pkg/client/listers/tenant/v1alpha1" - "kubesphere.io/kubesphere/pkg/controller/network/controllerapi" -) - -const controllerAgentName = "wsnp-controller" - -var ( - log = klogr.New().WithName("Controller").WithValues(controllerAgentName) - errCount = 0 -) - -type controller struct { - kubeClientset kubernetes.Interface - kubesphereClientset kubesphereclient.Interface - - wsnpInformer networkinformer.WorkspaceNetworkPolicyInformer - wsnpLister networklister.WorkspaceNetworkPolicyLister - wsnpSynced cache.InformerSynced - - networkPolicyInformer k8snetworkinformer.NetworkPolicyInformer - networkPolicyLister k8snetworklister.NetworkPolicyLister - networkPolicySynced cache.InformerSynced - - namespaceLister corev1lister.NamespaceLister - namespaceInformer corev1informer.NamespaceInformer - namespaceSynced cache.InformerSynced - - workspaceLister workspacelister.WorkspaceLister - workspaceInformer workspaceinformer.WorkspaceInformer - workspaceSynced cache.InformerSynced - // workqueue is a rate limited work queue. This is used to queue work to be - // processed instead of performing it as soon as a change happens. This - // means we can ensure we only process a fixed amount of resources at a - // time, and makes it easy to ensure we are never processing the same item - // simultaneously in two different workers. - workqueue workqueue.RateLimitingInterface - // recorder is an event recorder for recording Event resources to the - // Kubernetes API. - recorder record.EventRecorder -} - -func NewController(kubeclientset kubernetes.Interface, - kubesphereclientset kubesphereclient.Interface, - wsnpInformer networkinformer.WorkspaceNetworkPolicyInformer, - networkPolicyInformer k8snetworkinformer.NetworkPolicyInformer, - namespaceInformer corev1informer.NamespaceInformer, - workspaceInformer workspaceinformer.WorkspaceInformer) controllerapi.Controller { - utilruntime.Must(kubespherescheme.AddToScheme(scheme.Scheme)) - log.V(4).Info("Creating event broadcaster") - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartLogging(klog.Infof) - eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")}) - recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName}) - ctl := &controller{ - kubeClientset: kubeclientset, - kubesphereClientset: kubesphereclientset, - wsnpInformer: wsnpInformer, - wsnpLister: wsnpInformer.Lister(), - wsnpSynced: wsnpInformer.Informer().HasSynced, - networkPolicyInformer: networkPolicyInformer, - networkPolicyLister: networkPolicyInformer.Lister(), - networkPolicySynced: networkPolicyInformer.Informer().HasSynced, - namespaceInformer: namespaceInformer, - namespaceLister: namespaceInformer.Lister(), - namespaceSynced: namespaceInformer.Informer().HasSynced, - workspaceInformer: workspaceInformer, - workspaceLister: workspaceInformer.Lister(), - workspaceSynced: workspaceInformer.Informer().HasSynced, - - workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "WorkspaceNetworkPolicies"), - recorder: recorder, - } - log.Info("Setting up event handlers") - wsnpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: ctl.enqueueWSNP, - UpdateFunc: func(old, new interface{}) { - ctl.enqueueWSNP(new) - }, - }) - networkPolicyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: ctl.handleNP, - UpdateFunc: func(old, new interface{}) { - newNP := new.(*k8snetwork.NetworkPolicy) - oldNP := old.(*k8snetwork.NetworkPolicy) - if newNP.ResourceVersion == oldNP.ResourceVersion { - return - } - ctl.handleNP(new) - }, - DeleteFunc: ctl.handleNP, - }) - workspaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: ctl.handleWS, - UpdateFunc: func(old, new interface{}) { - newNP := new.(*workspaceapi.Workspace) - oldNP := old.(*workspaceapi.Workspace) - if newNP.ResourceVersion == oldNP.ResourceVersion { - return - } - ctl.handleWS(new) - }, - DeleteFunc: ctl.handleNP, - }) - return ctl -} - -func (c *controller) handleWS(obj interface{}) { - ws := obj.(*workspaceapi.Workspace) - wsnps, err := c.wsnpLister.List(labels.Everything()) - if err != nil { - log.Error(err, "Failed to get WSNP when a workspace changed ") - return - } - for _, wsnp := range wsnps { - log.V(4).Info("Enqueue wsnp because a workspace being changed", "obj", ws.Name) - c.enqueueWSNP(wsnp) - } - return -} - -func (c *controller) Run(threadiness int, stopCh <-chan struct{}) error { - defer utilruntime.HandleCrash() - defer c.workqueue.ShutDown() - - // Start the informer factories to begin populating the informer caches - log.Info("Starting WSNP controller") - - // Wait for the caches to be synced before starting workers - log.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, c.wsnpSynced, c.namespaceSynced, c.networkPolicySynced, c.workspaceSynced); !ok { - return fmt.Errorf("failed to wait for caches to sync") - } - - log.Info("Starting workers") - // Launch two workers to process Foo resources - for i := 0; i < threadiness; i++ { - go wait.Until(c.runWorker, time.Second, stopCh) - } - - klog.Info("Started workers") - <-stopCh - log.Info("Shutting down workers") - - return nil -} - -func (c *controller) enqueueWSNP(obj interface{}) { - var key string - var err error - if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { - utilruntime.HandleError(err) - return - } - c.workqueue.Add(key) -} - -func (c *controller) handleNP(obj interface{}) { - var object metav1.Object - var ok bool - if object, ok = obj.(metav1.Object); !ok { - tombstone, ok := obj.(cache.DeletedFinalStateUnknown) - if !ok { - utilruntime.HandleError(fmt.Errorf("error decoding object, invalid type")) - return - } - object, ok = tombstone.Obj.(metav1.Object) - if !ok { - utilruntime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type")) - return - } - log.V(4).Info("Recovered deleted object from tombstone", "name", object.GetName()) - } - log.V(4).Info("Processing object:", "name", object.GetName()) - if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { - if ownerRef.Kind != "WorkspaceNetworkPol" { - return - } - - wsnp, err := c.wsnpLister.Get(ownerRef.Name) - if err != nil { - log.V(4).Info("ignoring orphaned object", "link", object.GetSelfLink(), "name", ownerRef.Name) - return - } - c.enqueueWSNP(wsnp) - return - } -} - -func (c *controller) runWorker() { - for c.processNextWorkItem() { - } -} - -func (c *controller) processNextWorkItem() bool { - obj, shutdown := c.workqueue.Get() - - if shutdown { - return false - } - - // We wrap this block in a func so we can defer c.workqueue.Done. - err := func(obj interface{}) error { - // We call Done here so the workqueue knows we have finished - // processing this item. We also must remember to call Forget if we - // do not want this work item being re-queued. For example, we do - // not call Forget if a transient error occurs, instead the item is - // put back on the workqueue and attempted again after a back-off - // period. - defer c.workqueue.Done(obj) - var key string - var ok bool - // We expect strings to come off the workqueue. These are of the - // form namespace/name. We do this as the delayed nature of the - // workqueue means the items in the informer cache may actually be - // more up to date that when the item was initially put onto the - // workqueue. - if key, ok = obj.(string); !ok { - // As the item in the workqueue is actually invalid, we call - // Forget here else we'd go into a loop of attempting to - // process a work item that is invalid. - c.workqueue.Forget(obj) - utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) - return nil - } - // Run the reconcile, passing it the namespace/name string of the - // Foo resource to be synced. - if err := c.reconcile(key); err != nil { - // Put the item back on the workqueue to handle any transient errors. - c.workqueue.AddRateLimited(key) - return fmt.Errorf("error syncing '%s': %s, requeuing", key, err.Error()) - } - // Finally, if no error occurs we Forget this item so it does not - // get queued again until another change happens. - c.workqueue.Forget(obj) - log.Info("Successfully synced", key) - return nil - }(obj) - - if err != nil { - utilruntime.HandleError(err) - return true - } - - return true -} - -func (c *controller) handleError(err error) { - log.Error(err, "Error in handling") - errCount++ -} diff --git a/pkg/controller/network/wsnetworkpolicy/reconcile.go b/pkg/controller/network/wsnetworkpolicy/reconcile.go deleted file mode 100644 index f6bad5366350b848422d15d5bdbc69ddb24986d5..0000000000000000000000000000000000000000 --- a/pkg/controller/network/wsnetworkpolicy/reconcile.go +++ /dev/null @@ -1,203 +0,0 @@ -package wsnetworkpolicy - -import ( - "fmt" - "reflect" - "sort" - - corev1 "k8s.io/api/core/v1" - ks8network "k8s.io/api/networking/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - errutil "k8s.io/apimachinery/pkg/util/errors" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - wsnpapi "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" -) - -const ( - workspaceSelectorLabel = "kubesphere.io/workspace" - workspaceNetworkPolicyLabel = "networking.kubesphere.io/wsnp" - - MessageResourceExists = "Resource %q already exists and is not managed by WorkspaceNetworkPolicy" - ErrResourceExists = "ErrResourceExists" -) - -var everything = labels.Everything() -var reconcileCount = 0 - -// NetworkPolicyNameForWSNP return the name of the networkpolicy owned by this WNSP -func NetworkPolicyNameForWSNP(wsnp string) string { - return wsnp + "-np" -} - -func (c *controller) reconcile(key string) error { - reconcileCount++ - _, name, err := cache.SplitMetaNamespaceKey(key) - if err != nil { - utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key)) - return nil - } - olog := log.WithName(name) - olog.Info("Begin to reconcile") - owner, err := c.wsnpLister.Get(name) - if err != nil { - if errors.IsNotFound(err) { - utilruntime.HandleError(fmt.Errorf("WSNP '%s' in work queue no longer exists", key)) - return nil - } - return err - } - namespaces, err := c.listNamespacesInWorkspace(owner.Spec.Workspace) - if err != nil { - return err - } - var errs []error - for _, ns := range namespaces { - err = c.reconcileNamespace(ns.Name, owner) - if err != nil { - errs = append(errs, err) - } - } - if len(errs) == 0 { - return nil - } - return errutil.NewAggregate(errs) -} - -func (c *controller) reconcileNamespace(name string, wsnp *wsnpapi.WorkspaceNetworkPolicy) error { - npname := NetworkPolicyNameForWSNP(wsnp.Name) - np, err := c.generateNPForNamesapce(name, wsnp) - if err != nil { - log.Error(nil, "Failed to generate NetworkPolicy", "wsnp", wsnp, "namespace", name) - return err - } - old, err := c.networkPolicyLister.NetworkPolicies(name).Get(npname) - if errors.IsNotFound(err) { - _, err = c.kubeClientset.NetworkingV1().NetworkPolicies(name).Create(np) - if err != nil { - log.Error(err, "cannot create networkpolicy of this wsnp", wsnp) - return err - } - return nil - } - if err != nil { - log.Error(err, "Failed to get networkPolicy") - return err - } - if !metav1.IsControlledBy(old, wsnp) { - msg := fmt.Sprintf(MessageResourceExists, old.Name) - c.recorder.Event(wsnp, corev1.EventTypeWarning, ErrResourceExists, msg) - return fmt.Errorf(msg) - } - if !reflect.DeepEqual(old.Spec, np.Spec) { - log.V(2).Info("Detect network policy changed, updating network policy", "the old one", old.Spec, "the new one", np.Spec) - err = retry.RetryOnConflict(retry.DefaultBackoff, func() error { - _, err = c.kubeClientset.NetworkingV1().NetworkPolicies(name).Update(np) - return err - }) - if err != nil { - log.Error(err, "Failed to update wsnp") - return err - } - log.V(2).Info("updating completed") - } - return nil -} - -func (c *controller) generateNPForNamesapce(ns string, wsnp *wsnpapi.WorkspaceNetworkPolicy) (*ks8network.NetworkPolicy, error) { - np := &ks8network.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: NetworkPolicyNameForWSNP(wsnp.Name), - Namespace: ns, - Labels: map[string]string{workspaceNetworkPolicyLabel: wsnp.Name}, - OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(wsnp, wsnpapi.SchemeGroupVersion.WithKind("WorkspaceNetworkPolicy")), - }, - }, - Spec: ks8network.NetworkPolicySpec{ - PolicyTypes: wsnp.Spec.PolicyTypes, - }, - } - - if wsnp.Spec.Ingress != nil { - np.Spec.Ingress = make([]ks8network.NetworkPolicyIngressRule, len(wsnp.Spec.Ingress)) - for index, ing := range wsnp.Spec.Ingress { - ingRule, err := c.transformWSNPIngressToK8sIngress(ing) - if err != nil { - return nil, err - } - np.Spec.Ingress[index] = *ingRule - } - } - return np, nil -} - -func (c *controller) transformWSNPIngressToK8sIngress(rule wsnpapi.WorkspaceNetworkPolicyIngressRule) (*ks8network.NetworkPolicyIngressRule, error) { - k8srule := &ks8network.NetworkPolicyIngressRule{ - Ports: rule.Ports, - From: make([]ks8network.NetworkPolicyPeer, len(rule.From)), - } - for index, f := range rule.From { - k8srule.From[index] = f.NetworkPolicyPeer - if f.WorkspaceSelector != nil { - if f.WorkspaceSelector.Size() == 0 { - k8srule.From[index].NamespaceSelector = &metav1.LabelSelector{} - } else { - selector, err := metav1.LabelSelectorAsSelector(f.WorkspaceSelector) - if err != nil { - log.Error(err, "Failed to convert label selectors") - return nil, err - } - ws, err := c.workspaceLister.List(selector) - if err != nil { - log.Error(err, "Failed to list workspaces") - return nil, err - } - if len(ws) == 0 { - log.Info("ws selector doesnot match anything") - continue - } - if k8srule.From[index].NamespaceSelector == nil { - k8srule.From[index].NamespaceSelector = &metav1.LabelSelector{} - } - if len(ws) == 1 { - if k8srule.From[index].NamespaceSelector.MatchLabels == nil { - k8srule.From[index].NamespaceSelector.MatchLabels = make(map[string]string) - } - k8srule.From[index].NamespaceSelector.MatchLabels[workspaceSelectorLabel] = ws[0].Name - } else { - if k8srule.From[index].NamespaceSelector.MatchExpressions == nil { - k8srule.From[index].NamespaceSelector.MatchExpressions = make([]metav1.LabelSelectorRequirement, 0) - } - re := metav1.LabelSelectorRequirement{ - Key: workspaceSelectorLabel, - Operator: metav1.LabelSelectorOpIn, - Values: make([]string, len(ws)), - } - for index, w := range ws { - re.Values[index] = w.Name - } - sort.Strings(re.Values) - k8srule.From[index].NamespaceSelector.MatchExpressions = append(k8srule.From[index].NamespaceSelector.MatchExpressions, re) - } - } - } - } - return k8srule, nil -} -func (c *controller) listNamespacesInWorkspace(workspace string) ([]*corev1.Namespace, error) { - selector, err := labels.Parse(workspaceSelectorLabel + "==" + workspace) - if err != nil { - log.Error(err, "Failed to parse label selector") - return nil, err - } - namespaces, err := c.namespaceLister.List(selector) - if err != nil { - log.Error(err, "Failed to list namespaces in this workspace") - return nil, err - } - return namespaces, nil -} diff --git a/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_suite_test.go b/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_suite_test.go deleted file mode 100644 index c6c00707547e60f84231571cad6963b3b115b2a8..0000000000000000000000000000000000000000 --- a/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_suite_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package wsnetworkpolicy - -import ( - "flag" - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "k8s.io/klog" -) - -func TestWsnetworkpolicy(t *testing.T) { - klog.InitFlags(nil) - flag.Set("logtostderr", "false") - flag.Set("alsologtostderr", "false") - flag.Set("v", "4") - flag.Parse() - klog.SetOutput(GinkgoWriter) - RegisterFailHandler(Fail) - RunSpecs(t, "Wsnetworkpolicy Suite") -} diff --git a/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_test.go b/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_test.go deleted file mode 100644 index 189d30906aac839b3ccf2cd3da764ce741d79f5e..0000000000000000000000000000000000000000 --- a/pkg/controller/network/wsnetworkpolicy/wsnetworkpolicy_test.go +++ /dev/null @@ -1,242 +0,0 @@ -package wsnetworkpolicy - -import ( - "fmt" - "time" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" - corev1 "k8s.io/api/core/v1" - k8snetwork "k8s.io/api/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - netv1lister "k8s.io/client-go/listers/networking/v1" - "k8s.io/client-go/tools/record" - "k8s.io/klog" - "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" - tenant "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1" - "kubesphere.io/kubesphere/pkg/controller/network/controllerapi" - controllertesting "kubesphere.io/kubesphere/pkg/controller/network/testing" -) - -var ( - fakeControllerBuilder *controllertesting.FakeControllerBuilder - c controllerapi.Controller - npLister netv1lister.NetworkPolicyLister - stopCh chan struct{} - deletePolicy metav1.DeletionPropagation - testName string -) - -var _ = Describe("Wsnetworkpolicy", func() { - BeforeEach(func() { - deletePolicy = metav1.DeletePropagationBackground - fakeControllerBuilder = controllertesting.NewFakeControllerBuilder() - informer, k8sinformer := fakeControllerBuilder.NewControllerInformer() - stopCh = make(chan struct{}) - c = NewController(fakeControllerBuilder.KubeClient, fakeControllerBuilder.KsClient, - informer.Network().V1alpha1().WorkspaceNetworkPolicies(), k8sinformer.Networking().V1().NetworkPolicies(), - k8sinformer.Core().V1().Namespaces(), informer.Tenant().V1alpha1().Workspaces()) - originalController := c.(*controller) - go originalController.wsnpInformer.Informer().Run(stopCh) - go originalController.networkPolicyInformer.Informer().Run(stopCh) - go originalController.namespaceInformer.Informer().Run(stopCh) - go originalController.workspaceInformer.Informer().Run(stopCh) - originalController.recorder = &record.FakeRecorder{} - go c.Run(1, stopCh) - npLister = k8sinformer.Networking().V1().NetworkPolicies().Lister() - testName = "test" - ns1 := newWorkspaceNamespaces("ns1", testName) - ns2 := newWorkspaceNamespaces("ns2", testName) - _, err := fakeControllerBuilder.KubeClient.CoreV1().Namespaces().Create(ns1) - Expect(err).ShouldNot(HaveOccurred()) - _, err = fakeControllerBuilder.KubeClient.CoreV1().Namespaces().Create(ns2) - Expect(err).ShouldNot(HaveOccurred()) - }) - - AfterEach(func() { - close(stopCh) - }) - - It("Should proper ingress rule when using workspaceSelector", func() { - label := map[string]string{"workspace": "test-selector"} - ws := &tenant.Workspace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Labels: label, - }, - } - _, err := fakeControllerBuilder.KsClient.TenantV1alpha1().Workspaces().Create(ws) - wsnp := newWorkspaceNP(testName) - wsnp.Spec.PolicyTypes = []k8snetwork.PolicyType{k8snetwork.PolicyTypeIngress} - wsnp.Spec.Ingress = []v1alpha1.WorkspaceNetworkPolicyIngressRule{ - { - From: []v1alpha1.WorkspaceNetworkPolicyPeer{ - { - WorkspaceSelector: &metav1.LabelSelector{ - MatchLabels: label, - }, - }, - }, - }} - _, err = fakeControllerBuilder.KsClient.NetworkV1alpha1().WorkspaceNetworkPolicies().Create(wsnp) - Expect(err).ShouldNot(HaveOccurred()) - expect1Json := `{ - "apiVersion": "networking.k8s.io/v1", - "kind": "NetworkPolicy", - "metadata": { - "name": "test-np", - "namespace": "ns1", - "labels": { - "networking.kubesphere.io/wsnp": "test" - } - }, - "spec": { - "policyTypes": [ - "Ingress" - ], - "ingress": [ - { - "from": [ - { - "namespaceSelector": { - "matchLabels": { - "kubesphere.io/workspace": "test" - } - } - } - ] - } - ] - } - }` - expect1 := &k8snetwork.NetworkPolicy{} - Expect(controllertesting.StringToObject(expect1Json, expect1)).ShouldNot(HaveOccurred()) - nps := []*k8snetwork.NetworkPolicy{} - Eventually(func() error { - selector, _ := labels.Parse(workspaceNetworkPolicyLabel + "==test") - nps, err = npLister.List(selector) - if err != nil { - klog.Errorf("Failed to list npmerr:%s", err.Error()) - return err - } - if len(nps) != 2 { - return fmt.Errorf("Length is not right, current length :%d", len(nps)) - } - return nil - }, time.Second*5, time.Second).ShouldNot(HaveOccurred()) - - for _, np := range nps { - Expect(np.Labels).To(Equal(expect1.Labels)) - Expect(np.Spec).To(Equal(expect1.Spec)) - } - // create a new ws will change the `From` - ws2 := &tenant.Workspace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test2", - Labels: label, - }, - } - _, err = fakeControllerBuilder.KsClient.TenantV1alpha1().Workspaces().Create(ws2) - Expect(err).ShouldNot(HaveOccurred()) - expect2Json := `{ - "apiVersion": "networking.k8s.io/v1", - "kind": "NetworkPolicy", - "metadata": { - "name": "test-np", - "namespace": "ns1", - "labels": { - "networking.kubesphere.io/wsnp": "test" - } - }, - "spec": { - "policyTypes": [ - "Ingress" - ], - "ingress": [ - { - "from": [ - { - "namespaceSelector": { - "matchExpressions": [{ - "key": "kubesphere.io/workspace", - "operator":"In", - "values": ["test", "test2"] - }] - } - } - ] - } - ] - } - }` - expect2 := &k8snetwork.NetworkPolicy{} - Expect(controllertesting.StringToObject(expect2Json, expect2)).ShouldNot(HaveOccurred()) - - id := func(element interface{}) string { - e := element.(*k8snetwork.NetworkPolicy) - return e.Namespace - } - Eventually(func() []*k8snetwork.NetworkPolicy { - selector, _ := labels.Parse(workspaceNetworkPolicyLabel + "=test") - nps, err := npLister.List(selector) - if err != nil { - return nil - } - if len(nps) != 2 { - klog.Errorf("Length is not right, current length :%d", len(nps)) - return nil - } - return nps - }, time.Second*5, time.Second).Should(MatchAllElements(id, Elements{ - "ns1": PointTo(MatchFields(IgnoreExtras, Fields{ - "Spec": Equal(expect2.Spec), - })), - "ns2": PointTo(MatchFields(IgnoreExtras, Fields{ - "Spec": Equal(expect2.Spec), - })), - })) - }) - - It("Should create networkpolicies", func() { - //create a wsnp - _, err := fakeControllerBuilder.KsClient.NetworkV1alpha1().WorkspaceNetworkPolicies().Create(newWorkspaceNP(testName)) - Expect(err).ShouldNot(HaveOccurred()) - Eventually(func() error { - selector, _ := labels.Parse(workspaceNetworkPolicyLabel + "=" + testName) - nps, err := npLister.List(selector) - if err != nil { - return err - } - if len(nps) != 2 { - return fmt.Errorf("Length is not right, current length :%d", len(nps)) - } - return nil - }, time.Second*5, time.Second).ShouldNot(HaveOccurred()) - err = fakeControllerBuilder.KsClient.NetworkV1alpha1().WorkspaceNetworkPolicies().Delete(testName, &metav1.DeleteOptions{ - PropagationPolicy: &deletePolicy, - }) - Expect(err).ShouldNot(HaveOccurred()) - }) -}) - -func newWorkspaceNP(name string) *v1alpha1.WorkspaceNetworkPolicy { - return &v1alpha1.WorkspaceNetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1alpha1.WorkspaceNetworkPolicySpec{ - Workspace: name, - }, - } -} - -func newWorkspaceNamespaces(ns, ws string) *corev1.Namespace { - return &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: ns, - Labels: map[string]string{workspaceSelectorLabel: ws}, - }, - } -} diff --git a/tools/cmd/crd-doc-gen/main.go b/tools/cmd/crd-doc-gen/main.go index d069e84ec07374f5d131bea927eacecc4918639d..e1acbbc1a9e74fd06723883eeb69ca5735a2ab6b 100644 --- a/tools/cmd/crd-doc-gen/main.go +++ b/tools/cmd/crd-doc-gen/main.go @@ -18,7 +18,6 @@ import ( "k8s.io/kube-openapi/pkg/common" devopsinstall "kubesphere.io/kubesphere/pkg/apis/devops/crdinstall" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" - devopsv1alpha3 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha3" networkinstall "kubesphere.io/kubesphere/pkg/apis/network/crdinstall" networkv1alpha1 "kubesphere.io/kubesphere/pkg/apis/network/v1alpha1" servicemeshinstall "kubesphere.io/kubesphere/pkg/apis/servicemesh/crdinstall" @@ -77,9 +76,9 @@ func main() { devopsv1alpha1.SchemeGroupVersion.WithResource(devopsv1alpha1.ResourceSingularS2iBinary), devopsv1alpha1.SchemeGroupVersion.WithResource(devopsv1alpha1.ResourcePluralS2iBinary), meta.RESTScopeRoot) - mapper.AddSpecific(networkv1alpha1.SchemeGroupVersion.WithKind(networkv1alpha1.ResourceKindWorkspaceNetworkPolicy), - networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourcePluralWorkspaceNetworkPolicy), - networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourceSingularWorkspaceNetworkPolicy), meta.RESTScopeRoot) + mapper.AddSpecific(networkv1alpha1.SchemeGroupVersion.WithKind(networkv1alpha1.ResourceKindNamespaceNetworkPolicy), + networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourcePluralNamespaceNetworkPolicy), + networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourceSingularNamespaceNetworkPolicy), meta.RESTScopeRoot) mapper.AddSpecific(devopsv1alpha3.SchemeGroupVersion.WithKind(devopsv1alpha3.ResourceKindDevOpsProject), devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject), devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourceSingularDevOpsProject), meta.RESTScopeRoot) @@ -138,7 +137,7 @@ func main() { devopsv1alpha1.SchemeGroupVersion.WithResource(devopsv1alpha1.ResourcePluralS2iRun), devopsv1alpha1.SchemeGroupVersion.WithResource(devopsv1alpha1.ResourcePluralS2iBuilderTemplate), devopsv1alpha1.SchemeGroupVersion.WithResource(devopsv1alpha1.ResourcePluralS2iBuilder), - networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourcePluralWorkspaceNetworkPolicy), + networkv1alpha1.SchemeGroupVersion.WithResource(networkv1alpha1.ResourcePluralNamespaceNetworkPolicy), devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralDevOpsProject), devopsv1alpha3.SchemeGroupVersion.WithResource(devopsv1alpha3.ResourcePluralPipeline), clusterv1alpha1.SchemeGroupVersion.WithResource(clusterv1alpha1.ResourcesPluralAgent), diff --git a/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS b/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS new file mode 100644 index 0000000000000000000000000000000000000000..2b16e997415f3e2fb451cb140b4e30cf073e7c00 --- /dev/null +++ b/vendor/github.com/patrickmn/go-cache/CONTRIBUTORS @@ -0,0 +1,9 @@ +This is a list of people who have contributed code to go-cache. They, or their +employers, are the copyright holders of the contributed code. Contributed code +is subject to the license restrictions listed in LICENSE (as they were when the +code was contributed.) + +Dustin Sallings +Jason Mooberry +Sergey Shepelev +Alex Edwards diff --git a/vendor/github.com/patrickmn/go-cache/LICENSE b/vendor/github.com/patrickmn/go-cache/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..db9903c75c58ac256dd63c3236801cdbc997c380 --- /dev/null +++ b/vendor/github.com/patrickmn/go-cache/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012-2017 Patrick Mylund Nielsen and the go-cache contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/patrickmn/go-cache/README.md b/vendor/github.com/patrickmn/go-cache/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c5789cc66cc8a7a4beaafb54c81771bf1e014e1e --- /dev/null +++ b/vendor/github.com/patrickmn/go-cache/README.md @@ -0,0 +1,83 @@ +# go-cache + +go-cache is an in-memory key:value store/cache similar to memcached that is +suitable for applications running on a single machine. Its major advantage is +that, being essentially a thread-safe `map[string]interface{}` with expiration +times, it doesn't need to serialize or transmit its contents over the network. + +Any object can be stored, for a given duration or forever, and the cache can be +safely used by multiple goroutines. + +Although go-cache isn't meant to be used as a persistent datastore, the entire +cache can be saved to and loaded from a file (using `c.Items()` to retrieve the +items map to serialize, and `NewFrom()` to create a cache from a deserialized +one) to recover from downtime quickly. (See the docs for `NewFrom()` for caveats.) + +### Installation + +`go get github.com/patrickmn/go-cache` + +### Usage + +```go +import ( + "fmt" + "github.com/patrickmn/go-cache" + "time" +) + +func main() { + // Create a cache with a default expiration time of 5 minutes, and which + // purges expired items every 10 minutes + c := cache.New(5*time.Minute, 10*time.Minute) + + // Set the value of the key "foo" to "bar", with the default expiration time + c.Set("foo", "bar", cache.DefaultExpiration) + + // Set the value of the key "baz" to 42, with no expiration time + // (the item won't be removed until it is re-set, or removed using + // c.Delete("baz") + c.Set("baz", 42, cache.NoExpiration) + + // Get the string associated with the key "foo" from the cache + foo, found := c.Get("foo") + if found { + fmt.Println(foo) + } + + // Since Go is statically typed, and cache values can be anything, type + // assertion is needed when values are being passed to functions that don't + // take arbitrary types, (i.e. interface{}). The simplest way to do this for + // values which will only be used once--e.g. for passing to another + // function--is: + foo, found := c.Get("foo") + if found { + MyFunction(foo.(string)) + } + + // This gets tedious if the value is used several times in the same function. + // You might do either of the following instead: + if x, found := c.Get("foo"); found { + foo := x.(string) + // ... + } + // or + var foo string + if x, found := c.Get("foo"); found { + foo = x.(string) + } + // ... + // foo can then be passed around freely as a string + + // Want performance? Store pointers! + c.Set("foo", &MyStruct, cache.DefaultExpiration) + if x, found := c.Get("foo"); found { + foo := x.(*MyStruct) + // ... + } +} +``` + +### Reference + +`godoc` or [http://godoc.org/github.com/patrickmn/go-cache](http://godoc.org/github.com/patrickmn/go-cache) diff --git a/vendor/github.com/patrickmn/go-cache/cache.go b/vendor/github.com/patrickmn/go-cache/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..db88d2f2cb1924cc263690409b4d8298d2fa7ed6 --- /dev/null +++ b/vendor/github.com/patrickmn/go-cache/cache.go @@ -0,0 +1,1161 @@ +package cache + +import ( + "encoding/gob" + "fmt" + "io" + "os" + "runtime" + "sync" + "time" +) + +type Item struct { + Object interface{} + Expiration int64 +} + +// Returns true if the item has expired. +func (item Item) Expired() bool { + if item.Expiration == 0 { + return false + } + return time.Now().UnixNano() > item.Expiration +} + +const ( + // For use with functions that take an expiration time. + NoExpiration time.Duration = -1 + // For use with functions that take an expiration time. Equivalent to + // passing in the same expiration duration as was given to New() or + // NewFrom() when the cache was created (e.g. 5 minutes.) + DefaultExpiration time.Duration = 0 +) + +type Cache struct { + *cache + // If this is confusing, see the comment at the bottom of New() +} + +type cache struct { + defaultExpiration time.Duration + items map[string]Item + mu sync.RWMutex + onEvicted func(string, interface{}) + janitor *janitor +} + +// Add an item to the cache, replacing any existing item. If the duration is 0 +// (DefaultExpiration), the cache's default expiration time is used. If it is -1 +// (NoExpiration), the item never expires. +func (c *cache) Set(k string, x interface{}, d time.Duration) { + // "Inlining" of set + var e int64 + if d == DefaultExpiration { + d = c.defaultExpiration + } + if d > 0 { + e = time.Now().Add(d).UnixNano() + } + c.mu.Lock() + c.items[k] = Item{ + Object: x, + Expiration: e, + } + // TODO: Calls to mu.Unlock are currently not deferred because defer + // adds ~200 ns (as of go1.) + c.mu.Unlock() +} + +func (c *cache) set(k string, x interface{}, d time.Duration) { + var e int64 + if d == DefaultExpiration { + d = c.defaultExpiration + } + if d > 0 { + e = time.Now().Add(d).UnixNano() + } + c.items[k] = Item{ + Object: x, + Expiration: e, + } +} + +// Add an item to the cache, replacing any existing item, using the default +// expiration. +func (c *cache) SetDefault(k string, x interface{}) { + c.Set(k, x, DefaultExpiration) +} + +// Add an item to the cache only if an item doesn't already exist for the given +// key, or if the existing item has expired. Returns an error otherwise. +func (c *cache) Add(k string, x interface{}, d time.Duration) error { + c.mu.Lock() + _, found := c.get(k) + if found { + c.mu.Unlock() + return fmt.Errorf("Item %s already exists", k) + } + c.set(k, x, d) + c.mu.Unlock() + return nil +} + +// Set a new value for the cache key only if it already exists, and the existing +// item hasn't expired. Returns an error otherwise. +func (c *cache) Replace(k string, x interface{}, d time.Duration) error { + c.mu.Lock() + _, found := c.get(k) + if !found { + c.mu.Unlock() + return fmt.Errorf("Item %s doesn't exist", k) + } + c.set(k, x, d) + c.mu.Unlock() + return nil +} + +// Get an item from the cache. Returns the item or nil, and a bool indicating +// whether the key was found. +func (c *cache) Get(k string) (interface{}, bool) { + c.mu.RLock() + // "Inlining" of get and Expired + item, found := c.items[k] + if !found { + c.mu.RUnlock() + return nil, false + } + if item.Expiration > 0 { + if time.Now().UnixNano() > item.Expiration { + c.mu.RUnlock() + return nil, false + } + } + c.mu.RUnlock() + return item.Object, true +} + +// GetWithExpiration returns an item and its expiration time from the cache. +// It returns the item or nil, the expiration time if one is set (if the item +// never expires a zero value for time.Time is returned), and a bool indicating +// whether the key was found. +func (c *cache) GetWithExpiration(k string) (interface{}, time.Time, bool) { + c.mu.RLock() + // "Inlining" of get and Expired + item, found := c.items[k] + if !found { + c.mu.RUnlock() + return nil, time.Time{}, false + } + + if item.Expiration > 0 { + if time.Now().UnixNano() > item.Expiration { + c.mu.RUnlock() + return nil, time.Time{}, false + } + + // Return the item and the expiration time + c.mu.RUnlock() + return item.Object, time.Unix(0, item.Expiration), true + } + + // If expiration <= 0 (i.e. no expiration time set) then return the item + // and a zeroed time.Time + c.mu.RUnlock() + return item.Object, time.Time{}, true +} + +func (c *cache) get(k string) (interface{}, bool) { + item, found := c.items[k] + if !found { + return nil, false + } + // "Inlining" of Expired + if item.Expiration > 0 { + if time.Now().UnixNano() > item.Expiration { + return nil, false + } + } + return item.Object, true +} + +// Increment an item of type int, int8, int16, int32, int64, uintptr, uint, +// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the +// item's value is not an integer, if it was not found, or if it is not +// possible to increment it by n. To retrieve the incremented value, use one +// of the specialized methods, e.g. IncrementInt64. +func (c *cache) Increment(k string, n int64) error { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return fmt.Errorf("Item %s not found", k) + } + switch v.Object.(type) { + case int: + v.Object = v.Object.(int) + int(n) + case int8: + v.Object = v.Object.(int8) + int8(n) + case int16: + v.Object = v.Object.(int16) + int16(n) + case int32: + v.Object = v.Object.(int32) + int32(n) + case int64: + v.Object = v.Object.(int64) + n + case uint: + v.Object = v.Object.(uint) + uint(n) + case uintptr: + v.Object = v.Object.(uintptr) + uintptr(n) + case uint8: + v.Object = v.Object.(uint8) + uint8(n) + case uint16: + v.Object = v.Object.(uint16) + uint16(n) + case uint32: + v.Object = v.Object.(uint32) + uint32(n) + case uint64: + v.Object = v.Object.(uint64) + uint64(n) + case float32: + v.Object = v.Object.(float32) + float32(n) + case float64: + v.Object = v.Object.(float64) + float64(n) + default: + c.mu.Unlock() + return fmt.Errorf("The value for %s is not an integer", k) + } + c.items[k] = v + c.mu.Unlock() + return nil +} + +// Increment an item of type float32 or float64 by n. Returns an error if the +// item's value is not floating point, if it was not found, or if it is not +// possible to increment it by n. Pass a negative number to decrement the +// value. To retrieve the incremented value, use one of the specialized methods, +// e.g. IncrementFloat64. +func (c *cache) IncrementFloat(k string, n float64) error { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return fmt.Errorf("Item %s not found", k) + } + switch v.Object.(type) { + case float32: + v.Object = v.Object.(float32) + float32(n) + case float64: + v.Object = v.Object.(float64) + n + default: + c.mu.Unlock() + return fmt.Errorf("The value for %s does not have type float32 or float64", k) + } + c.items[k] = v + c.mu.Unlock() + return nil +} + +// Increment an item of type int by n. Returns an error if the item's value is +// not an int, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementInt(k string, n int) (int, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type int8 by n. Returns an error if the item's value is +// not an int8, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementInt8(k string, n int8) (int8, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int8) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int8", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type int16 by n. Returns an error if the item's value is +// not an int16, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementInt16(k string, n int16) (int16, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int16) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int16", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type int32 by n. Returns an error if the item's value is +// not an int32, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementInt32(k string, n int32) (int32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int32", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type int64 by n. Returns an error if the item's value is +// not an int64, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementInt64(k string, n int64) (int64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int64", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uint by n. Returns an error if the item's value is +// not an uint, or if it was not found. If there is no error, the incremented +// value is returned. +func (c *cache) IncrementUint(k string, n uint) (uint, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uintptr by n. Returns an error if the item's value +// is not an uintptr, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementUintptr(k string, n uintptr) (uintptr, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uintptr) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uintptr", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uint8 by n. Returns an error if the item's value +// is not an uint8, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementUint8(k string, n uint8) (uint8, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint8) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint8", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uint16 by n. Returns an error if the item's value +// is not an uint16, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementUint16(k string, n uint16) (uint16, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint16) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint16", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uint32 by n. Returns an error if the item's value +// is not an uint32, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementUint32(k string, n uint32) (uint32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint32", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type uint64 by n. Returns an error if the item's value +// is not an uint64, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementUint64(k string, n uint64) (uint64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint64", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type float32 by n. Returns an error if the item's value +// is not an float32, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementFloat32(k string, n float32) (float32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(float32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an float32", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Increment an item of type float64 by n. Returns an error if the item's value +// is not an float64, or if it was not found. If there is no error, the +// incremented value is returned. +func (c *cache) IncrementFloat64(k string, n float64) (float64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(float64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an float64", k) + } + nv := rv + n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type int, int8, int16, int32, int64, uintptr, uint, +// uint8, uint32, or uint64, float32 or float64 by n. Returns an error if the +// item's value is not an integer, if it was not found, or if it is not +// possible to decrement it by n. To retrieve the decremented value, use one +// of the specialized methods, e.g. DecrementInt64. +func (c *cache) Decrement(k string, n int64) error { + // TODO: Implement Increment and Decrement more cleanly. + // (Cannot do Increment(k, n*-1) for uints.) + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return fmt.Errorf("Item not found") + } + switch v.Object.(type) { + case int: + v.Object = v.Object.(int) - int(n) + case int8: + v.Object = v.Object.(int8) - int8(n) + case int16: + v.Object = v.Object.(int16) - int16(n) + case int32: + v.Object = v.Object.(int32) - int32(n) + case int64: + v.Object = v.Object.(int64) - n + case uint: + v.Object = v.Object.(uint) - uint(n) + case uintptr: + v.Object = v.Object.(uintptr) - uintptr(n) + case uint8: + v.Object = v.Object.(uint8) - uint8(n) + case uint16: + v.Object = v.Object.(uint16) - uint16(n) + case uint32: + v.Object = v.Object.(uint32) - uint32(n) + case uint64: + v.Object = v.Object.(uint64) - uint64(n) + case float32: + v.Object = v.Object.(float32) - float32(n) + case float64: + v.Object = v.Object.(float64) - float64(n) + default: + c.mu.Unlock() + return fmt.Errorf("The value for %s is not an integer", k) + } + c.items[k] = v + c.mu.Unlock() + return nil +} + +// Decrement an item of type float32 or float64 by n. Returns an error if the +// item's value is not floating point, if it was not found, or if it is not +// possible to decrement it by n. Pass a negative number to decrement the +// value. To retrieve the decremented value, use one of the specialized methods, +// e.g. DecrementFloat64. +func (c *cache) DecrementFloat(k string, n float64) error { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return fmt.Errorf("Item %s not found", k) + } + switch v.Object.(type) { + case float32: + v.Object = v.Object.(float32) - float32(n) + case float64: + v.Object = v.Object.(float64) - n + default: + c.mu.Unlock() + return fmt.Errorf("The value for %s does not have type float32 or float64", k) + } + c.items[k] = v + c.mu.Unlock() + return nil +} + +// Decrement an item of type int by n. Returns an error if the item's value is +// not an int, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementInt(k string, n int) (int, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type int8 by n. Returns an error if the item's value is +// not an int8, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementInt8(k string, n int8) (int8, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int8) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int8", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type int16 by n. Returns an error if the item's value is +// not an int16, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementInt16(k string, n int16) (int16, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int16) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int16", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type int32 by n. Returns an error if the item's value is +// not an int32, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementInt32(k string, n int32) (int32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int32", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type int64 by n. Returns an error if the item's value is +// not an int64, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementInt64(k string, n int64) (int64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(int64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an int64", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uint by n. Returns an error if the item's value is +// not an uint, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementUint(k string, n uint) (uint, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uintptr by n. Returns an error if the item's value +// is not an uintptr, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementUintptr(k string, n uintptr) (uintptr, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uintptr) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uintptr", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uint8 by n. Returns an error if the item's value is +// not an uint8, or if it was not found. If there is no error, the decremented +// value is returned. +func (c *cache) DecrementUint8(k string, n uint8) (uint8, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint8) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint8", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uint16 by n. Returns an error if the item's value +// is not an uint16, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementUint16(k string, n uint16) (uint16, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint16) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint16", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uint32 by n. Returns an error if the item's value +// is not an uint32, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementUint32(k string, n uint32) (uint32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint32", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type uint64 by n. Returns an error if the item's value +// is not an uint64, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementUint64(k string, n uint64) (uint64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(uint64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an uint64", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type float32 by n. Returns an error if the item's value +// is not an float32, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementFloat32(k string, n float32) (float32, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(float32) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an float32", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Decrement an item of type float64 by n. Returns an error if the item's value +// is not an float64, or if it was not found. If there is no error, the +// decremented value is returned. +func (c *cache) DecrementFloat64(k string, n float64) (float64, error) { + c.mu.Lock() + v, found := c.items[k] + if !found || v.Expired() { + c.mu.Unlock() + return 0, fmt.Errorf("Item %s not found", k) + } + rv, ok := v.Object.(float64) + if !ok { + c.mu.Unlock() + return 0, fmt.Errorf("The value for %s is not an float64", k) + } + nv := rv - n + v.Object = nv + c.items[k] = v + c.mu.Unlock() + return nv, nil +} + +// Delete an item from the cache. Does nothing if the key is not in the cache. +func (c *cache) Delete(k string) { + c.mu.Lock() + v, evicted := c.delete(k) + c.mu.Unlock() + if evicted { + c.onEvicted(k, v) + } +} + +func (c *cache) delete(k string) (interface{}, bool) { + if c.onEvicted != nil { + if v, found := c.items[k]; found { + delete(c.items, k) + return v.Object, true + } + } + delete(c.items, k) + return nil, false +} + +type keyAndValue struct { + key string + value interface{} +} + +// Delete all expired items from the cache. +func (c *cache) DeleteExpired() { + var evictedItems []keyAndValue + now := time.Now().UnixNano() + c.mu.Lock() + for k, v := range c.items { + // "Inlining" of expired + if v.Expiration > 0 && now > v.Expiration { + ov, evicted := c.delete(k) + if evicted { + evictedItems = append(evictedItems, keyAndValue{k, ov}) + } + } + } + c.mu.Unlock() + for _, v := range evictedItems { + c.onEvicted(v.key, v.value) + } +} + +// Sets an (optional) function that is called with the key and value when an +// item is evicted from the cache. (Including when it is deleted manually, but +// not when it is overwritten.) Set to nil to disable. +func (c *cache) OnEvicted(f func(string, interface{})) { + c.mu.Lock() + c.onEvicted = f + c.mu.Unlock() +} + +// Write the cache's items (using Gob) to an io.Writer. +// +// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the +// documentation for NewFrom().) +func (c *cache) Save(w io.Writer) (err error) { + enc := gob.NewEncoder(w) + defer func() { + if x := recover(); x != nil { + err = fmt.Errorf("Error registering item types with Gob library") + } + }() + c.mu.RLock() + defer c.mu.RUnlock() + for _, v := range c.items { + gob.Register(v.Object) + } + err = enc.Encode(&c.items) + return +} + +// Save the cache's items to the given filename, creating the file if it +// doesn't exist, and overwriting it if it does. +// +// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the +// documentation for NewFrom().) +func (c *cache) SaveFile(fname string) error { + fp, err := os.Create(fname) + if err != nil { + return err + } + err = c.Save(fp) + if err != nil { + fp.Close() + return err + } + return fp.Close() +} + +// Add (Gob-serialized) cache items from an io.Reader, excluding any items with +// keys that already exist (and haven't expired) in the current cache. +// +// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the +// documentation for NewFrom().) +func (c *cache) Load(r io.Reader) error { + dec := gob.NewDecoder(r) + items := map[string]Item{} + err := dec.Decode(&items) + if err == nil { + c.mu.Lock() + defer c.mu.Unlock() + for k, v := range items { + ov, found := c.items[k] + if !found || ov.Expired() { + c.items[k] = v + } + } + } + return err +} + +// Load and add cache items from the given filename, excluding any items with +// keys that already exist in the current cache. +// +// NOTE: This method is deprecated in favor of c.Items() and NewFrom() (see the +// documentation for NewFrom().) +func (c *cache) LoadFile(fname string) error { + fp, err := os.Open(fname) + if err != nil { + return err + } + err = c.Load(fp) + if err != nil { + fp.Close() + return err + } + return fp.Close() +} + +// Copies all unexpired items in the cache into a new map and returns it. +func (c *cache) Items() map[string]Item { + c.mu.RLock() + defer c.mu.RUnlock() + m := make(map[string]Item, len(c.items)) + now := time.Now().UnixNano() + for k, v := range c.items { + // "Inlining" of Expired + if v.Expiration > 0 { + if now > v.Expiration { + continue + } + } + m[k] = v + } + return m +} + +// Returns the number of items in the cache. This may include items that have +// expired, but have not yet been cleaned up. +func (c *cache) ItemCount() int { + c.mu.RLock() + n := len(c.items) + c.mu.RUnlock() + return n +} + +// Delete all items from the cache. +func (c *cache) Flush() { + c.mu.Lock() + c.items = map[string]Item{} + c.mu.Unlock() +} + +type janitor struct { + Interval time.Duration + stop chan bool +} + +func (j *janitor) Run(c *cache) { + ticker := time.NewTicker(j.Interval) + for { + select { + case <-ticker.C: + c.DeleteExpired() + case <-j.stop: + ticker.Stop() + return + } + } +} + +func stopJanitor(c *Cache) { + c.janitor.stop <- true +} + +func runJanitor(c *cache, ci time.Duration) { + j := &janitor{ + Interval: ci, + stop: make(chan bool), + } + c.janitor = j + go j.Run(c) +} + +func newCache(de time.Duration, m map[string]Item) *cache { + if de == 0 { + de = -1 + } + c := &cache{ + defaultExpiration: de, + items: m, + } + return c +} + +func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache { + c := newCache(de, m) + // This trick ensures that the janitor goroutine (which--granted it + // was enabled--is running DeleteExpired on c forever) does not keep + // the returned C object from being garbage collected. When it is + // garbage collected, the finalizer stops the janitor goroutine, after + // which c can be collected. + C := &Cache{c} + if ci > 0 { + runJanitor(c, ci) + runtime.SetFinalizer(C, stopJanitor) + } + return C +} + +// Return a new cache with a given default expiration duration and cleanup +// interval. If the expiration duration is less than one (or NoExpiration), +// the items in the cache never expire (by default), and must be deleted +// manually. If the cleanup interval is less than one, expired items are not +// deleted from the cache before calling c.DeleteExpired(). +func New(defaultExpiration, cleanupInterval time.Duration) *Cache { + items := make(map[string]Item) + return newCacheWithJanitor(defaultExpiration, cleanupInterval, items) +} + +// Return a new cache with a given default expiration duration and cleanup +// interval. If the expiration duration is less than one (or NoExpiration), +// the items in the cache never expire (by default), and must be deleted +// manually. If the cleanup interval is less than one, expired items are not +// deleted from the cache before calling c.DeleteExpired(). +// +// NewFrom() also accepts an items map which will serve as the underlying map +// for the cache. This is useful for starting from a deserialized cache +// (serialized using e.g. gob.Encode() on c.Items()), or passing in e.g. +// make(map[string]Item, 500) to improve startup performance when the cache +// is expected to reach a certain minimum size. +// +// Only the cache's methods synchronize access to this map, so it is not +// recommended to keep any references to the map around after creating a cache. +// If need be, the map can be accessed at a later point using c.Items() (subject +// to the same caveat.) +// +// Note regarding serialization: When using e.g. gob, make sure to +// gob.Register() the individual types stored in the cache before encoding a +// map retrieved with c.Items(), and to register those same types before +// decoding a blob containing an items map. +func NewFrom(defaultExpiration, cleanupInterval time.Duration, items map[string]Item) *Cache { + return newCacheWithJanitor(defaultExpiration, cleanupInterval, items) +} diff --git a/vendor/github.com/patrickmn/go-cache/sharded.go b/vendor/github.com/patrickmn/go-cache/sharded.go new file mode 100644 index 0000000000000000000000000000000000000000..bcc0538bcc7abc11bf0a0d35755bae1f76f83a23 --- /dev/null +++ b/vendor/github.com/patrickmn/go-cache/sharded.go @@ -0,0 +1,192 @@ +package cache + +import ( + "crypto/rand" + "math" + "math/big" + insecurerand "math/rand" + "os" + "runtime" + "time" +) + +// This is an experimental and unexported (for now) attempt at making a cache +// with better algorithmic complexity than the standard one, namely by +// preventing write locks of the entire cache when an item is added. As of the +// time of writing, the overhead of selecting buckets results in cache +// operations being about twice as slow as for the standard cache with small +// total cache sizes, and faster for larger ones. +// +// See cache_test.go for a few benchmarks. + +type unexportedShardedCache struct { + *shardedCache +} + +type shardedCache struct { + seed uint32 + m uint32 + cs []*cache + janitor *shardedJanitor +} + +// djb2 with better shuffling. 5x faster than FNV with the hash.Hash overhead. +func djb33(seed uint32, k string) uint32 { + var ( + l = uint32(len(k)) + d = 5381 + seed + l + i = uint32(0) + ) + // Why is all this 5x faster than a for loop? + if l >= 4 { + for i < l-4 { + d = (d * 33) ^ uint32(k[i]) + d = (d * 33) ^ uint32(k[i+1]) + d = (d * 33) ^ uint32(k[i+2]) + d = (d * 33) ^ uint32(k[i+3]) + i += 4 + } + } + switch l - i { + case 1: + case 2: + d = (d * 33) ^ uint32(k[i]) + case 3: + d = (d * 33) ^ uint32(k[i]) + d = (d * 33) ^ uint32(k[i+1]) + case 4: + d = (d * 33) ^ uint32(k[i]) + d = (d * 33) ^ uint32(k[i+1]) + d = (d * 33) ^ uint32(k[i+2]) + } + return d ^ (d >> 16) +} + +func (sc *shardedCache) bucket(k string) *cache { + return sc.cs[djb33(sc.seed, k)%sc.m] +} + +func (sc *shardedCache) Set(k string, x interface{}, d time.Duration) { + sc.bucket(k).Set(k, x, d) +} + +func (sc *shardedCache) Add(k string, x interface{}, d time.Duration) error { + return sc.bucket(k).Add(k, x, d) +} + +func (sc *shardedCache) Replace(k string, x interface{}, d time.Duration) error { + return sc.bucket(k).Replace(k, x, d) +} + +func (sc *shardedCache) Get(k string) (interface{}, bool) { + return sc.bucket(k).Get(k) +} + +func (sc *shardedCache) Increment(k string, n int64) error { + return sc.bucket(k).Increment(k, n) +} + +func (sc *shardedCache) IncrementFloat(k string, n float64) error { + return sc.bucket(k).IncrementFloat(k, n) +} + +func (sc *shardedCache) Decrement(k string, n int64) error { + return sc.bucket(k).Decrement(k, n) +} + +func (sc *shardedCache) Delete(k string) { + sc.bucket(k).Delete(k) +} + +func (sc *shardedCache) DeleteExpired() { + for _, v := range sc.cs { + v.DeleteExpired() + } +} + +// Returns the items in the cache. This may include items that have expired, +// but have not yet been cleaned up. If this is significant, the Expiration +// fields of the items should be checked. Note that explicit synchronization +// is needed to use a cache and its corresponding Items() return values at +// the same time, as the maps are shared. +func (sc *shardedCache) Items() []map[string]Item { + res := make([]map[string]Item, len(sc.cs)) + for i, v := range sc.cs { + res[i] = v.Items() + } + return res +} + +func (sc *shardedCache) Flush() { + for _, v := range sc.cs { + v.Flush() + } +} + +type shardedJanitor struct { + Interval time.Duration + stop chan bool +} + +func (j *shardedJanitor) Run(sc *shardedCache) { + j.stop = make(chan bool) + tick := time.Tick(j.Interval) + for { + select { + case <-tick: + sc.DeleteExpired() + case <-j.stop: + return + } + } +} + +func stopShardedJanitor(sc *unexportedShardedCache) { + sc.janitor.stop <- true +} + +func runShardedJanitor(sc *shardedCache, ci time.Duration) { + j := &shardedJanitor{ + Interval: ci, + } + sc.janitor = j + go j.Run(sc) +} + +func newShardedCache(n int, de time.Duration) *shardedCache { + max := big.NewInt(0).SetUint64(uint64(math.MaxUint32)) + rnd, err := rand.Int(rand.Reader, max) + var seed uint32 + if err != nil { + os.Stderr.Write([]byte("WARNING: go-cache's newShardedCache failed to read from the system CSPRNG (/dev/urandom or equivalent.) Your system's security may be compromised. Continuing with an insecure seed.\n")) + seed = insecurerand.Uint32() + } else { + seed = uint32(rnd.Uint64()) + } + sc := &shardedCache{ + seed: seed, + m: uint32(n), + cs: make([]*cache, n), + } + for i := 0; i < n; i++ { + c := &cache{ + defaultExpiration: de, + items: map[string]Item{}, + } + sc.cs[i] = c + } + return sc +} + +func unexportedNewSharded(defaultExpiration, cleanupInterval time.Duration, shards int) *unexportedShardedCache { + if defaultExpiration == 0 { + defaultExpiration = -1 + } + sc := newShardedCache(shards, defaultExpiration) + SC := &unexportedShardedCache{sc} + if cleanupInterval > 0 { + runShardedJanitor(sc, cleanupInterval) + runtime.SetFinalizer(SC, stopShardedJanitor) + } + return SC +} diff --git a/vendor/github.com/projectcalico/kube-controllers/LICENSE b/vendor/github.com/projectcalico/kube-controllers/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..8dada3edaf50dbc082c9a125058f25def75e625a --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/cache/cache.go b/vendor/github.com/projectcalico/kube-controllers/pkg/cache/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..1f5e7e4252d3fba6b1bfd902ff5f24b3db4afb9f --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/cache/cache.go @@ -0,0 +1,296 @@ +// 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 cache + +import ( + "reflect" + "sync" + "time" + + "github.com/patrickmn/go-cache" + log "github.com/sirupsen/logrus" + "k8s.io/client-go/util/workqueue" +) + +// ResourceCache stores resources and queues updates when those resources +// are created, modified, or deleted. It de-duplicates updates by ensuring +// updates are only queued when an object has changed. +type ResourceCache interface { + // Set sets the key to the provided value, and generates an update + // on the queue the value has changed. + Set(key string, value interface{}) + + // Get gets the value associated with the given key. Returns nil + // if the key is not present. + Get(key string) (interface{}, bool) + + // Prime sets the key to the provided value, but does not generate + // and update on the queue ever. + Prime(key string, value interface{}) + + // Delete deletes the value identified by the given key from the cache, and + // generates an update on the queue if a value was deleted. + Delete(key string) + + // Clean removes the object identified by the given key from the cache. + // It does not generate an update on the queue. + Clean(key string) + + // ListKeys lists the keys currently in the cache. + ListKeys() []string + + // Run enables the generation of events on the output queue starts + // cache reconciliation. + Run(reconcilerPeriod string) + + // GetQueue returns the cache's output queue, which emits a stream + // of any keys which have been created, modified, or deleted. + GetQueue() workqueue.RateLimitingInterface +} + +// ResourceCacheArgs struct passed to constructor of ResourceCache. +// Groups togather all the arguments to pass in single struct. +type ResourceCacheArgs struct { + // ListFunc returns a mapping of keys to objects from the Calico datastore. + ListFunc func() (map[string]interface{}, error) + + // ObjectType is the type of object which is to be stored in this cache. + ObjectType reflect.Type + + // LogTypeDesc (optional) to log the type of object stored in the cache. + // If not provided it is derived from the ObjectType. + LogTypeDesc string + + ReconcilerConfig ReconcilerConfig +} + +// ReconcilerConfig contains configuration for the periodic reconciler. +type ReconcilerConfig struct { + // DisableUpdateOnChange disables the queuing of updates when the reconciler + // detects that a value has changed in the datastore. + DisableUpdateOnChange bool + + // DisableMissingInDatastore disables queueing of updates when the reconciler + // detects that a value is no longer in the datastore but still exists in the cache. + DisableMissingInDatastore bool + + // DisableMissingInCache disables queueing of updates when reconciler detects + // that a value that is still in the datastore no longer is in the cache. + DisableMissingInCache bool +} + +// calicoCache implements the ResourceCache interface +type calicoCache struct { + threadSafeCache *cache.Cache + workqueue workqueue.RateLimitingInterface + ListFunc func() (map[string]interface{}, error) + ObjectType reflect.Type + log *log.Entry + running bool + mut *sync.Mutex + reconcilerConfig ReconcilerConfig +} + +// NewResourceCache builds and returns a resource cache using the provided arguments. +func NewResourceCache(args ResourceCacheArgs) ResourceCache { + // Make sure logging is context aware. + return &calicoCache{ + threadSafeCache: cache.New(cache.NoExpiration, cache.DefaultExpiration), + workqueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), + ListFunc: args.ListFunc, + ObjectType: args.ObjectType, + log: func() *log.Entry { + if args.LogTypeDesc == "" { + return log.WithFields(log.Fields{"type": args.ObjectType}) + } + return log.WithFields(log.Fields{"type": args.LogTypeDesc}) + }(), + mut: &sync.Mutex{}, + reconcilerConfig: args.ReconcilerConfig, + } +} + +func (c *calicoCache) Set(key string, newObj interface{}) { + if reflect.TypeOf(newObj) != c.ObjectType { + c.log.Fatalf("Wrong object type recieved to store in cache. Expected: %s, Found: %s", c.ObjectType, reflect.TypeOf(newObj)) + } + + // Check if the object exists in the cache already. If it does and hasn't changed, + // then we don't need to send an update on the queue. + if existingObj, found := c.threadSafeCache.Get(key); found { + c.log.Debugf("%#v already exists in cache - comparing.", existingObj) + if !reflect.DeepEqual(existingObj, newObj) { + // The objects do not match - send an update over the queue. + c.threadSafeCache.Set(key, newObj, cache.NoExpiration) + if c.isRunning() { + c.log.Debugf("Queueing update - %#v and %#v do not match.", newObj, existingObj) + c.workqueue.Add(key) + } + } + } else { + c.threadSafeCache.Set(key, newObj, cache.NoExpiration) + if c.isRunning() { + c.log.Debugf("%#v not found in cache, adding it + queuing update.", newObj) + c.workqueue.Add(key) + } + } +} + +func (c *calicoCache) Delete(key string) { + c.log.Debugf("Deleting %s from cache", key) + c.threadSafeCache.Delete(key) + c.workqueue.Add(key) +} + +func (c *calicoCache) Clean(key string) { + c.log.Debugf("Cleaning %s from cache, no update required", key) + c.threadSafeCache.Delete(key) +} + +func (c *calicoCache) Get(key string) (interface{}, bool) { + obj, found := c.threadSafeCache.Get(key) + if found { + return obj, true + } + return nil, false +} + +// Prime adds the key and value to the cache but will never generate +// an update on the queue. +func (c *calicoCache) Prime(key string, value interface{}) { + c.threadSafeCache.Set(key, value, cache.NoExpiration) +} + +// ListKeys returns a list of all the keys in the cache. +func (c *calicoCache) ListKeys() []string { + cacheItems := c.threadSafeCache.Items() + keys := make([]string, 0, len(cacheItems)) + for k := range cacheItems { + keys = append(keys, k) + } + + return keys +} + +// GetQueue returns the output queue from the cache. Whenever a key/value pair +// is modified, an event will appear on this queue. +func (c *calicoCache) GetQueue() workqueue.RateLimitingInterface { + return c.workqueue +} + +// Run starts the cache. Any Set() calls prior to calling Run() will +// prime the cache, but not trigger any updates on the output queue. +func (c *calicoCache) Run(reconcilerPeriod string) { + go c.reconcile(reconcilerPeriod) + + // Indicate that the cache is running, and so updates + // can be queued. + c.mut.Lock() + c.running = true + c.mut.Unlock() +} + +func (c *calicoCache) isRunning() bool { + c.mut.Lock() + defer c.mut.Unlock() + return c.running +} + +// reconcile ensures a reconciliation is run every `reconcilerPeriod` in order to bring the datastore +// in sync with the cache. This is to correct any manual changes made in the datastore +// without the cache being aware. +func (c *calicoCache) reconcile(reconcilerPeriod string) { + duration, err := time.ParseDuration(reconcilerPeriod) + if err != nil { + c.log.Fatalf("Invalid time duration format for reconciler: %s. Some valid examples: 5m, 30s, 2m30s etc.", reconcilerPeriod) + } + + // If user has set duration to 0 then disable the reconciler job. + if duration.Nanoseconds() == 0 { + c.log.Infof("Reconciler period set to %d. Disabling reconciler.", duration.Nanoseconds()) + return + } + + // Loop forever, performing a datastore reconciliation periodically. + for { + c.log.Debugf("Performing reconciliation") + err := c.performDatastoreSync() + if err != nil { + c.log.WithError(err).Error("Reconciliation failed") + continue + } + + // Reconciliation was successful, sleep the configured duration. + c.log.Debugf("Reconciliation complete, %+v until next one.", duration) + time.Sleep(duration) + } +} + +func (c *calicoCache) performDatastoreSync() error { + // Get all the objects we care about from the datastore using ListFunc. + objMap, err := c.ListFunc() + if err != nil { + c.log.WithError(err).Errorf("unable to list objects from datastore while reconciling.") + return err + } + + // Build a map of existing keys in the datastore. + allKeys := map[string]bool{} + for key := range objMap { + allKeys[key] = true + } + + // Also add all existing keys in the cache. + for _, key := range c.ListKeys() { + allKeys[key] = true + } + + c.log.Debugf("Reconciling %d keys in total", len(allKeys)) + for key := range allKeys { + cachedObj, existsInCache := c.Get(key) + if !existsInCache { + // Key does not exist in the cache, queue an update to + // remove it from the datastore if configured to do so. + if !c.reconcilerConfig.DisableMissingInCache { + c.log.WithField("key", key).Warn("Value for key should not exist, queueing update to remove") + c.workqueue.Add(key) + } + continue + } + + obj, existsInDatastore := objMap[key] + if !existsInDatastore { + // Key exists in the cache but not in the datastore - queue an update + // to re-add it if configured to do so. + if !c.reconcilerConfig.DisableMissingInDatastore { + c.log.WithField("key", key).Warn("Value for key is missing in datastore, queueing update to reprogram") + c.workqueue.Add(key) + } + continue + } + + if !reflect.DeepEqual(obj, cachedObj) { + // Objects differ - queue an update to re-program if configured to do so. + if !c.reconcilerConfig.DisableUpdateOnChange { + c.log.WithField("key", key).Warn("Value for key has changed, queueing update to reprogram") + c.log.Debugf("Cached: %#v", cachedObj) + c.log.Debugf("Updated: %#v", obj) + c.workqueue.Add(key) + } + continue + } + } + return nil +} diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/converter/converter.go b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/converter.go new file mode 100644 index 0000000000000000000000000000000000000000..2a63787c4d997b59d36498eeb41f169ba72bae01 --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/converter.go @@ -0,0 +1,28 @@ +// 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 + +// Converter Responsible for conversion of given kubernetes object to equivalent calico object +type Converter interface { + // Converts kubernetes object to calico representation of it. + Convert(k8sObj interface{}) (interface{}, error) + + // Returns apporpriate key for the object + GetKey(obj interface{}) string + + // DeleteArgsFromKey returns name and namespace of the object to pass to Delete + // for the given key as generated by GetKey. + DeleteArgsFromKey(key string) (string, string) +} diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/converter/namespace_converter.go b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/namespace_converter.go new file mode 100644 index 0000000000000000000000000000000000000000..09c926a5a92a19140e30ef87af9c4ba143f4c364 --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/namespace_converter.go @@ -0,0 +1,72 @@ +// 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 ( + "fmt" + + api "github.com/projectcalico/libcalico-go/lib/apis/v3" + "github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +type namespaceConverter struct { +} + +// NewNamespaceConverter Constructor for namespaceConverter +func NewNamespaceConverter() Converter { + return &namespaceConverter{} +} +func (nc *namespaceConverter) Convert(k8sObj interface{}) (interface{}, error) { + var c conversion.Converter + namespace, ok := k8sObj.(*v1.Namespace) + if !ok { + tombstone, ok := k8sObj.(cache.DeletedFinalStateUnknown) + if !ok { + return nil, fmt.Errorf("couldn't get object from tombstone %+v", k8sObj) + } + namespace, ok = tombstone.Obj.(*v1.Namespace) + if !ok { + return nil, fmt.Errorf("tombstone contained object that is not a Namespace %+v", k8sObj) + } + } + kvp, err := c.NamespaceToProfile(namespace) + if err != nil { + return nil, err + } + profile := kvp.Value.(*api.Profile) + + // Isolate the metadata fields that we care about. ResourceVersion, CreationTimeStamp, etc are + // not relevant so we ignore them. This prevents uncessary updates. + profile.ObjectMeta = metav1.ObjectMeta{Name: profile.Name} + + return *profile, nil +} + +// GetKey returns name of the Profile as its key. For Profiles +// backed by Kubernetes namespaces and managed by this controller, the name +// is of format `kns.name`. +func (nc *namespaceConverter) GetKey(obj interface{}) string { + profile := obj.(api.Profile) + return profile.Name +} + +func (p *namespaceConverter) DeleteArgsFromKey(key string) (string, string) { + // Not namespaced, so just return the key, which is the profile name. + return "", key +} diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/converter/networkpolicy_converter.go b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/networkpolicy_converter.go new file mode 100644 index 0000000000000000000000000000000000000000..63a877082849c42c90659362b758f42c4a5ee409 --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/networkpolicy_converter.go @@ -0,0 +1,75 @@ +// 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 ( + "fmt" + "strings" + + api "github.com/projectcalico/libcalico-go/lib/apis/v3" + "github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion" + + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +type policyConverter struct { +} + +// NewPolicyConverter Constructor for policyConverter +func NewPolicyConverter() Converter { + return &policyConverter{} +} + +// Convert takes a Kubernetes NetworkPolicy and returns a Calico api.NetworkPolicy representation. +func (p *policyConverter) Convert(k8sObj interface{}) (interface{}, error) { + np, ok := k8sObj.(*networkingv1.NetworkPolicy) + + if !ok { + tombstone, ok := k8sObj.(cache.DeletedFinalStateUnknown) + if !ok { + return nil, fmt.Errorf("couldn't get object from tombstone %+v", k8sObj) + } + np, ok = tombstone.Obj.(*networkingv1.NetworkPolicy) + if !ok { + return nil, fmt.Errorf("tombstone contained object that is not a NetworkPolicy %+v", k8sObj) + } + } + + var c conversion.Converter + kvp, err := c.K8sNetworkPolicyToCalico(np) + if err != nil { + return nil, err + } + cnp := kvp.Value.(*api.NetworkPolicy) + + // Isolate the metadata fields that we care about. ResourceVersion, CreationTimeStamp, etc are + // not relevant so we ignore them. This prevents uncessary updates. + cnp.ObjectMeta = metav1.ObjectMeta{Name: cnp.Name, Namespace: cnp.Namespace} + + return *cnp, err +} + +// GetKey returns the 'namespace/name' for the given Calico NetworkPolicy as its key. +func (p *policyConverter) GetKey(obj interface{}) string { + policy := obj.(api.NetworkPolicy) + return fmt.Sprintf("%s/%s", policy.Namespace, policy.Name) +} + +func (p *policyConverter) DeleteArgsFromKey(key string) (string, string) { + splits := strings.SplitN(key, "/", 2) + return splits[0], splits[1] +} diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/converter/pod_converter.go b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/pod_converter.go new file mode 100644 index 0000000000000000000000000000000000000000..9b892ab0add6a2598883b7bde26914e73a51b8f4 --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/pod_converter.go @@ -0,0 +1,109 @@ +// 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 "", "" +} diff --git a/vendor/github.com/projectcalico/kube-controllers/pkg/converter/serviceaccount_converter.go b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/serviceaccount_converter.go new file mode 100644 index 0000000000000000000000000000000000000000..5cd9157f0d3b81f6cdb12d45888b76256b94af89 --- /dev/null +++ b/vendor/github.com/projectcalico/kube-controllers/pkg/converter/serviceaccount_converter.go @@ -0,0 +1,73 @@ +// Copyright (c) 2018 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 ( + "fmt" + + api "github.com/projectcalico/libcalico-go/lib/apis/v3" + "github.com/projectcalico/libcalico-go/lib/backend/k8s/conversion" + + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +type serviceAccountConverter struct { +} + +// NewServiceaccountConverter Constructor to convert ServiceAccount to Profile +func NewServiceAccountConverter() Converter { + return &serviceAccountConverter{} +} + +func (nc *serviceAccountConverter) Convert(k8sObj interface{}) (interface{}, error) { + var c conversion.Converter + serviceAccount, ok := k8sObj.(*v1.ServiceAccount) + if !ok { + tombstone, ok := k8sObj.(cache.DeletedFinalStateUnknown) + if !ok { + return nil, fmt.Errorf("couldn't get object from tombstone %+v", k8sObj) + } + serviceAccount, ok = tombstone.Obj.(*v1.ServiceAccount) + if !ok { + return nil, fmt.Errorf("tombstone contained object that is not a Serviceaccount %+v", k8sObj) + } + } + kvp, err := c.ServiceAccountToProfile(serviceAccount) + if err != nil { + return nil, err + } + profile := kvp.Value.(*api.Profile) + + // Isolate the metadata fields that we care about. ResourceVersion, CreationTimeStamp, etc are + // not relevant so we ignore them. This prevents uncessary updates. + profile.ObjectMeta = metav1.ObjectMeta{Name: profile.Name} + + return *profile, nil +} + +// GetKey returns name of the Profile as its key. For Profiles +// backed by Kubernetes serviceaccounts and managed by this controller, the name +// is of format `ksa.namespace.name`. +func (nc *serviceAccountConverter) GetKey(obj interface{}) string { + profile := obj.(api.Profile) + return profile.Name +} + +func (nc *serviceAccountConverter) DeleteArgsFromKey(key string) (string, string) { + // Not serviceaccount, so just return the key, which is the profile name. + return "", key +}