diff --git a/clients/go/msd/client.go b/clients/go/msd/client.go index a9c6598401d..5bce82d6c63 100644 --- a/clients/go/msd/client.go +++ b/clients/go/msd/client.go @@ -777,6 +777,48 @@ func (client MSDClient) EvaluateNetworkPolicyChange(detail *NetworkPolicyChangeI } } +func (client MSDClient) PostKubernetesNetworkPolicyRequest(domainName DomainName, serviceName EntityName, request *KubernetesNetworkPolicyRequest, matchingTag string) (*KubernetesNetworkPolicyResponse, string, error) { + var data *KubernetesNetworkPolicyResponse + headers := map[string]string{ + "If-None-Match": matchingTag, + } + url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/kubernetesnetworkpolicy" + contentBytes, err := json.Marshal(request) + if err != nil { + return nil, "", err + } + resp, err := client.httpPost(url, headers, contentBytes) + if err != nil { + return nil, "", err + } + defer resp.Body.Close() + switch resp.StatusCode { + case 200, 304: + if 304 != resp.StatusCode { + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + return nil, "", err + } + } + tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag")) + return data, tag, nil + default: + var errobj rdl.ResourceError + contentBytes, err = io.ReadAll(resp.Body) + if err != nil { + return nil, "", err + } + json.Unmarshal(contentBytes, &errobj) + if errobj.Code == 0 { + errobj.Code = resp.StatusCode + } + if errobj.Message == "" { + errobj.Message = string(contentBytes) + } + return nil, "", errobj + } +} + func (client MSDClient) GetRdlSchema() (*rdl.Schema, error) { var data *rdl.Schema url := client.URL + "/schema" diff --git a/clients/go/msd/model.go b/clients/go/msd/model.go index 9c38cf805e6..e3f3a45cad7 100644 --- a/clients/go/msd/model.go +++ b/clients/go/msd/model.go @@ -2056,7 +2056,7 @@ func (self *BulkWorkloadResponse) Validate() error { } // NetworkPolicyChangeEffect - IMPACT indicates that a change in network policy -// will interfere with workings of one or more transport policies NO_IMAPCT +// will interfere with workings of one or more transport policies NO_IMPACT // indicates that a change in network policy will not interfere with workings of // any transport policy type NetworkPolicyChangeEffect int @@ -2474,3 +2474,637 @@ func (self *NetworkPolicyChangeImpactResponse) UnmarshalJSON(b []byte) error { func (self *NetworkPolicyChangeImpactResponse) Validate() error { return nil } + +// KubernetesLabelSelectorRequirement - A label selector requirement is a +// selector that contains values, a key, and an operator that relates the key +// and values. +type KubernetesLabelSelectorRequirement struct { + + // + // Label key that the selector applies to + // + Key string `json:"key"` + + // + // Operator that is applied to the key. Valid operators are In, NotIn, Exists + // and DoesNotExist. + // + Operator string `json:"operator"` + + // + // 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. + // + Values []string `json:"values,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesLabelSelectorRequirement - creates an initialized KubernetesLabelSelectorRequirement instance, returns a pointer to it +func NewKubernetesLabelSelectorRequirement(init ...*KubernetesLabelSelectorRequirement) *KubernetesLabelSelectorRequirement { + var o *KubernetesLabelSelectorRequirement + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesLabelSelectorRequirement) + } + return o +} + +type rawKubernetesLabelSelectorRequirement KubernetesLabelSelectorRequirement + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesLabelSelectorRequirement +func (self *KubernetesLabelSelectorRequirement) UnmarshalJSON(b []byte) error { + var m rawKubernetesLabelSelectorRequirement + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesLabelSelectorRequirement(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesLabelSelectorRequirement) Validate() error { + if self.Key == "" { + return fmt.Errorf("KubernetesLabelSelectorRequirement.key is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.Key) + if !val.Valid { + return fmt.Errorf("KubernetesLabelSelectorRequirement.key does not contain a valid String (%v)", val.Error) + } + } + if self.Operator == "" { + return fmt.Errorf("KubernetesLabelSelectorRequirement.operator is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.Operator) + if !val.Valid { + return fmt.Errorf("KubernetesLabelSelectorRequirement.operator does not contain a valid String (%v)", val.Error) + } + } + return nil +} + +// KubernetesLabelSelector - 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. +type KubernetesLabelSelector struct { + + // + // Array of label selector requirements. The requirements are ANDed. + // + MatchExpressions []*KubernetesLabelSelectorRequirement `json:"matchExpressions"` + + // + // Map of label key/value pairs + // + MatchLabels map[string]string `json:"matchLabels"` +} + +// NewKubernetesLabelSelector - creates an initialized KubernetesLabelSelector instance, returns a pointer to it +func NewKubernetesLabelSelector(init ...*KubernetesLabelSelector) *KubernetesLabelSelector { + var o *KubernetesLabelSelector + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesLabelSelector) + } + return o.Init() +} + +// Init - sets up the instance according to its default field values, if any +func (self *KubernetesLabelSelector) Init() *KubernetesLabelSelector { + if self.MatchExpressions == nil { + self.MatchExpressions = make([]*KubernetesLabelSelectorRequirement, 0) + } + if self.MatchLabels == nil { + self.MatchLabels = make(map[string]string) + } + return self +} + +type rawKubernetesLabelSelector KubernetesLabelSelector + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesLabelSelector +func (self *KubernetesLabelSelector) UnmarshalJSON(b []byte) error { + var m rawKubernetesLabelSelector + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesLabelSelector(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesLabelSelector) Validate() error { + if self.MatchExpressions == nil { + return fmt.Errorf("KubernetesLabelSelector: Missing required field: matchExpressions") + } + if self.MatchLabels == nil { + return fmt.Errorf("KubernetesLabelSelector: Missing required field: matchLabels") + } + return nil +} + +// KubernetesNetworkPolicyPort - Kubernetes network policy port range +type KubernetesNetworkPolicyPort struct { + + // + // Start port of the port range. port and endPort will have same values for a + // single port definition. + // + Port int32 `json:"port"` + + // + // End port of the port range. port and endPort will have same values for a + // single port definition. + // + EndPort int32 `json:"endPort"` + + // + // Network policy protocol. Allowed values: TCP, UDP. + // + Protocol TransportPolicyProtocol `json:"protocol"` +} + +// NewKubernetesNetworkPolicyPort - creates an initialized KubernetesNetworkPolicyPort instance, returns a pointer to it +func NewKubernetesNetworkPolicyPort(init ...*KubernetesNetworkPolicyPort) *KubernetesNetworkPolicyPort { + var o *KubernetesNetworkPolicyPort + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyPort) + } + return o +} + +type rawKubernetesNetworkPolicyPort KubernetesNetworkPolicyPort + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyPort +func (self *KubernetesNetworkPolicyPort) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyPort + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyPort(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyPort) Validate() error { + return nil +} + +// KubernetesIPBlock - Kubernetes network policy IP block source/target +type KubernetesIPBlock struct { + + // + // CIDR block representing IP range for source/target + // + Cidr string `json:"cidr"` + + // + // Exception for CIDR blocks, if needed + // + Except []string `json:"except,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesIPBlock - creates an initialized KubernetesIPBlock instance, returns a pointer to it +func NewKubernetesIPBlock(init ...*KubernetesIPBlock) *KubernetesIPBlock { + var o *KubernetesIPBlock + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesIPBlock) + } + return o +} + +type rawKubernetesIPBlock KubernetesIPBlock + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesIPBlock +func (self *KubernetesIPBlock) UnmarshalJSON(b []byte) error { + var m rawKubernetesIPBlock + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesIPBlock(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesIPBlock) Validate() error { + if self.Cidr == "" { + return fmt.Errorf("KubernetesIPBlock.cidr is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.Cidr) + if !val.Valid { + return fmt.Errorf("KubernetesIPBlock.cidr does not contain a valid String (%v)", val.Error) + } + } + return nil +} + +// KubernetesNetworkPolicyPeer - Kubernetes network policy peer (source/target) +type KubernetesNetworkPolicyPeer struct { + + // + // Kubernetes pod selector for the network policy source/target + // + PodSelector *KubernetesLabelSelector `json:"podSelector,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // Kubernetes namespace selector for the network policy source/target + // + NamespaceSelector *KubernetesLabelSelector `json:"namespaceSelector,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // IP block for the network policy source/target + // + IpBlock *KubernetesIPBlock `json:"ipBlock,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesNetworkPolicyPeer - creates an initialized KubernetesNetworkPolicyPeer instance, returns a pointer to it +func NewKubernetesNetworkPolicyPeer(init ...*KubernetesNetworkPolicyPeer) *KubernetesNetworkPolicyPeer { + var o *KubernetesNetworkPolicyPeer + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyPeer) + } + return o +} + +type rawKubernetesNetworkPolicyPeer KubernetesNetworkPolicyPeer + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyPeer +func (self *KubernetesNetworkPolicyPeer) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyPeer + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyPeer(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyPeer) Validate() error { + return nil +} + +// KubernetesNetworkPolicyIngressRule - Kubernetes network policy ingress rule +type KubernetesNetworkPolicyIngressRule struct { + + // + // Network policy source, when empty all sources are allowed + // + From []*KubernetesNetworkPolicyPeer `json:"from,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // Ingress port(s), when empty all ports are allowed + // + Ports []*KubernetesNetworkPolicyPort `json:"ports,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesNetworkPolicyIngressRule - creates an initialized KubernetesNetworkPolicyIngressRule instance, returns a pointer to it +func NewKubernetesNetworkPolicyIngressRule(init ...*KubernetesNetworkPolicyIngressRule) *KubernetesNetworkPolicyIngressRule { + var o *KubernetesNetworkPolicyIngressRule + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyIngressRule) + } + return o +} + +type rawKubernetesNetworkPolicyIngressRule KubernetesNetworkPolicyIngressRule + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyIngressRule +func (self *KubernetesNetworkPolicyIngressRule) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyIngressRule + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyIngressRule(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyIngressRule) Validate() error { + return nil +} + +// KubernetesNetworkPolicyEgressRule - Kubernetes network policy egress rule +type KubernetesNetworkPolicyEgressRule struct { + + // + // Network policy target, when empty all sources are allowed + // + To []*KubernetesNetworkPolicyPeer `json:"to,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // Egress port(s), when empty all ports are allowed + // + Ports []*KubernetesNetworkPolicyPort `json:"ports,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesNetworkPolicyEgressRule - creates an initialized KubernetesNetworkPolicyEgressRule instance, returns a pointer to it +func NewKubernetesNetworkPolicyEgressRule(init ...*KubernetesNetworkPolicyEgressRule) *KubernetesNetworkPolicyEgressRule { + var o *KubernetesNetworkPolicyEgressRule + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyEgressRule) + } + return o +} + +type rawKubernetesNetworkPolicyEgressRule KubernetesNetworkPolicyEgressRule + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyEgressRule +func (self *KubernetesNetworkPolicyEgressRule) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyEgressRule + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyEgressRule(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyEgressRule) Validate() error { + return nil +} + +// KubernetesNetworkPolicySpec - Kubernetes network policy spec +type KubernetesNetworkPolicySpec struct { + + // + // Kubernetes pod selector for the network policy target + // + PodSelector *KubernetesLabelSelector `json:"podSelector"` + + // + // Network policy types - Ingress, Egress + // + PolicyTypes []string `json:"policyTypes"` + + // + // Ingress network policy rules, if empty then all ingress traffic is blocked + // + Ingress []*KubernetesNetworkPolicyIngressRule `json:"ingress,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // Egress network policy rules, if empty then all egress traffic is blocked + // + Egress []*KubernetesNetworkPolicyEgressRule `json:"egress,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesNetworkPolicySpec - creates an initialized KubernetesNetworkPolicySpec instance, returns a pointer to it +func NewKubernetesNetworkPolicySpec(init ...*KubernetesNetworkPolicySpec) *KubernetesNetworkPolicySpec { + var o *KubernetesNetworkPolicySpec + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicySpec) + } + return o.Init() +} + +// Init - sets up the instance according to its default field values, if any +func (self *KubernetesNetworkPolicySpec) Init() *KubernetesNetworkPolicySpec { + if self.PodSelector == nil { + self.PodSelector = NewKubernetesLabelSelector() + } + if self.PolicyTypes == nil { + self.PolicyTypes = make([]string, 0) + } + return self +} + +type rawKubernetesNetworkPolicySpec KubernetesNetworkPolicySpec + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicySpec +func (self *KubernetesNetworkPolicySpec) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicySpec + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicySpec(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicySpec) Validate() error { + if self.PodSelector == nil { + return fmt.Errorf("KubernetesNetworkPolicySpec: Missing required field: podSelector") + } + if self.PolicyTypes == nil { + return fmt.Errorf("KubernetesNetworkPolicySpec: Missing required field: policyTypes") + } + return nil +} + +// KubernetesNetworkPolicyRequest - Request object containing Kubernetes +// network policy inputs +type KubernetesNetworkPolicyRequest struct { + + // + // Label key name used on pods to identify Athenz domain + // + AthenzDomainLabel string `json:"athenzDomainLabel" rdl:"optional" yaml:",omitempty"` + + // + // Label key name used on pods to identify Athenz service + // + AthenzServiceLabel string `json:"athenzServiceLabel"` + + // + // Network policy type, default is vanilla Kubernetes + // + NetworkPolicyType string `json:"networkPolicyType" rdl:"optional" yaml:",omitempty"` + + // + // Requested network policy apiVersion + // + RequestedApiVersion string `json:"requestedApiVersion" rdl:"optional" yaml:",omitempty"` + + // + // Kubernetes namespace for the network policy object + // + NetworkPolicyNamespace string `json:"networkPolicyNamespace" rdl:"optional" yaml:",omitempty"` + + // + // Use athenzDomainLabel as namespace selector + // + DomainLabelAsNamespaceSelector *bool `json:"domainLabelAsNamespaceSelector,omitempty" rdl:"optional" yaml:",omitempty"` + + // + // Use Athenz domain name in service label + // + DomainInServiceLabel *bool `json:"domainInServiceLabel,omitempty" rdl:"optional" yaml:",omitempty"` +} + +// NewKubernetesNetworkPolicyRequest - creates an initialized KubernetesNetworkPolicyRequest instance, returns a pointer to it +func NewKubernetesNetworkPolicyRequest(init ...*KubernetesNetworkPolicyRequest) *KubernetesNetworkPolicyRequest { + var o *KubernetesNetworkPolicyRequest + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyRequest) + } + return o +} + +type rawKubernetesNetworkPolicyRequest KubernetesNetworkPolicyRequest + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyRequest +func (self *KubernetesNetworkPolicyRequest) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyRequest + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyRequest(m) + *self = o + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyRequest) Validate() error { + if self.AthenzDomainLabel != "" { + val := rdl.Validate(MSDSchema(), "String", self.AthenzDomainLabel) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyRequest.athenzDomainLabel does not contain a valid String (%v)", val.Error) + } + } + if self.AthenzServiceLabel == "" { + return fmt.Errorf("KubernetesNetworkPolicyRequest.athenzServiceLabel is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.AthenzServiceLabel) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyRequest.athenzServiceLabel does not contain a valid String (%v)", val.Error) + } + } + if self.NetworkPolicyType != "" { + val := rdl.Validate(MSDSchema(), "String", self.NetworkPolicyType) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyRequest.networkPolicyType does not contain a valid String (%v)", val.Error) + } + } + if self.RequestedApiVersion != "" { + val := rdl.Validate(MSDSchema(), "String", self.RequestedApiVersion) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyRequest.requestedApiVersion does not contain a valid String (%v)", val.Error) + } + } + if self.NetworkPolicyNamespace != "" { + val := rdl.Validate(MSDSchema(), "String", self.NetworkPolicyNamespace) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyRequest.networkPolicyNamespace does not contain a valid String (%v)", val.Error) + } + } + return nil +} + +// KubernetesNetworkPolicyResponse - Response object containing Kubernetes +// network policy +type KubernetesNetworkPolicyResponse struct { + + // + // Kubernetes network policy apiVersion + // + ApiVersion string `json:"apiVersion"` + + // + // Kubernetes network policy kind + // + Kind string `json:"kind"` + + // + // Kubernetes network policy metadata + // + Metadata map[string]string `json:"metadata"` + + // + // Kubernetes network policy spec + // + Spec *KubernetesNetworkPolicySpec `json:"spec"` +} + +// NewKubernetesNetworkPolicyResponse - creates an initialized KubernetesNetworkPolicyResponse instance, returns a pointer to it +func NewKubernetesNetworkPolicyResponse(init ...*KubernetesNetworkPolicyResponse) *KubernetesNetworkPolicyResponse { + var o *KubernetesNetworkPolicyResponse + if len(init) == 1 { + o = init[0] + } else { + o = new(KubernetesNetworkPolicyResponse) + } + return o.Init() +} + +// Init - sets up the instance according to its default field values, if any +func (self *KubernetesNetworkPolicyResponse) Init() *KubernetesNetworkPolicyResponse { + if self.Metadata == nil { + self.Metadata = make(map[string]string) + } + if self.Spec == nil { + self.Spec = NewKubernetesNetworkPolicySpec() + } + return self +} + +type rawKubernetesNetworkPolicyResponse KubernetesNetworkPolicyResponse + +// UnmarshalJSON is defined for proper JSON decoding of a KubernetesNetworkPolicyResponse +func (self *KubernetesNetworkPolicyResponse) UnmarshalJSON(b []byte) error { + var m rawKubernetesNetworkPolicyResponse + err := json.Unmarshal(b, &m) + if err == nil { + o := KubernetesNetworkPolicyResponse(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// Validate - checks for missing required fields, etc +func (self *KubernetesNetworkPolicyResponse) Validate() error { + if self.ApiVersion == "" { + return fmt.Errorf("KubernetesNetworkPolicyResponse.apiVersion is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.ApiVersion) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyResponse.apiVersion does not contain a valid String (%v)", val.Error) + } + } + if self.Kind == "" { + return fmt.Errorf("KubernetesNetworkPolicyResponse.kind is missing but is a required field") + } else { + val := rdl.Validate(MSDSchema(), "String", self.Kind) + if !val.Valid { + return fmt.Errorf("KubernetesNetworkPolicyResponse.kind does not contain a valid String (%v)", val.Error) + } + } + if self.Metadata == nil { + return fmt.Errorf("KubernetesNetworkPolicyResponse: Missing required field: metadata") + } + if self.Spec == nil { + return fmt.Errorf("KubernetesNetworkPolicyResponse: Missing required field: spec") + } + return nil +} diff --git a/clients/go/msd/msd_schema.go b/clients/go/msd/msd_schema.go index be5f7c49855..66a3a492b77 100644 --- a/clients/go/msd/msd_schema.go +++ b/clients/go/msd/msd_schema.go @@ -300,7 +300,7 @@ func init() { sb.AddType(tBulkWorkloadResponse.Build()) tNetworkPolicyChangeEffect := rdl.NewEnumTypeBuilder("Enum", "NetworkPolicyChangeEffect") - tNetworkPolicyChangeEffect.Comment("IMPACT indicates that a change in network policy will interfere with workings of one or more transport policies NO_IMAPCT indicates that a change in network policy will not interfere with workings of any transport policy") + tNetworkPolicyChangeEffect.Comment("IMPACT indicates that a change in network policy will interfere with workings of one or more transport policies NO_IMPACT indicates that a change in network policy will not interfere with workings of any transport policy") tNetworkPolicyChangeEffect.Element("IMPACT", "") tNetworkPolicyChangeEffect.Element("NO_IMPACT", "") sb.AddType(tNetworkPolicyChangeEffect.Build()) @@ -340,6 +340,76 @@ func init() { tNetworkPolicyChangeImpactResponse.ArrayField("details", "NetworkPolicyChangeImpactDetail", true, "if the above enum value is IMPACT then this optional object contains more details about the impacted transport policies") sb.AddType(tNetworkPolicyChangeImpactResponse.Build()) + tKubernetesLabelSelectorRequirement := rdl.NewStructTypeBuilder("Struct", "KubernetesLabelSelectorRequirement") + tKubernetesLabelSelectorRequirement.Comment("A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.") + tKubernetesLabelSelectorRequirement.Field("key", "String", false, nil, "Label key that the selector applies to") + tKubernetesLabelSelectorRequirement.Field("operator", "String", false, nil, "Operator that is applied to the key. Valid operators are In, NotIn, Exists and DoesNotExist.") + tKubernetesLabelSelectorRequirement.ArrayField("values", "String", true, "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.") + sb.AddType(tKubernetesLabelSelectorRequirement.Build()) + + tKubernetesLabelSelector := rdl.NewStructTypeBuilder("Struct", "KubernetesLabelSelector") + tKubernetesLabelSelector.Comment("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.") + tKubernetesLabelSelector.ArrayField("matchExpressions", "KubernetesLabelSelectorRequirement", false, "Array of label selector requirements. The requirements are ANDed.") + tKubernetesLabelSelector.MapField("matchLabels", "String", "String", false, "Map of label key/value pairs") + sb.AddType(tKubernetesLabelSelector.Build()) + + tKubernetesNetworkPolicyPort := rdl.NewStructTypeBuilder("PolicyPort", "KubernetesNetworkPolicyPort") + tKubernetesNetworkPolicyPort.Comment("Kubernetes network policy port range") + tKubernetesNetworkPolicyPort.Field("protocol", "TransportPolicyProtocol", false, nil, "Network policy protocol. Allowed values: TCP, UDP.") + sb.AddType(tKubernetesNetworkPolicyPort.Build()) + + tKubernetesIPBlock := rdl.NewStructTypeBuilder("Struct", "KubernetesIPBlock") + tKubernetesIPBlock.Comment("Kubernetes network policy IP block source/target") + tKubernetesIPBlock.Field("cidr", "String", false, nil, "CIDR block representing IP range for source/target") + tKubernetesIPBlock.ArrayField("except", "String", true, "Exception for CIDR blocks, if needed") + sb.AddType(tKubernetesIPBlock.Build()) + + tKubernetesNetworkPolicyPeer := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicyPeer") + tKubernetesNetworkPolicyPeer.Comment("Kubernetes network policy peer (source/target)") + tKubernetesNetworkPolicyPeer.Field("podSelector", "KubernetesLabelSelector", true, nil, "Kubernetes pod selector for the network policy source/target") + tKubernetesNetworkPolicyPeer.Field("namespaceSelector", "KubernetesLabelSelector", true, nil, "Kubernetes namespace selector for the network policy source/target") + tKubernetesNetworkPolicyPeer.Field("ipBlock", "KubernetesIPBlock", true, nil, "IP block for the network policy source/target") + sb.AddType(tKubernetesNetworkPolicyPeer.Build()) + + tKubernetesNetworkPolicyIngressRule := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicyIngressRule") + tKubernetesNetworkPolicyIngressRule.Comment("Kubernetes network policy ingress rule") + tKubernetesNetworkPolicyIngressRule.ArrayField("from", "KubernetesNetworkPolicyPeer", true, "Network policy source, when empty all sources are allowed") + tKubernetesNetworkPolicyIngressRule.ArrayField("ports", "KubernetesNetworkPolicyPort", true, "Ingress port(s), when empty all ports are allowed") + sb.AddType(tKubernetesNetworkPolicyIngressRule.Build()) + + tKubernetesNetworkPolicyEgressRule := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicyEgressRule") + tKubernetesNetworkPolicyEgressRule.Comment("Kubernetes network policy egress rule") + tKubernetesNetworkPolicyEgressRule.ArrayField("to", "KubernetesNetworkPolicyPeer", true, "Network policy target, when empty all sources are allowed") + tKubernetesNetworkPolicyEgressRule.ArrayField("ports", "KubernetesNetworkPolicyPort", true, "Egress port(s), when empty all ports are allowed") + sb.AddType(tKubernetesNetworkPolicyEgressRule.Build()) + + tKubernetesNetworkPolicySpec := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicySpec") + tKubernetesNetworkPolicySpec.Comment("Kubernetes network policy spec") + tKubernetesNetworkPolicySpec.Field("podSelector", "KubernetesLabelSelector", false, nil, "Kubernetes pod selector for the network policy target") + tKubernetesNetworkPolicySpec.ArrayField("policyTypes", "String", false, "Network policy types - Ingress, Egress") + tKubernetesNetworkPolicySpec.ArrayField("ingress", "KubernetesNetworkPolicyIngressRule", true, "Ingress network policy rules, if empty then all ingress traffic is blocked") + tKubernetesNetworkPolicySpec.ArrayField("egress", "KubernetesNetworkPolicyEgressRule", true, "Egress network policy rules, if empty then all egress traffic is blocked") + sb.AddType(tKubernetesNetworkPolicySpec.Build()) + + tKubernetesNetworkPolicyRequest := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicyRequest") + tKubernetesNetworkPolicyRequest.Comment("Request object containing Kubernetes network policy inputs") + tKubernetesNetworkPolicyRequest.Field("athenzDomainLabel", "String", true, nil, "Label key name used on pods to identify Athenz domain") + tKubernetesNetworkPolicyRequest.Field("athenzServiceLabel", "String", false, nil, "Label key name used on pods to identify Athenz service") + tKubernetesNetworkPolicyRequest.Field("networkPolicyType", "String", true, nil, "Network policy type, default is vanilla Kubernetes") + tKubernetesNetworkPolicyRequest.Field("requestedApiVersion", "String", true, nil, "Requested network policy apiVersion") + tKubernetesNetworkPolicyRequest.Field("networkPolicyNamespace", "String", true, nil, "Kubernetes namespace for the network policy object") + tKubernetesNetworkPolicyRequest.Field("domainLabelAsNamespaceSelector", "Bool", true, false, "Use athenzDomainLabel as namespace selector") + tKubernetesNetworkPolicyRequest.Field("domainInServiceLabel", "Bool", true, false, "Use Athenz domain name in service label") + sb.AddType(tKubernetesNetworkPolicyRequest.Build()) + + tKubernetesNetworkPolicyResponse := rdl.NewStructTypeBuilder("Struct", "KubernetesNetworkPolicyResponse") + tKubernetesNetworkPolicyResponse.Comment("Response object containing Kubernetes network policy") + tKubernetesNetworkPolicyResponse.Field("apiVersion", "String", false, nil, "Kubernetes network policy apiVersion") + tKubernetesNetworkPolicyResponse.Field("kind", "String", false, nil, "Kubernetes network policy kind") + tKubernetesNetworkPolicyResponse.MapField("metadata", "String", "String", false, "Kubernetes network policy metadata") + tKubernetesNetworkPolicyResponse.Field("spec", "KubernetesNetworkPolicySpec", false, nil, "Kubernetes network policy spec") + sb.AddType(tKubernetesNetworkPolicyResponse.Build()) + tRdl_Identifier := rdl.NewStringTypeBuilder("rdl.Identifier") tRdl_Identifier.Comment("All names need to be of this restricted string type") tRdl_Identifier.Pattern("[a-zA-Z_]+[a-zA-Z_0-9]*") @@ -753,6 +823,21 @@ func init() { mEvaluateNetworkPolicyChange.Exception("UNAUTHORIZED", "ResourceError", "") sb.AddResource(mEvaluateNetworkPolicyChange.Build()) + mPostKubernetesNetworkPolicyRequest := rdl.NewResourceBuilder("KubernetesNetworkPolicyResponse", "POST", "/domain/{domainName}/service/{serviceName}/kubernetesnetworkpolicy") + mPostKubernetesNetworkPolicyRequest.Comment("API endpoint to get the Kubernetes network policy converted from the corresponding MSD policy") + mPostKubernetesNetworkPolicyRequest.Input("domainName", "DomainName", true, "", "", false, nil, "Name of the domain") + mPostKubernetesNetworkPolicyRequest.Input("serviceName", "EntityName", true, "", "", false, nil, "Name of the service") + mPostKubernetesNetworkPolicyRequest.Input("request", "KubernetesNetworkPolicyRequest", false, "", "", false, nil, "Struct representing input options based on the cluster context") + mPostKubernetesNetworkPolicyRequest.Input("matchingTag", "String", false, "", "If-None-Match", false, nil, "Retrieved from the previous request, this timestamp specifies to the server to return any policies modified since this time") + mPostKubernetesNetworkPolicyRequest.Output("tag", "String", "ETag", false, "The current latest modification timestamp is returned in this header") + mPostKubernetesNetworkPolicyRequest.Auth("read", "{domain}:service.{service}", false, "") + mPostKubernetesNetworkPolicyRequest.Exception("BAD_REQUEST", "ResourceError", "") + mPostKubernetesNetworkPolicyRequest.Exception("FORBIDDEN", "ResourceError", "") + mPostKubernetesNetworkPolicyRequest.Exception("NOT_FOUND", "ResourceError", "") + mPostKubernetesNetworkPolicyRequest.Exception("TOO_MANY_REQUESTS", "ResourceError", "") + mPostKubernetesNetworkPolicyRequest.Exception("UNAUTHORIZED", "ResourceError", "") + sb.AddResource(mPostKubernetesNetworkPolicyRequest.Build()) + mGetRdlSchema := rdl.NewResourceBuilder("rdl.Schema", "GET", "/schema") mGetRdlSchema.Comment("Get RDL Schema") mGetRdlSchema.Auth("", "", true, "") diff --git a/clients/java/msd/src/main/java/com/yahoo/athenz/msd/MSDRDLGeneratedClient.java b/clients/java/msd/src/main/java/com/yahoo/athenz/msd/MSDRDLGeneratedClient.java index 74a71cd681c..cbdbfe7be4e 100644 --- a/clients/java/msd/src/main/java/com/yahoo/athenz/msd/MSDRDLGeneratedClient.java +++ b/clients/java/msd/src/main/java/com/yahoo/athenz/msd/MSDRDLGeneratedClient.java @@ -591,6 +591,47 @@ public NetworkPolicyChangeImpactResponse evaluateNetworkPolicyChange(NetworkPoli } } + public KubernetesNetworkPolicyResponse postKubernetesNetworkPolicyRequest(String domainName, String serviceName, KubernetesNetworkPolicyRequest request, String matchingTag, java.util.Map> headers) throws URISyntaxException, IOException { + UriTemplateBuilder uriTemplateBuilder = new UriTemplateBuilder(baseUrl, "/domain/{domainName}/service/{serviceName}/kubernetesnetworkpolicy") + .resolveTemplate("domainName", domainName) + .resolveTemplate("serviceName", serviceName); + URIBuilder uriBuilder = new URIBuilder(uriTemplateBuilder.getUri()); + HttpEntity httpEntity = new StringEntity(jsonMapper.writeValueAsString(request), ContentType.APPLICATION_JSON); + HttpUriRequest httpUriRequest = RequestBuilder.post() + .setUri(uriBuilder.build()) + .setEntity(httpEntity) + .build(); + if (credsHeader != null) { + httpUriRequest.addHeader(credsHeader, credsToken); + } + if (matchingTag != null) { + httpUriRequest.addHeader("If-None-Match", matchingTag); + } + HttpEntity httpResponseEntity = null; + try (CloseableHttpResponse httpResponse = client.execute(httpUriRequest, httpContext)) { + int code = httpResponse.getStatusLine().getStatusCode(); + httpResponseEntity = httpResponse.getEntity(); + switch (code) { + case 200: + case 304: + if (headers != null) { + headers.put("tag", List.of(httpResponse.getFirstHeader("ETag").getValue())); + } + if (code == 304) { + return null; + } + return jsonMapper.readValue(httpResponseEntity.getContent(), KubernetesNetworkPolicyResponse.class); + default: + final String errorData = (httpResponseEntity == null) ? null : EntityUtils.toString(httpResponseEntity); + throw (errorData != null && !errorData.isEmpty()) + ? new ResourceException(code, jsonMapper.readValue(errorData, ResourceError.class)) + : new ResourceException(code); + } + } finally { + EntityUtils.consumeQuietly(httpResponseEntity); + } + } + public Schema getRdlSchema() throws URISyntaxException, IOException { UriTemplateBuilder uriTemplateBuilder = new UriTemplateBuilder(baseUrl, "/schema"); URIBuilder uriBuilder = new URIBuilder(uriTemplateBuilder.getUri()); diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesIPBlock.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesIPBlock.java new file mode 100644 index 00000000000..a4632f688e6 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesIPBlock.java @@ -0,0 +1,52 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import com.yahoo.rdl.*; + +// +// KubernetesIPBlock - Kubernetes network policy IP block source/target +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesIPBlock { + public String cidr; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List except; + + public KubernetesIPBlock setCidr(String cidr) { + this.cidr = cidr; + return this; + } + public String getCidr() { + return cidr; + } + public KubernetesIPBlock setExcept(List except) { + this.except = except; + return this; + } + public List getExcept() { + return except; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesIPBlock.class) { + return false; + } + KubernetesIPBlock a = (KubernetesIPBlock) another; + if (cidr == null ? a.cidr != null : !cidr.equals(a.cidr)) { + return false; + } + if (except == null ? a.except != null : !except.equals(a.except)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelector.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelector.java new file mode 100644 index 00000000000..9388c43914d --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelector.java @@ -0,0 +1,52 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.List; +import java.util.Map; +import com.yahoo.rdl.*; + +// +// KubernetesLabelSelector - 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. +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesLabelSelector { + public List matchExpressions; + public Map matchLabels; + + public KubernetesLabelSelector setMatchExpressions(List matchExpressions) { + this.matchExpressions = matchExpressions; + return this; + } + public List getMatchExpressions() { + return matchExpressions; + } + public KubernetesLabelSelector setMatchLabels(Map matchLabels) { + this.matchLabels = matchLabels; + return this; + } + public Map getMatchLabels() { + return matchLabels; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesLabelSelector.class) { + return false; + } + KubernetesLabelSelector a = (KubernetesLabelSelector) another; + if (matchExpressions == null ? a.matchExpressions != null : !matchExpressions.equals(a.matchExpressions)) { + return false; + } + if (matchLabels == null ? a.matchLabels != null : !matchLabels.equals(a.matchLabels)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirement.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirement.java new file mode 100644 index 00000000000..4824a1bf9ed --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirement.java @@ -0,0 +1,65 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import com.yahoo.rdl.*; + +// +// KubernetesLabelSelectorRequirement - A label selector requirement is a +// selector that contains values, a key, and an operator that relates the key +// and values. +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesLabelSelectorRequirement { + public String key; + public String operator; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List values; + + public KubernetesLabelSelectorRequirement setKey(String key) { + this.key = key; + return this; + } + public String getKey() { + return key; + } + public KubernetesLabelSelectorRequirement setOperator(String operator) { + this.operator = operator; + return this; + } + public String getOperator() { + return operator; + } + public KubernetesLabelSelectorRequirement setValues(List values) { + this.values = values; + return this; + } + public List getValues() { + return values; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesLabelSelectorRequirement.class) { + return false; + } + KubernetesLabelSelectorRequirement a = (KubernetesLabelSelectorRequirement) another; + if (key == null ? a.key != null : !key.equals(a.key)) { + return false; + } + if (operator == null ? a.operator != null : !operator.equals(a.operator)) { + return false; + } + if (values == null ? a.values != null : !values.equals(a.values)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRule.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRule.java new file mode 100644 index 00000000000..33acef04c8c --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRule.java @@ -0,0 +1,54 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyEgressRule - Kubernetes network policy egress rule +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyEgressRule { + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List to; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List ports; + + public KubernetesNetworkPolicyEgressRule setTo(List to) { + this.to = to; + return this; + } + public List getTo() { + return to; + } + public KubernetesNetworkPolicyEgressRule setPorts(List ports) { + this.ports = ports; + return this; + } + public List getPorts() { + return ports; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyEgressRule.class) { + return false; + } + KubernetesNetworkPolicyEgressRule a = (KubernetesNetworkPolicyEgressRule) another; + if (to == null ? a.to != null : !to.equals(a.to)) { + return false; + } + if (ports == null ? a.ports != null : !ports.equals(a.ports)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRule.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRule.java new file mode 100644 index 00000000000..e47d677dd26 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRule.java @@ -0,0 +1,54 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyIngressRule - Kubernetes network policy ingress rule +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyIngressRule { + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List from; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List ports; + + public KubernetesNetworkPolicyIngressRule setFrom(List from) { + this.from = from; + return this; + } + public List getFrom() { + return from; + } + public KubernetesNetworkPolicyIngressRule setPorts(List ports) { + this.ports = ports; + return this; + } + public List getPorts() { + return ports; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyIngressRule.class) { + return false; + } + KubernetesNetworkPolicyIngressRule a = (KubernetesNetworkPolicyIngressRule) another; + if (from == null ? a.from != null : !from.equals(a.from)) { + return false; + } + if (ports == null ? a.ports != null : !ports.equals(a.ports)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeer.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeer.java new file mode 100644 index 00000000000..a0245523d18 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeer.java @@ -0,0 +1,66 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyPeer - Kubernetes network policy peer (source/target) +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyPeer { + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public KubernetesLabelSelector podSelector; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public KubernetesLabelSelector namespaceSelector; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public KubernetesIPBlock ipBlock; + + public KubernetesNetworkPolicyPeer setPodSelector(KubernetesLabelSelector podSelector) { + this.podSelector = podSelector; + return this; + } + public KubernetesLabelSelector getPodSelector() { + return podSelector; + } + public KubernetesNetworkPolicyPeer setNamespaceSelector(KubernetesLabelSelector namespaceSelector) { + this.namespaceSelector = namespaceSelector; + return this; + } + public KubernetesLabelSelector getNamespaceSelector() { + return namespaceSelector; + } + public KubernetesNetworkPolicyPeer setIpBlock(KubernetesIPBlock ipBlock) { + this.ipBlock = ipBlock; + return this; + } + public KubernetesIPBlock getIpBlock() { + return ipBlock; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyPeer.class) { + return false; + } + KubernetesNetworkPolicyPeer a = (KubernetesNetworkPolicyPeer) another; + if (podSelector == null ? a.podSelector != null : !podSelector.equals(a.podSelector)) { + return false; + } + if (namespaceSelector == null ? a.namespaceSelector != null : !namespaceSelector.equals(a.namespaceSelector)) { + return false; + } + if (ipBlock == null ? a.ipBlock != null : !ipBlock.equals(a.ipBlock)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPort.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPort.java new file mode 100644 index 00000000000..06cd2bb7ba2 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPort.java @@ -0,0 +1,59 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyPort - Kubernetes network policy port range +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyPort { + public int port; + public int endPort; + public TransportPolicyProtocol protocol; + + public KubernetesNetworkPolicyPort setPort(int port) { + this.port = port; + return this; + } + public int getPort() { + return port; + } + public KubernetesNetworkPolicyPort setEndPort(int endPort) { + this.endPort = endPort; + return this; + } + public int getEndPort() { + return endPort; + } + public KubernetesNetworkPolicyPort setProtocol(TransportPolicyProtocol protocol) { + this.protocol = protocol; + return this; + } + public TransportPolicyProtocol getProtocol() { + return protocol; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyPort.class) { + return false; + } + KubernetesNetworkPolicyPort a = (KubernetesNetworkPolicyPort) another; + if (port != a.port) { + return false; + } + if (endPort != a.endPort) { + return false; + } + if (protocol == null ? a.protocol != null : !protocol.equals(a.protocol)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequest.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequest.java new file mode 100644 index 00000000000..d2680d74d30 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequest.java @@ -0,0 +1,117 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyRequest - Request object containing Kubernetes +// network policy inputs +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyRequest { + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public String athenzDomainLabel; + public String athenzServiceLabel; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public String networkPolicyType; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public String requestedApiVersion; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public String networkPolicyNamespace; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public Boolean domainLabelAsNamespaceSelector; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public Boolean domainInServiceLabel; + + public KubernetesNetworkPolicyRequest setAthenzDomainLabel(String athenzDomainLabel) { + this.athenzDomainLabel = athenzDomainLabel; + return this; + } + public String getAthenzDomainLabel() { + return athenzDomainLabel; + } + public KubernetesNetworkPolicyRequest setAthenzServiceLabel(String athenzServiceLabel) { + this.athenzServiceLabel = athenzServiceLabel; + return this; + } + public String getAthenzServiceLabel() { + return athenzServiceLabel; + } + public KubernetesNetworkPolicyRequest setNetworkPolicyType(String networkPolicyType) { + this.networkPolicyType = networkPolicyType; + return this; + } + public String getNetworkPolicyType() { + return networkPolicyType; + } + public KubernetesNetworkPolicyRequest setRequestedApiVersion(String requestedApiVersion) { + this.requestedApiVersion = requestedApiVersion; + return this; + } + public String getRequestedApiVersion() { + return requestedApiVersion; + } + public KubernetesNetworkPolicyRequest setNetworkPolicyNamespace(String networkPolicyNamespace) { + this.networkPolicyNamespace = networkPolicyNamespace; + return this; + } + public String getNetworkPolicyNamespace() { + return networkPolicyNamespace; + } + public KubernetesNetworkPolicyRequest setDomainLabelAsNamespaceSelector(Boolean domainLabelAsNamespaceSelector) { + this.domainLabelAsNamespaceSelector = domainLabelAsNamespaceSelector; + return this; + } + public Boolean getDomainLabelAsNamespaceSelector() { + return domainLabelAsNamespaceSelector; + } + public KubernetesNetworkPolicyRequest setDomainInServiceLabel(Boolean domainInServiceLabel) { + this.domainInServiceLabel = domainInServiceLabel; + return this; + } + public Boolean getDomainInServiceLabel() { + return domainInServiceLabel; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyRequest.class) { + return false; + } + KubernetesNetworkPolicyRequest a = (KubernetesNetworkPolicyRequest) another; + if (athenzDomainLabel == null ? a.athenzDomainLabel != null : !athenzDomainLabel.equals(a.athenzDomainLabel)) { + return false; + } + if (athenzServiceLabel == null ? a.athenzServiceLabel != null : !athenzServiceLabel.equals(a.athenzServiceLabel)) { + return false; + } + if (networkPolicyType == null ? a.networkPolicyType != null : !networkPolicyType.equals(a.networkPolicyType)) { + return false; + } + if (requestedApiVersion == null ? a.requestedApiVersion != null : !requestedApiVersion.equals(a.requestedApiVersion)) { + return false; + } + if (networkPolicyNamespace == null ? a.networkPolicyNamespace != null : !networkPolicyNamespace.equals(a.networkPolicyNamespace)) { + return false; + } + if (domainLabelAsNamespaceSelector == null ? a.domainLabelAsNamespaceSelector != null : !domainLabelAsNamespaceSelector.equals(a.domainLabelAsNamespaceSelector)) { + return false; + } + if (domainInServiceLabel == null ? a.domainInServiceLabel != null : !domainInServiceLabel.equals(a.domainInServiceLabel)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponse.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponse.java new file mode 100644 index 00000000000..c80edee216e --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponse.java @@ -0,0 +1,72 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.Map; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicyResponse - Response object containing Kubernetes +// network policy +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicyResponse { + public String apiVersion; + public String kind; + public Map metadata; + public KubernetesNetworkPolicySpec spec; + + public KubernetesNetworkPolicyResponse setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + return this; + } + public String getApiVersion() { + return apiVersion; + } + public KubernetesNetworkPolicyResponse setKind(String kind) { + this.kind = kind; + return this; + } + public String getKind() { + return kind; + } + public KubernetesNetworkPolicyResponse setMetadata(Map metadata) { + this.metadata = metadata; + return this; + } + public Map getMetadata() { + return metadata; + } + public KubernetesNetworkPolicyResponse setSpec(KubernetesNetworkPolicySpec spec) { + this.spec = spec; + return this; + } + public KubernetesNetworkPolicySpec getSpec() { + return spec; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicyResponse.class) { + return false; + } + KubernetesNetworkPolicyResponse a = (KubernetesNetworkPolicyResponse) another; + if (apiVersion == null ? a.apiVersion != null : !apiVersion.equals(a.apiVersion)) { + return false; + } + if (kind == null ? a.kind != null : !kind.equals(a.kind)) { + return false; + } + if (metadata == null ? a.metadata != null : !metadata.equals(a.metadata)) { + return false; + } + if (spec == null ? a.spec != null : !spec.equals(a.spec)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpec.java b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpec.java new file mode 100644 index 00000000000..27e3c1c7b75 --- /dev/null +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpec.java @@ -0,0 +1,76 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.msd; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import com.yahoo.rdl.*; + +// +// KubernetesNetworkPolicySpec - Kubernetes network policy spec +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class KubernetesNetworkPolicySpec { + public KubernetesLabelSelector podSelector; + public List policyTypes; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List ingress; + @RdlOptional + @JsonInclude(JsonInclude.Include.NON_EMPTY) + public List egress; + + public KubernetesNetworkPolicySpec setPodSelector(KubernetesLabelSelector podSelector) { + this.podSelector = podSelector; + return this; + } + public KubernetesLabelSelector getPodSelector() { + return podSelector; + } + public KubernetesNetworkPolicySpec setPolicyTypes(List policyTypes) { + this.policyTypes = policyTypes; + return this; + } + public List getPolicyTypes() { + return policyTypes; + } + public KubernetesNetworkPolicySpec setIngress(List ingress) { + this.ingress = ingress; + return this; + } + public List getIngress() { + return ingress; + } + public KubernetesNetworkPolicySpec setEgress(List egress) { + this.egress = egress; + return this; + } + public List getEgress() { + return egress; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != KubernetesNetworkPolicySpec.class) { + return false; + } + KubernetesNetworkPolicySpec a = (KubernetesNetworkPolicySpec) another; + if (podSelector == null ? a.podSelector != null : !podSelector.equals(a.podSelector)) { + return false; + } + if (policyTypes == null ? a.policyTypes != null : !policyTypes.equals(a.policyTypes)) { + return false; + } + if (ingress == null ? a.ingress != null : !ingress.equals(a.ingress)) { + return false; + } + if (egress == null ? a.egress != null : !egress.equals(a.egress)) { + return false; + } + } + return true; + } +} diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/MSDSchema.java b/core/msd/src/main/java/com/yahoo/athenz/msd/MSDSchema.java index 2a3ffb0352e..f6c3c8e3192 100644 --- a/core/msd/src/main/java/com/yahoo/athenz/msd/MSDSchema.java +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/MSDSchema.java @@ -256,7 +256,7 @@ private static Schema build() { .field("workloads", "Workloads", false, "matching workloads"); sb.enumType("NetworkPolicyChangeEffect") - .comment("IMPACT indicates that a change in network policy will interfere with workings of one or more transport policies NO_IMAPCT indicates that a change in network policy will not interfere with workings of any transport policy") + .comment("IMPACT indicates that a change in network policy will interfere with workings of one or more transport policies NO_IMPACT indicates that a change in network policy will not interfere with workings of any transport policy") .element("IMPACT") .element("NO_IMPACT"); @@ -289,6 +289,66 @@ private static Schema build() { .field("effect", "NetworkPolicyChangeEffect", false, "enum indicating effect of network policy change on one or more transport policies") .arrayField("details", "NetworkPolicyChangeImpactDetail", true, "if the above enum value is IMPACT then this optional object contains more details about the impacted transport policies"); + sb.structType("KubernetesLabelSelectorRequirement") + .comment("A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.") + .field("key", "String", false, "Label key that the selector applies to") + .field("operator", "String", false, "Operator that is applied to the key. Valid operators are In, NotIn, Exists and DoesNotExist.") + .arrayField("values", "String", true, "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."); + + sb.structType("KubernetesLabelSelector") + .comment("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.") + .arrayField("matchExpressions", "KubernetesLabelSelectorRequirement", false, "Array of label selector requirements. The requirements are ANDed.") + .mapField("matchLabels", "String", "String", false, "Map of label key/value pairs"); + + sb.structType("KubernetesNetworkPolicyPort", "PolicyPort") + .comment("Kubernetes network policy port range") + .field("protocol", "TransportPolicyProtocol", false, "Network policy protocol. Allowed values: TCP, UDP."); + + sb.structType("KubernetesIPBlock") + .comment("Kubernetes network policy IP block source/target") + .field("cidr", "String", false, "CIDR block representing IP range for source/target") + .arrayField("except", "String", true, "Exception for CIDR blocks, if needed"); + + sb.structType("KubernetesNetworkPolicyPeer") + .comment("Kubernetes network policy peer (source/target)") + .field("podSelector", "KubernetesLabelSelector", true, "Kubernetes pod selector for the network policy source/target") + .field("namespaceSelector", "KubernetesLabelSelector", true, "Kubernetes namespace selector for the network policy source/target") + .field("ipBlock", "KubernetesIPBlock", true, "IP block for the network policy source/target"); + + sb.structType("KubernetesNetworkPolicyIngressRule") + .comment("Kubernetes network policy ingress rule") + .arrayField("from", "KubernetesNetworkPolicyPeer", true, "Network policy source, when empty all sources are allowed") + .arrayField("ports", "KubernetesNetworkPolicyPort", true, "Ingress port(s), when empty all ports are allowed"); + + sb.structType("KubernetesNetworkPolicyEgressRule") + .comment("Kubernetes network policy egress rule") + .arrayField("to", "KubernetesNetworkPolicyPeer", true, "Network policy target, when empty all sources are allowed") + .arrayField("ports", "KubernetesNetworkPolicyPort", true, "Egress port(s), when empty all ports are allowed"); + + sb.structType("KubernetesNetworkPolicySpec") + .comment("Kubernetes network policy spec") + .field("podSelector", "KubernetesLabelSelector", false, "Kubernetes pod selector for the network policy target") + .arrayField("policyTypes", "String", false, "Network policy types - Ingress, Egress") + .arrayField("ingress", "KubernetesNetworkPolicyIngressRule", true, "Ingress network policy rules, if empty then all ingress traffic is blocked") + .arrayField("egress", "KubernetesNetworkPolicyEgressRule", true, "Egress network policy rules, if empty then all egress traffic is blocked"); + + sb.structType("KubernetesNetworkPolicyRequest") + .comment("Request object containing Kubernetes network policy inputs") + .field("athenzDomainLabel", "String", true, "Label key name used on pods to identify Athenz domain") + .field("athenzServiceLabel", "String", false, "Label key name used on pods to identify Athenz service") + .field("networkPolicyType", "String", true, "Network policy type, default is vanilla Kubernetes") + .field("requestedApiVersion", "String", true, "Requested network policy apiVersion") + .field("networkPolicyNamespace", "String", true, "Kubernetes namespace for the network policy object") + .field("domainLabelAsNamespaceSelector", "Bool", true, "Use athenzDomainLabel as namespace selector", false) + .field("domainInServiceLabel", "Bool", true, "Use Athenz domain name in service label", false); + + sb.structType("KubernetesNetworkPolicyResponse") + .comment("Response object containing Kubernetes network policy") + .field("apiVersion", "String", false, "Kubernetes network policy apiVersion") + .field("kind", "String", false, "Kubernetes network policy kind") + .mapField("metadata", "String", "String", false, "Kubernetes network policy metadata") + .field("spec", "KubernetesNetworkPolicySpec", false, "Kubernetes network policy spec"); + sb.stringType("rdl.Identifier") .comment("All names need to be of this restricted string type") .pattern("[a-zA-Z_]+[a-zA-Z_0-9]*"); @@ -741,6 +801,26 @@ private static Schema build() { .exception("UNAUTHORIZED", "ResourceError", "") ; + sb.resource("KubernetesNetworkPolicyRequest", "POST", "/domain/{domainName}/service/{serviceName}/kubernetesnetworkpolicy") + .comment("API endpoint to get the Kubernetes network policy converted from the corresponding MSD policy") + .pathParam("domainName", "DomainName", "Name of the domain") + .pathParam("serviceName", "EntityName", "Name of the service") + .input("request", "KubernetesNetworkPolicyRequest", "Struct representing input options based on the cluster context") + .headerParam("If-None-Match", "matchingTag", "String", null, "Retrieved from the previous request, this timestamp specifies to the server to return any policies modified since this time") + .output("ETag", "tag", "String", "The current latest modification timestamp is returned in this header") + .auth("read", "{domain}:service.{service}") + .expected("OK") + .exception("BAD_REQUEST", "ResourceError", "") + + .exception("FORBIDDEN", "ResourceError", "") + + .exception("NOT_FOUND", "ResourceError", "") + + .exception("TOO_MANY_REQUESTS", "ResourceError", "") + + .exception("UNAUTHORIZED", "ResourceError", "") +; + sb.resource("rdl.Schema", "GET", "/schema") .comment("Get RDL Schema") .auth("", "", true) diff --git a/core/msd/src/main/java/com/yahoo/athenz/msd/NetworkPolicyChangeEffect.java b/core/msd/src/main/java/com/yahoo/athenz/msd/NetworkPolicyChangeEffect.java index 30ea9a34e49..5df958d46ef 100644 --- a/core/msd/src/main/java/com/yahoo/athenz/msd/NetworkPolicyChangeEffect.java +++ b/core/msd/src/main/java/com/yahoo/athenz/msd/NetworkPolicyChangeEffect.java @@ -7,7 +7,7 @@ // // NetworkPolicyChangeEffect - IMPACT indicates that a change in network policy -// will interfere with workings of one or more transport policies NO_IMAPCT +// will interfere with workings of one or more transport policies NO_IMPACT // indicates that a change in network policy will not interfere with workings of // any transport policy // diff --git a/core/msd/src/main/rdl/KubernetesNetworkPolicy.rdli b/core/msd/src/main/rdl/KubernetesNetworkPolicy.rdli new file mode 100644 index 00000000000..2f59ad6c4a7 --- /dev/null +++ b/core/msd/src/main/rdl/KubernetesNetworkPolicy.rdli @@ -0,0 +1,23 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +include "Names.tdl"; +include "KubernetesNetworkPolicy.tdl"; + +// API endpoint to get the Kubernetes network policy converted from the corresponding MSD policy +resource KubernetesNetworkPolicyResponse POST "/domain/{domainName}/service/{serviceName}/kubernetesnetworkpolicy" { + DomainName domainName; //Name of the domain + EntityName serviceName; //Name of the service + KubernetesNetworkPolicyRequest request; //Struct representing input options based on the cluster context + authorize ("read", "{domain}:service.{service}"); + String matchingTag (header="If-None-Match"); //Retrieved from the previous request, this timestamp specifies to the server to return any policies modified since this time + String tag (header="ETag", out); //The current latest modification timestamp is returned in this header + expected OK, NOT_MODIFIED; + exceptions { + ResourceError BAD_REQUEST; + ResourceError NOT_FOUND; + ResourceError FORBIDDEN; + ResourceError UNAUTHORIZED; + ResourceError TOO_MANY_REQUESTS; + } +} diff --git a/core/msd/src/main/rdl/KubernetesNetworkPolicy.tdl b/core/msd/src/main/rdl/KubernetesNetworkPolicy.tdl new file mode 100644 index 00000000000..100eb76ba15 --- /dev/null +++ b/core/msd/src/main/rdl/KubernetesNetworkPolicy.tdl @@ -0,0 +1,75 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +include "Names.tdl"; +include "TransportPolicyRule.tdl"; + +// A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. +type KubernetesLabelSelectorRequirement Struct { + String key; //Label key that the selector applies to + String operator; //Operator that is applied to the key. Valid operators are In, NotIn, Exists and DoesNotExist. + Array values (optional); //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. +} + +// 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. +type KubernetesLabelSelector Struct { + Array matchExpressions; //Array of label selector requirements. The requirements are ANDed. + Map matchLabels; //Map of label key/value pairs +} + +// Kubernetes network policy port range +type KubernetesNetworkPolicyPort PolicyPort { + TransportPolicyProtocol protocol; //Network policy protocol. Allowed values: TCP, UDP. +} + +// Kubernetes network policy IP block source/target +type KubernetesIPBlock Struct { + String cidr; //CIDR block representing IP range for source/target + Array except (optional); //Exception for CIDR blocks, if needed +} + +// Kubernetes network policy peer (source/target) +type KubernetesNetworkPolicyPeer Struct { + KubernetesLabelSelector podSelector (optional); //Kubernetes pod selector for the network policy source/target + KubernetesLabelSelector namespaceSelector (optional); //Kubernetes namespace selector for the network policy source/target + KubernetesIPBlock ipBlock (optional); //IP block for the network policy source/target +} + +// Kubernetes network policy ingress rule +type KubernetesNetworkPolicyIngressRule Struct { + Array from (optional); //Network policy source, when empty all sources are allowed + Array ports (optional); //Ingress port(s), when empty all ports are allowed +} + +// Kubernetes network policy egress rule +type KubernetesNetworkPolicyEgressRule Struct { + Array to (optional); //Network policy target, when empty all sources are allowed + Array ports (optional); //Egress port(s), when empty all ports are allowed +} + +// Kubernetes network policy spec +type KubernetesNetworkPolicySpec Struct { + KubernetesLabelSelector podSelector; //Kubernetes pod selector for the network policy target + Array policyTypes; //Network policy types - Ingress, Egress + Array ingress (optional); //Ingress network policy rules, if empty then all ingress traffic is blocked + Array egress (optional); //Egress network policy rules, if empty then all egress traffic is blocked +} + +// Request object containing Kubernetes network policy inputs +type KubernetesNetworkPolicyRequest Struct { + String athenzDomainLabel (optional); //Label key name used on pods to identify Athenz domain + String athenzServiceLabel; //Label key name used on pods to identify Athenz service + String networkPolicyType (optional); //Network policy type, default is vanilla Kubernetes + String requestedApiVersion (optional); //Requested network policy apiVersion + String networkPolicyNamespace (optional); //Kubernetes namespace for the network policy object + Bool domainLabelAsNamespaceSelector (optional, default=false); //Use athenzDomainLabel as namespace selector + Bool domainInServiceLabel (optional, default=false); //Use Athenz domain name in service label +} + +// Response object containing Kubernetes network policy +type KubernetesNetworkPolicyResponse Struct { + String apiVersion; //Kubernetes network policy apiVersion + String kind; //Kubernetes network policy kind + Map metadata; //Kubernetes network policy metadata + KubernetesNetworkPolicySpec spec; //Kubernetes network policy spec +} \ No newline at end of file diff --git a/core/msd/src/main/rdl/MSD.rdl b/core/msd/src/main/rdl/MSD.rdl index fe82a36a773..28b898ed87d 100644 --- a/core/msd/src/main/rdl/MSD.rdl +++ b/core/msd/src/main/rdl/MSD.rdl @@ -11,4 +11,5 @@ namespace com.yahoo.athenz.msd; include "TransportPolicyRule.rdli"; include "Workload.rdli"; include "NetworkPolicy.rdli"; +include "KubernetesNetworkPolicy.rdli"; include "Schema.rdli"; diff --git a/core/msd/src/main/rdl/NetworkPolicy.tdl b/core/msd/src/main/rdl/NetworkPolicy.tdl index d7cd83370c2..8b2108cc4d0 100644 --- a/core/msd/src/main/rdl/NetworkPolicy.tdl +++ b/core/msd/src/main/rdl/NetworkPolicy.tdl @@ -5,7 +5,7 @@ include "Names.tdl"; include "TransportPolicyRule.tdl"; // IMPACT indicates that a change in network policy will interfere with workings of one or more transport policies -// NO_IMAPCT indicates that a change in network policy will not interfere with workings of any transport policy +// NO_IMPACT indicates that a change in network policy will not interfere with workings of any transport policy type NetworkPolicyChangeEffect Enum { IMPACT, diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesIPBlockTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesIPBlockTest.java new file mode 100644 index 00000000000..b0e3d06c0ff --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesIPBlockTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; + +import org.testng.annotations.Test; + +import java.util.List; + +import static org.testng.Assert.*; + +public class KubernetesIPBlockTest { + + @Test + public void testMethods() { + KubernetesIPBlock kubernetesIPBlock1 = new KubernetesIPBlock(); + kubernetesIPBlock1.setCidr("10.0.0.0/12"); + kubernetesIPBlock1.setExcept(null); + assertEquals(kubernetesIPBlock1.getCidr(), "10.0.0.0/12"); + assertNull(kubernetesIPBlock1.getExcept()); + KubernetesIPBlock kubernetesIPBlock2 = new KubernetesIPBlock(); + kubernetesIPBlock2.setCidr("10.0.0.0/12"); + kubernetesIPBlock2.setExcept(null); + + assertEquals(kubernetesIPBlock1, kubernetesIPBlock2); + assertFalse(kubernetesIPBlock1.equals("abc")); + + kubernetesIPBlock2.setCidr("10.0.0.0/13"); + assertNotEquals(kubernetesIPBlock1, kubernetesIPBlock2); + + kubernetesIPBlock2.setCidr("10.0.0.0/12"); + kubernetesIPBlock2.setExcept(List.of("10.0.0.2")); + assertNotEquals(kubernetesIPBlock1, kubernetesIPBlock2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirementTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirementTest.java new file mode 100644 index 00000000000..1587d516645 --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorRequirementTest.java @@ -0,0 +1,54 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class KubernetesLabelSelectorRequirementTest { + + @Test + public void testMethods() { + KubernetesLabelSelectorRequirement k1 = new KubernetesLabelSelectorRequirement(); + k1.setKey("key"); + k1.setOperator("operator"); + k1.setValues(null); + + KubernetesLabelSelectorRequirement k2 = new KubernetesLabelSelectorRequirement(); + k2.setKey("key"); + k2.setOperator("operator"); + k2.setValues(null); + + assertEquals(k1, k2); + assertFalse(k1.equals("abc")); + + assertEquals(k1.getKey(), "key"); + assertEquals(k1.getOperator(), "operator"); + assertNull(k1.getValues()); + + k2.setKey("key2"); + assertNotEquals(k1, k2); + + k2.setKey("key"); + k2.setOperator("operator2"); + assertNotEquals(k1, k2); + + k2.setOperator("operator"); + k2.setValues(new java.util.ArrayList<>()); + assertNotEquals(k1, k2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorTest.java new file mode 100644 index 00000000000..b4849073ab3 --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesLabelSelectorTest.java @@ -0,0 +1,49 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.List; + +import static org.testng.Assert.*; + +public class KubernetesLabelSelectorTest { + @Test + public void testMethods() { + KubernetesLabelSelector kubernetesLabelSelector1 = new KubernetesLabelSelector(); + kubernetesLabelSelector1.setMatchExpressions(null); + kubernetesLabelSelector1.setMatchLabels(null); + assertNull(kubernetesLabelSelector1.getMatchExpressions()); + assertNull(kubernetesLabelSelector1.getMatchLabels()); + + KubernetesLabelSelector kubernetesLabelSelector2 = new KubernetesLabelSelector(); + kubernetesLabelSelector2.setMatchExpressions(null); + kubernetesLabelSelector2.setMatchLabels(null); + + assertEquals(kubernetesLabelSelector1, kubernetesLabelSelector2); + assertFalse(kubernetesLabelSelector1.equals("abc")); + + KubernetesLabelSelectorRequirement labelSelectorRequirement = new KubernetesLabelSelectorRequirement(); + kubernetesLabelSelector2.setMatchExpressions(List.of(labelSelectorRequirement)); + assertNotEquals(kubernetesLabelSelector1, kubernetesLabelSelector2); + + kubernetesLabelSelector2.setMatchExpressions(null); + kubernetesLabelSelector2.setMatchLabels(new HashMap<>()); + assertNotEquals(kubernetesLabelSelector1, kubernetesLabelSelector2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRuleTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRuleTest.java new file mode 100644 index 00000000000..2efc08704d1 --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyEgressRuleTest.java @@ -0,0 +1,48 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyEgressRuleTest { + + @Test + public void testMethods() { + + KubernetesNetworkPolicyEgressRule egressRule1 = new KubernetesNetworkPolicyEgressRule(); + egressRule1.setTo(null); + egressRule1.setPorts(null); + assertNull(egressRule1.getTo()); + assertNull(egressRule1.getPorts()); + + KubernetesNetworkPolicyEgressRule egressRule2 = new KubernetesNetworkPolicyEgressRule(); + egressRule2.setTo(null); + egressRule2.setPorts(null); + + assertEquals(egressRule1, egressRule2); + assertFalse(egressRule1.equals("abc")); + + egressRule2.setTo(new ArrayList<>()); + assertNotEquals(egressRule1, egressRule2); + + egressRule2.setTo(null); + egressRule2.setPorts(new ArrayList<>()); + assertNotEquals(egressRule1, egressRule2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRuleTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRuleTest.java new file mode 100644 index 00000000000..ee51c97ad7e --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyIngressRuleTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyIngressRuleTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicyIngressRule ingressRule1 = new KubernetesNetworkPolicyIngressRule(); + ingressRule1.setFrom(null); + ingressRule1.setPorts(null); + assertNull(ingressRule1.getFrom()); + assertNull(ingressRule1.getPorts()); + + KubernetesNetworkPolicyIngressRule ingressRule2 = new KubernetesNetworkPolicyIngressRule(); + ingressRule2.setFrom(null); + ingressRule2.setPorts(null); + + assertEquals(ingressRule1, ingressRule2); + assertFalse(ingressRule1.equals("abc")); + + ingressRule2.setFrom(new ArrayList<>()); + assertNotEquals(ingressRule1, ingressRule2); + + ingressRule2.setFrom(null); + ingressRule2.setPorts(new ArrayList<>()); + assertNotEquals(ingressRule1, ingressRule2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeerTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeerTest.java new file mode 100644 index 00000000000..a0b398e0d7d --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPeerTest.java @@ -0,0 +1,55 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyPeerTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicyPeer peer1 = new KubernetesNetworkPolicyPeer(); + KubernetesIPBlock ipBlock = new KubernetesIPBlock(); + KubernetesLabelSelector podSelector = new KubernetesLabelSelector(); + KubernetesLabelSelector namespaceSelector = new KubernetesLabelSelector(); + peer1.setIpBlock(ipBlock); + peer1.setNamespaceSelector(namespaceSelector); + peer1.setPodSelector(podSelector); + assertEquals(peer1.getIpBlock(), ipBlock); + assertEquals(peer1.getNamespaceSelector(), namespaceSelector); + assertEquals(peer1.getPodSelector(), podSelector); + + KubernetesNetworkPolicyPeer peer2 = new KubernetesNetworkPolicyPeer(); + peer2.setIpBlock(ipBlock); + peer2.setNamespaceSelector(namespaceSelector); + peer2.setPodSelector(podSelector); + + assertEquals(peer1, peer2); + assertFalse(peer1.equals("abc")); + + peer2.setIpBlock(null); + assertNotEquals(peer1, peer2); + + peer2.setIpBlock(ipBlock); + peer2.setPodSelector(null); + assertNotEquals(peer1, peer2); + + peer2.setPodSelector(podSelector); + peer2.setNamespaceSelector(null); + assertNotEquals(peer1, peer2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPortTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPortTest.java new file mode 100644 index 00000000000..cd212aa707e --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyPortTest.java @@ -0,0 +1,52 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyPortTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicyPort policyPort1 = new KubernetesNetworkPolicyPort(); + policyPort1.setPort(8080); + policyPort1.setEndPort(8081); + policyPort1.setProtocol(TransportPolicyProtocol.TCP); + assertEquals(policyPort1.getPort(), 8080); + assertEquals(policyPort1.getEndPort(), 8081); + assertEquals(policyPort1.getProtocol(), TransportPolicyProtocol.TCP); + + KubernetesNetworkPolicyPort policyPort2 = new KubernetesNetworkPolicyPort(); + policyPort2.setPort(8080); + policyPort2.setEndPort(8081); + policyPort2.setProtocol(TransportPolicyProtocol.TCP); + + assertEquals(policyPort1, policyPort2); + assertFalse(policyPort1.equals("abc")); + + policyPort2.setPort(8081); + assertNotEquals(policyPort1, policyPort2); + + policyPort2.setPort(8080); + policyPort2.setEndPort(8082); + assertNotEquals(policyPort1, policyPort2); + + policyPort2.setEndPort(8081); + policyPort2.setProtocol(TransportPolicyProtocol.UDP); + assertNotEquals(policyPort1, policyPort2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequestTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequestTest.java new file mode 100644 index 00000000000..2196bd8083a --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyRequestTest.java @@ -0,0 +1,83 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.Map; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyRequestTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicyRequest req1 = new KubernetesNetworkPolicyRequest(); + req1.setAthenzDomainLabel("athenz"); + req1.setAthenzServiceLabel("api"); + req1.setNetworkPolicyType("kubernetes"); + req1.setNetworkPolicyNamespace("myns"); + req1.setDomainLabelAsNamespaceSelector(true); + req1.setDomainInServiceLabel(true); + req1.setRequestedApiVersion("v1"); + + KubernetesNetworkPolicyRequest req2 = new KubernetesNetworkPolicyRequest(); + req2.setAthenzDomainLabel("athenz"); + req2.setAthenzServiceLabel("api"); + req2.setNetworkPolicyType("kubernetes"); + req2.setNetworkPolicyNamespace("myns"); + req2.setDomainLabelAsNamespaceSelector(true); + req2.setDomainInServiceLabel(true); + req2.setRequestedApiVersion("v1"); + + assertEquals(req1, req2); + assertFalse(req1.equals("abc")); + + assertEquals(req1.getAthenzDomainLabel(), "athenz"); + assertEquals(req1.getAthenzServiceLabel(), "api"); + assertEquals(req1.getNetworkPolicyType(), "kubernetes"); + assertEquals(req1.getNetworkPolicyNamespace(), "myns"); + assertTrue(req1.getDomainInServiceLabel()); + assertTrue(req1.getDomainLabelAsNamespaceSelector()); + assertEquals(req1.getRequestedApiVersion(), "v1"); + + req2.setAthenzDomainLabel("athenz2"); + assertNotEquals(req1, req2); + + req2.setAthenzDomainLabel("athenz"); + req2.setAthenzServiceLabel("api2"); + assertNotEquals(req1, req2); + + req2.setAthenzServiceLabel("api"); + req2.setNetworkPolicyType("cilium"); + assertNotEquals(req1, req2); + + req2.setNetworkPolicyType("kubernetes"); + req2.setNetworkPolicyNamespace("myns2"); + assertNotEquals(req1, req2); + + req2.setNetworkPolicyNamespace("myns"); + req2.setDomainInServiceLabel(false); + assertNotEquals(req1, req2); + + req2.setDomainInServiceLabel(true); + req2.setRequestedApiVersion("v2"); + assertNotEquals(req1, req2); + + req2.setRequestedApiVersion("v1"); + req2.setDomainLabelAsNamespaceSelector(false); + assertNotEquals(req1, req2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponseTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponseTest.java new file mode 100644 index 00000000000..f6ad02bd112 --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicyResponseTest.java @@ -0,0 +1,62 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.HashMap; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicyResponseTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicyResponse knp = new KubernetesNetworkPolicyResponse(); + knp.setApiVersion("apiVersion"); + knp.setKind("kind"); + knp.setMetadata(null); + knp.setSpec(null); + assertEquals(knp.getApiVersion(), "apiVersion"); + assertEquals(knp.getKind(), "kind"); + assertNull(knp.getMetadata()); + assertNull(knp.getSpec()); + + KubernetesNetworkPolicyResponse knp2 = new KubernetesNetworkPolicyResponse(); + knp2.setApiVersion("apiVersion"); + knp2.setKind("kind"); + knp2.setMetadata(null); + knp2.setSpec(null); + + assertEquals(knp, knp2); + assertFalse(knp.equals("abc")); + + knp2.setApiVersion("apiVersion2"); + assertNotEquals(knp, knp2); + + knp2.setApiVersion("apiVersion"); + knp2.setKind("kind2"); + assertNotEquals(knp, knp2); + + knp2.setKind("kind"); + knp2.setMetadata(new HashMap<>()); + assertNotEquals(knp, knp2); + + knp2.setMetadata(null); + knp2.setSpec(new KubernetesNetworkPolicySpec()); + assertNotEquals(knp, knp2); + } +} \ No newline at end of file diff --git a/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpecTest.java b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpecTest.java new file mode 100644 index 00000000000..9f326f82da2 --- /dev/null +++ b/core/msd/src/test/java/com/yahoo/athenz/msd/KubernetesNetworkPolicySpecTest.java @@ -0,0 +1,61 @@ +/* + * Copyright The Athenz 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 com.yahoo.athenz.msd; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +import static org.testng.Assert.*; + +public class KubernetesNetworkPolicySpecTest { + + @Test + public void testMethods() { + KubernetesNetworkPolicySpec spec1 = new KubernetesNetworkPolicySpec(); + spec1.setEgress(null); + spec1.setIngress(null); + spec1.setPodSelector(null); + spec1.setPolicyTypes(null); + assertNull(spec1.getEgress()); + assertNull(spec1.getIngress()); + assertNull(spec1.getPodSelector()); + assertNull(spec1.getPolicyTypes()); + + KubernetesNetworkPolicySpec spec2 = new KubernetesNetworkPolicySpec(); + spec2.setEgress(null); + spec2.setIngress(null); + spec2.setPodSelector(null); + spec2.setPolicyTypes(null); + + assertEquals(spec1, spec2); + assertFalse(spec1.equals("abc")); + + spec2.setEgress(new ArrayList<>()); + assertNotEquals(spec1, spec2); + + spec2.setEgress(null); + spec2.setIngress(new ArrayList<>()); + assertNotEquals(spec1, spec2); + + spec2.setIngress(null); + spec2.setPodSelector(new KubernetesLabelSelector()); + assertNotEquals(spec1, spec2); + + spec2.setPodSelector(null); + spec2.setPolicyTypes(new ArrayList<>()); + assertNotEquals(spec1, spec2); + } +} \ No newline at end of file