Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

k8s: Fix CCNP for host policies #11638

Merged
merged 1 commit into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions examples/policies/l3/host/host-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
description: "Allow ports for kube-dns, kube-api, Cilium, and SSH, as well as queries to Google's DNS on UDP/53 only"
metadata:
name: "allow-google-dns-on-udp-53-only"
spec:
nodeSelector:
matchLabels:
{}
ingress:
- toPorts:
- ports:
- port: "6443"
protocol: TCP
- port: "22"
protocol: TCP
egress:
- toPorts:
- ports:
- port: "4240"
protocol: TCP
- port: "8080"
protocol: TCP
pchaigno marked this conversation as resolved.
Show resolved Hide resolved
- toCIDR:
- "8.8.0.0/16"
toPorts:
- ports:
- port: "53"
protocol: UDP
13 changes: 11 additions & 2 deletions pkg/k8s/apis/cilium.io/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func getEndpointSelector(namespace string, labelSelector *slim_metav1.LabelSelec
}

func parseToCiliumIngressRule(namespace string, inRule, retRule *api.Rule) {
matchesInit := retRule.EndpointSelector.HasKey(podInitLbl)
matchesInit := matchesPodInit(retRule.EndpointSelector)

if inRule.Ingress != nil {
retRule.Ingress = make([]api.IngressRule, len(inRule.Ingress))
Expand Down Expand Up @@ -145,7 +145,7 @@ func parseToCiliumIngressRule(namespace string, inRule, retRule *api.Rule) {
}

func parseToCiliumEgressRule(namespace string, inRule, retRule *api.Rule) {
matchesInit := retRule.EndpointSelector.HasKey(podInitLbl)
matchesInit := matchesPodInit(retRule.EndpointSelector)

if inRule.Egress != nil {
retRule.Egress = make([]api.EgressRule, len(inRule.Egress))
Expand Down Expand Up @@ -204,6 +204,13 @@ func parseToCiliumEgressRule(namespace string, inRule, retRule *api.Rule) {
}
}

func matchesPodInit(epSelector api.EndpointSelector) bool {
if epSelector.LabelSelector == nil {
return false
}
return epSelector.HasKey(podInitLbl)
}

// namespacesAreValid checks the set of namespaces from a rule returns true if
// they are not specified, or if they are specified and match the namespace
// where the rule is being inserted.
Expand Down Expand Up @@ -240,6 +247,8 @@ func ParseToCiliumRule(namespace, name string, uid types.UID, r *api.Rule) *api.
}
retRule.EndpointSelector.AddMatch(podPrefixLbl, namespace)
}
} else if r.NodeSelector.LabelSelector != nil {
retRule.NodeSelector = api.NewESFromK8sLabelSelector("", r.NodeSelector.LabelSelector)
}

parseToCiliumIngressRule(namespace, r, retRule)
Expand Down
42 changes: 26 additions & 16 deletions pkg/k8s/apis/cilium.io/v2/client/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const (

// CustomResourceDefinitionSchemaVersion is semver-conformant version of CRD schema
// Used to determine if CRD needs to be updated in cluster
CustomResourceDefinitionSchemaVersion = "1.19"
CustomResourceDefinitionSchemaVersion = "1.20"

// CustomResourceDefinitionSchemaVersionKey is key to label which holds the CRD schema version
CustomResourceDefinitionSchemaVersionKey = "io.cilium.k8s.crd.schema.version"
Expand Down Expand Up @@ -182,6 +182,27 @@ func createCCNPCRD(clientset apiextensionsclient.Interface) error {
CRDName = CustomResourceDefinitionPluralName + "." + SchemeGroupVersion.Group
)

CCNPCRV := CNPCRV.DeepCopy()
clusterwideSpec := CCNPCRV.OpenAPIV3Schema.Properties["spec"]
clusterwideSpec.Required = nil
clusterwideSpec.OneOf = []apiextensionsv1beta1.JSONSchemaProps{
{
Required: []string{"endpointSelector"},
},
{
Required: []string{"nodeSelector"},
},
}
CCNPCRV.OpenAPIV3Schema.Properties["spec"] = clusterwideSpec
pchaigno marked this conversation as resolved.
Show resolved Hide resolved
CCNPCRV.OpenAPIV3Schema.Properties["specs"] = apiextensionsv1beta1.JSONSchemaProps{
Description: "Specs is a list of desired Cilium specific rule specification.",
Type: "array",
Items: &apiextensionsv1beta1.JSONSchemaPropsOrArray{
Schema: &clusterwideSpec,
},
}
CCNPCRV.OpenAPIV3Schema.Properties["NodeSelector"] = NodeSelector

res := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: CRDName,
Expand All @@ -202,7 +223,7 @@ func createCCNPCRD(clientset apiextensionsclient.Interface) error {
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
},
Scope: apiextensionsv1beta1.ClusterScoped,
Validation: &CNPCRV,
Validation: CCNPCRV,
},
}
// Kubernetes < 1.12 does not support having the field Type set in the root
Expand Down Expand Up @@ -877,7 +898,9 @@ var (
},
},
}

EndpointSelector = *LabelSelector.DeepCopy()
NodeSelector = *LabelSelector.DeepCopy()

IngressRule = apiextensionsv1beta1.JSONSchemaProps{
Type: "object",
Expand Down Expand Up @@ -1449,14 +1472,7 @@ var (
"ingress and egress, both ingress and egress side have to either specifically allow " +
"the connection or one side has to be omitted.\n\nEither ingress, egress, or both " +
"can be provided. If both ingress and egress are omitted, the rule has no effect.",
OneOf: []apiextensionsv1beta1.JSONSchemaProps{
{
Required: []string{"endpointSelector"},
},
{
Required: []string{"nodeSelector"},
},
},
Required: []string{"endpointSelector"},
Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
"Description": {
Description: "Description is a free form string, it can be used by the creator " +
Expand All @@ -1473,7 +1489,6 @@ var (
},
},
"endpointSelector": EndpointSelector,
"nodeSelector": EndpointSelector,
"ingress": {
Description: "Ingress is a list of IngressRule which are enforced at ingress. " +
"If omitted or empty, this rule does not apply at ingress.",
Expand Down Expand Up @@ -1543,11 +1558,6 @@ func init() {
"to this rule. Cannot be empty if nodeSelector is empty."
Rule.Properties["endpointSelector"] = ruleProps

ruleProps = Rule.Properties["nodeSelector"]
ruleProps.Description = "NodeSelector selects all nodes which should be subject " +
"to this rule. Cannot be empty if endpointSelector is empty."
Rule.Properties["nodeSelector"] = ruleProps

serviceProps := Service.Properties["k8sServiceSelector"]
serviceProps.Description = "K8sServiceSelector selects services by k8s labels. " +
"Not supported yet"
Expand Down
1 change: 0 additions & 1 deletion pkg/k8s/apis/cilium.io/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ func (r *CiliumNetworkPolicy) Parse() (api.Rules, error) {
if r.Spec != nil {
if err := r.Spec.Sanitize(); err != nil {
return nil, fmt.Errorf("Invalid CiliumNetworkPolicy spec: %s", err)

}
cr := k8sCiliumUtils.ParseToCiliumRule(namespace, name, uid, r.Spec)
retRules = append(retRules, cr)
Expand Down