api icon indicating copy to clipboard operation
api copied to clipboard

AuthorizationPolicy: client-go SDK will skip serialize action with AuthorizationPolicy_ALLOW since it is int32(0)

Open taitelman opened this issue 3 years ago • 2 comments

while generating a standard AuthorizationPolicy via client side SDK , I ran kubectl describe... I noticed the Action is missing from my AuthorizationPolicy

this is the code sniplet:

      allowIncomingTrafficRuleFromTheseSA := v1betaSecurityAPI.Rule{
		From: []*v1betaSecurityAPI.Rule_From{
			&v1betaSecurityAPI.Rule_From{
				Source: &v1betaSecurityAPI.Source{
					Principals: []string{
						// list of service accounts in a special query format
						"cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account",
						"cluster.local/ns/istio-system/sa/istio-ingressgateway-public-2-service-account",
						"cluster.local/ns/istio-system/sa/istio-ingressgateway-public-3-service-account",
						"cluster.local/ns/" + c.fmtn.Namespace + "/sa/" + c.fmtn.Namespace,
					},
				},
			},
		},
	}
	policyName := c.fmtn.Name + "-blockothers"
	authorizationPolicy := &v1betaSecurityClient.AuthorizationPolicy{
		ObjectMeta: metav1.ObjectMeta{
			Name:            policyName,
			Namespace:       c.fmtn.Namespace,
			OwnerReferences: []metav1.OwnerReference{kubemeta.NewFormationOwnerReference(c.fmtn)},
		},
		Spec: v1betaSecurityAPI.AuthorizationPolicy{
			// problem: the Allow action is not written to the K8s !!! a problem defect with istio go client ?!
			Action: v1betaSecurityAPI.AuthorizationPolicy_ALLOW,
			Selector: &selectorType.WorkloadSelector{
				MatchLabels: map[string]string{
					"formation_id": c.fmtn.Name,
				},
			},
			Rules:  []*v1betaSecurityAPI.Rule{&allowIncomingTrafficRuleFromTheseSA},
		},
	}
	_, err := icdClient.Istio().Istio().Clientsets().SecurityV1beta1().AuthorizationPolicies(c.fmtn.Namespace).Create(authorizationPolicy)

I then follow the flow (debugged) into K8s client, got into authorizationpolicy.gen.go#func (c *authorizationPolicies) Create(authorizationPolicy *v1beta1.AuthorizationPolicy) and then into K8s Request.go# Body(obj interface{}) and I see this serialized object:

{"kind":"AuthorizationPolicy","apiVersion":"security.istio.io/v1beta1","metadata":{"name":"7bac2dcf-9f77-4063-af3f-5c9836b8fbe6-blockothers","namespace":"823edda102129f3232a0dc06556d5abd","creationTimestamp":null,"ownerReferences":[{"apiVersion":"crd.compose.com/v1","kind":"Formation","name":"7bac2dcf-9f77-4063-af3f-5c9836b8fbe6","uid":"1d01feae-2ad4-4e74-8e9a-5f89b71d18de"}]},"spec":{"selector":{"matchLabels":{"formation_id":"7bac2dcf-9f77-4063-af3f-5c9836b8fbe6"}},"rules":[{"from":[{"source":{"principals":["cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account","cluster.local/ns/istio-system/sa/istio-ingressgateway-public-2-service-account","cluster.local/ns/istio-system/sa/istio-ingressgateway-public-3-service-account","cluster.local/ns/823edda102129f3232a0dc06556d5abd/sa/823edda102129f3232a0dc06556d5abd"]}}]}]}}

I verified that till that point the Go object does contain the Action field in the spec section and it is 0. after serialization, as you can see, Action is missing.

go.mod uses:

k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
istio.io/api v0.0.0-20200513175333-ae3da0d240e3
istio.io/client-go v0.0.0-20200513180646-f8d9d8ff84e6

here is the output:

$ kubectl get authorizationpolicy -n 823edda102129f3232a0dc06556d5abd  7bac2dcf-9f77-4063-af3f-5c9836b8fbe6-blockothers -o yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  creationTimestamp: "2020-09-01T02:23:02Z"
  generation: 1
  name: 7bac2dcf-9f77-4063-af3f-5c9836b8fbe6-blockothers
  namespace: 823edda102129f3232a0dc06556d5abd
  ownerReferences:
  - apiVersion: crd.compose.com/v1
    kind: Formation
    name: 7bac2dcf-9f77-4063-af3f-5c9836b8fbe6
    uid: 1d01feae-2ad4-4e74-8e9a-5f89b71d18de
  resourceVersion: "28470283"
  selfLink: /apis/security.istio.io/v1beta1/namespaces/823edda102129f3232a0dc06556d5abd/authorizationpolicies/7bac2dcf-9f77-4063-af3f-5c9836b8fbe6-blockothers
  uid: 4fb44926-f7bf-48e7-9e15-3af5c63fd0ae
spec:
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account
        - cluster.local/ns/istio-system/sa/istio-ingressgateway-public-2-service-account
        - cluster.local/ns/istio-system/sa/istio-ingressgateway-public-3-service-account
        - cluster.local/ns/823edda102129f3232a0dc06556d5abd/sa/823edda102129f3232a0dc06556d5abd
  selector:
    matchLabels:
      formation_id: 7bac2dcf-9f77-4063-af3f-5c9836b8fbe6

of course , if I write a manual yaml file with similar action , all behaves well. so it is a golang issue. bare in mind: if I just change the Action to AuthorizationPolicy_DENY : all is serialized as expected. so it seems that using 0 int32 for ALLOW will omit that field

is that a old/fixed bug ?

taitelman avatar Sep 01 '20 02:09 taitelman

Similar to #1178

hzxuzhonghu avatar Sep 02 '20 03:09 hzxuzhonghu

Similar issue. If use istio-client to get the AuthorizationPolicy object, the AuthorizationPolicy_ALLOW will be omitted when marshal to json. But if call directly to kube-apiserver that will get the correct json. How to fix it?

foshantiger avatar May 26 '21 04:05 foshantiger

There is no fix; skipping it is the intended behavior of serialization of a zero value. It was unfortunate we made valid enums 0 instead of UNSPECIFIED, but we cannot change due to compatibility

howardjohn avatar May 14 '24 22:05 howardjohn