diff --git a/clients/go/zms/client.go b/clients/go/zms/client.go index eee0c5c8d7f..58d29f4f992 100644 --- a/clients/go/zms/client.go +++ b/clients/go/zms/client.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "fmt" + rdl "github.com/ardielle/ardielle-go/rdl" "io" "io/ioutil" "net/http" @@ -15,8 +16,6 @@ import ( "strconv" "strings" "time" - - rdl "github.com/ardielle/ardielle-go/rdl" ) var _ = json.Marshal diff --git a/clients/go/zts/client.go b/clients/go/zts/client.go index ce47b10252e..0cd1ffef241 100644 --- a/clients/go/zts/client.go +++ b/clients/go/zts/client.go @@ -1047,3 +1047,99 @@ func (client ZTSClient) PostRoleCertificateRequestExt(req *RoleCertificateReques return data, errobj } } + +func (client ZTSClient) GetWorkloadsByService(domainName DomainName, serviceName EntityName) (*Workloads, error) { + var data *Workloads + url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workloads" + resp, err := client.httpGet(url, nil) + if err != nil { + return data, err + } + defer resp.Body.Close() + switch resp.StatusCode { + case 200: + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + return data, err + } + return data, nil + default: + var errobj rdl.ResourceError + contentBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return data, err + } + json.Unmarshal(contentBytes, &errobj) + if errobj.Code == 0 { + errobj.Code = resp.StatusCode + } + if errobj.Message == "" { + errobj.Message = string(contentBytes) + } + return data, errobj + } +} + +func (client ZTSClient) GetWorkloadsByIP(ip string) (*Workloads, error) { + var data *Workloads + url := client.URL + "/workloads/" + ip + resp, err := client.httpGet(url, nil) + if err != nil { + return data, err + } + defer resp.Body.Close() + switch resp.StatusCode { + case 200: + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + return data, err + } + return data, nil + default: + var errobj rdl.ResourceError + contentBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return data, err + } + json.Unmarshal(contentBytes, &errobj) + if errobj.Code == 0 { + errobj.Code = resp.StatusCode + } + if errobj.Message == "" { + errobj.Message = string(contentBytes) + } + return data, errobj + } +} + +func (client ZTSClient) GetTransportRules(domainName DomainName, serviceName EntityName) (*TransportRules, error) { + var data *TransportRules + url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/transportRules" + resp, err := client.httpGet(url, nil) + if err != nil { + return data, err + } + defer resp.Body.Close() + switch resp.StatusCode { + case 200: + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + return data, err + } + return data, nil + default: + var errobj rdl.ResourceError + contentBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return data, err + } + json.Unmarshal(contentBytes, &errobj) + if errobj.Code == 0 { + errobj.Code = resp.StatusCode + } + if errobj.Message == "" { + errobj.Message = string(contentBytes) + } + return data, errobj + } +} diff --git a/clients/go/zts/model.go b/clients/go/zts/model.go index e566e564292..3ec1a176c26 100644 --- a/clients/go/zts/model.go +++ b/clients/go/zts/model.go @@ -3196,3 +3196,334 @@ func (self *RoleCertificate) Validate() error { } return nil } + +// +// Workload - +// +type Workload struct { + + // + // name of the domain, optional for getWorkloadsByService API call + // + DomainName DomainName `json:"domainName"` + + // + // name of the service, , optional for getWorkloadsByService API call + // + ServiceName EntityName `json:"serviceName"` + + // + // unique identifier for the workload, usually defined by provider + // + Uuid string `json:"uuid"` + + // + // list of IP addresses associated with the workload, optional for + // getWorkloadsByIP API call + // + IpAddresses []string `json:"ipAddresses"` + + // + // infrastructure provider e.g. k8s, AWS, Azure, openstack etc. + // + Provider string `json:"provider"` + + // + // most recent update timestamp in the backend + // + UpdateTime rdl.Timestamp `json:"updateTime"` +} + +// +// NewWorkload - creates an initialized Workload instance, returns a pointer to it +// +func NewWorkload(init ...*Workload) *Workload { + var o *Workload + if len(init) == 1 { + o = init[0] + } else { + o = new(Workload) + } + return o.Init() +} + +// +// Init - sets up the instance according to its default field values, if any +// +func (self *Workload) Init() *Workload { + if self.IpAddresses == nil { + self.IpAddresses = make([]string, 0) + } + return self +} + +type rawWorkload Workload + +// +// UnmarshalJSON is defined for proper JSON decoding of a Workload +// +func (self *Workload) UnmarshalJSON(b []byte) error { + var m rawWorkload + err := json.Unmarshal(b, &m) + if err == nil { + o := Workload(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// +// Validate - checks for missing required fields, etc +// +func (self *Workload) Validate() error { + if self.DomainName == "" { + return fmt.Errorf("Workload.domainName is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "DomainName", self.DomainName) + if !val.Valid { + return fmt.Errorf("Workload.domainName does not contain a valid DomainName (%v)", val.Error) + } + } + if self.ServiceName == "" { + return fmt.Errorf("Workload.serviceName is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "EntityName", self.ServiceName) + if !val.Valid { + return fmt.Errorf("Workload.serviceName does not contain a valid EntityName (%v)", val.Error) + } + } + if self.Uuid == "" { + return fmt.Errorf("Workload.uuid is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "String", self.Uuid) + if !val.Valid { + return fmt.Errorf("Workload.uuid does not contain a valid String (%v)", val.Error) + } + } + if self.IpAddresses == nil { + return fmt.Errorf("Workload: Missing required field: ipAddresses") + } + if self.Provider == "" { + return fmt.Errorf("Workload.provider is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "String", self.Provider) + if !val.Valid { + return fmt.Errorf("Workload.provider does not contain a valid String (%v)", val.Error) + } + } + if self.UpdateTime.IsZero() { + return fmt.Errorf("Workload: Missing required field: updateTime") + } + return nil +} + +// +// Workloads - +// +type Workloads struct { + + // + // list of workloads + // + WorkloadList []*Workload `json:"workloadList"` +} + +// +// NewWorkloads - creates an initialized Workloads instance, returns a pointer to it +// +func NewWorkloads(init ...*Workloads) *Workloads { + var o *Workloads + if len(init) == 1 { + o = init[0] + } else { + o = new(Workloads) + } + return o.Init() +} + +// +// Init - sets up the instance according to its default field values, if any +// +func (self *Workloads) Init() *Workloads { + if self.WorkloadList == nil { + self.WorkloadList = make([]*Workload, 0) + } + return self +} + +type rawWorkloads Workloads + +// +// UnmarshalJSON is defined for proper JSON decoding of a Workloads +// +func (self *Workloads) UnmarshalJSON(b []byte) error { + var m rawWorkloads + err := json.Unmarshal(b, &m) + if err == nil { + o := Workloads(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// +// Validate - checks for missing required fields, etc +// +func (self *Workloads) Validate() error { + if self.WorkloadList == nil { + return fmt.Errorf("Workloads: Missing required field: workloadList") + } + return nil +} + +// +// TransportRule - Copyright The Athenz Authors Licensed under the terms of the +// Apache version 2.0 license. See LICENSE file for terms. +// +type TransportRule struct { + + // + // source or destination endpoints defined in terms of CIDR notation + // + EndPoint string `json:"endPoint"` + + // + // range of port numbers for incoming connections + // + SourcePortRange string `json:"sourcePortRange"` + + // + // destination / listener port of the service + // + Port int32 `json:"port"` + + // + // protocol of the connection + // + Protocol string `json:"protocol"` +} + +// +// NewTransportRule - creates an initialized TransportRule instance, returns a pointer to it +// +func NewTransportRule(init ...*TransportRule) *TransportRule { + var o *TransportRule + if len(init) == 1 { + o = init[0] + } else { + o = new(TransportRule) + } + return o +} + +type rawTransportRule TransportRule + +// +// UnmarshalJSON is defined for proper JSON decoding of a TransportRule +// +func (self *TransportRule) UnmarshalJSON(b []byte) error { + var m rawTransportRule + err := json.Unmarshal(b, &m) + if err == nil { + o := TransportRule(m) + *self = o + err = self.Validate() + } + return err +} + +// +// Validate - checks for missing required fields, etc +// +func (self *TransportRule) Validate() error { + if self.EndPoint == "" { + return fmt.Errorf("TransportRule.endPoint is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "String", self.EndPoint) + if !val.Valid { + return fmt.Errorf("TransportRule.endPoint does not contain a valid String (%v)", val.Error) + } + } + if self.SourcePortRange == "" { + return fmt.Errorf("TransportRule.sourcePortRange is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "String", self.SourcePortRange) + if !val.Valid { + return fmt.Errorf("TransportRule.sourcePortRange does not contain a valid String (%v)", val.Error) + } + } + if self.Protocol == "" { + return fmt.Errorf("TransportRule.protocol is missing but is a required field") + } else { + val := rdl.Validate(ZTSSchema(), "String", self.Protocol) + if !val.Valid { + return fmt.Errorf("TransportRule.protocol does not contain a valid String (%v)", val.Error) + } + } + return nil +} + +// +// TransportRules - +// +type TransportRules struct { + IngressRules []*TransportRule `json:"ingressRules"` + EgressRules []*TransportRule `json:"egressRules"` +} + +// +// NewTransportRules - creates an initialized TransportRules instance, returns a pointer to it +// +func NewTransportRules(init ...*TransportRules) *TransportRules { + var o *TransportRules + if len(init) == 1 { + o = init[0] + } else { + o = new(TransportRules) + } + return o.Init() +} + +// +// Init - sets up the instance according to its default field values, if any +// +func (self *TransportRules) Init() *TransportRules { + if self.IngressRules == nil { + self.IngressRules = make([]*TransportRule, 0) + } + if self.EgressRules == nil { + self.EgressRules = make([]*TransportRule, 0) + } + return self +} + +type rawTransportRules TransportRules + +// +// UnmarshalJSON is defined for proper JSON decoding of a TransportRules +// +func (self *TransportRules) UnmarshalJSON(b []byte) error { + var m rawTransportRules + err := json.Unmarshal(b, &m) + if err == nil { + o := TransportRules(m) + *self = *((&o).Init()) + err = self.Validate() + } + return err +} + +// +// Validate - checks for missing required fields, etc +// +func (self *TransportRules) Validate() error { + if self.IngressRules == nil { + return fmt.Errorf("TransportRules: Missing required field: ingressRules") + } + if self.EgressRules == nil { + return fmt.Errorf("TransportRules: Missing required field: egressRules") + } + return nil +} diff --git a/clients/go/zts/zts_schema.go b/clients/go/zts/zts_schema.go index 07177ac6b1a..982fbada80c 100644 --- a/clients/go/zts/zts_schema.go +++ b/clients/go/zts/zts_schema.go @@ -387,6 +387,32 @@ func init() { tRoleCertificate.Field("x509Certificate", "String", false, nil, "") sb.AddType(tRoleCertificate.Build()) + tWorkload := rdl.NewStructTypeBuilder("Struct", "Workload") + tWorkload.Field("domainName", "DomainName", false, nil, "name of the domain, optional for getWorkloadsByService API call") + tWorkload.Field("serviceName", "EntityName", false, nil, "name of the service, , optional for getWorkloadsByService API call") + tWorkload.Field("uuid", "String", false, nil, "unique identifier for the workload, usually defined by provider") + tWorkload.ArrayField("ipAddresses", "String", false, "list of IP addresses associated with the workload, optional for getWorkloadsByIP API call") + tWorkload.Field("provider", "String", false, nil, "infrastructure provider e.g. k8s, AWS, Azure, openstack etc.") + tWorkload.Field("updateTime", "Timestamp", false, nil, "most recent update timestamp in the backend") + sb.AddType(tWorkload.Build()) + + tWorkloads := rdl.NewStructTypeBuilder("Struct", "Workloads") + tWorkloads.ArrayField("workloadList", "Workload", false, "list of workloads") + sb.AddType(tWorkloads.Build()) + + tTransportRule := rdl.NewStructTypeBuilder("Struct", "TransportRule") + tTransportRule.Comment("Copyright The Athenz Authors Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms.") + tTransportRule.Field("endPoint", "String", false, nil, "source or destination endpoints defined in terms of CIDR notation") + tTransportRule.Field("sourcePortRange", "String", false, nil, "range of port numbers for incoming connections") + tTransportRule.Field("port", "Int32", false, nil, "destination / listener port of the service") + tTransportRule.Field("protocol", "String", false, nil, "protocol of the connection") + sb.AddType(tTransportRule.Build()) + + tTransportRules := rdl.NewStructTypeBuilder("Struct", "TransportRules") + tTransportRules.ArrayField("ingressRules", "TransportRule", false, "") + tTransportRules.ArrayField("egressRules", "TransportRule", false, "") + sb.AddType(tTransportRules.Build()) + mGetResourceAccess := rdl.NewResourceBuilder("ResourceAccess", "GET", "/access/{action}/{resource}") mGetResourceAccess.Comment("Check access for the specified operation on the specified resource for the currently authenticated user. This is the slow centralized access for control-plane purposes. Use distributed mechanisms for decentralized (data-plane) access by fetching signed policies and role tokens for users. With this endpoint the resource is part of the uri and restricted to its strict definition of resource name. If needed, you can use the GetAccessExt api that allows resource name to be less restrictive.") mGetResourceAccess.Input("action", "ActionName", true, "", "", false, nil, "action as specified in the policy assertion, i.e. update or read") @@ -640,6 +666,40 @@ func init() { mPostRoleCertificateRequestExt.Exception("UNAUTHORIZED", "ResourceError", "") sb.AddResource(mPostRoleCertificateRequestExt.Build()) + mGetWorkloadsByService := rdl.NewResourceBuilder("Workloads", "GET", "/domain/{domainName}/service/{serviceName}/workloads") + mGetWorkloadsByService.Name("getWorkloadsByService") + mGetWorkloadsByService.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain") + mGetWorkloadsByService.Input("serviceName", "EntityName", true, "", "", false, nil, "name of the service") + mGetWorkloadsByService.Auth("", "", true, "") + mGetWorkloadsByService.Exception("BAD_REQUEST", "ResourceError", "") + mGetWorkloadsByService.Exception("FORBIDDEN", "ResourceError", "") + mGetWorkloadsByService.Exception("NOT_FOUND", "ResourceError", "") + mGetWorkloadsByService.Exception("TOO_MANY_REQUESTS", "ResourceError", "") + mGetWorkloadsByService.Exception("UNAUTHORIZED", "ResourceError", "") + sb.AddResource(mGetWorkloadsByService.Build()) + + mGetWorkloadsByIP := rdl.NewResourceBuilder("Workloads", "GET", "/workloads/{ip}") + mGetWorkloadsByIP.Name("getWorkloadsByIP") + mGetWorkloadsByIP.Input("ip", "String", true, "", "", false, nil, "ip address to query") + mGetWorkloadsByIP.Auth("", "", true, "") + mGetWorkloadsByIP.Exception("BAD_REQUEST", "ResourceError", "") + mGetWorkloadsByIP.Exception("FORBIDDEN", "ResourceError", "") + mGetWorkloadsByIP.Exception("NOT_FOUND", "ResourceError", "") + mGetWorkloadsByIP.Exception("TOO_MANY_REQUESTS", "ResourceError", "") + mGetWorkloadsByIP.Exception("UNAUTHORIZED", "ResourceError", "") + sb.AddResource(mGetWorkloadsByIP.Build()) + + mGetTransportRules := rdl.NewResourceBuilder("TransportRules", "GET", "/domain/{domainName}/service/{serviceName}/transportRules") + mGetTransportRules.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain") + mGetTransportRules.Input("serviceName", "EntityName", true, "", "", false, nil, "name of the service") + mGetTransportRules.Auth("", "", true, "") + mGetTransportRules.Exception("BAD_REQUEST", "ResourceError", "") + mGetTransportRules.Exception("FORBIDDEN", "ResourceError", "") + mGetTransportRules.Exception("NOT_FOUND", "ResourceError", "") + mGetTransportRules.Exception("TOO_MANY_REQUESTS", "ResourceError", "") + mGetTransportRules.Exception("UNAUTHORIZED", "ResourceError", "") + sb.AddResource(mGetTransportRules.Build()) + var err error schema, err = sb.BuildParanoid() if err != nil { diff --git a/clients/java/zts/core/pom.xml b/clients/java/zts/core/pom.xml index a620b0ffd96..6b180783ce1 100644 --- a/clients/java/zts/core/pom.xml +++ b/clients/java/zts/core/pom.xml @@ -38,7 +38,7 @@ - 0.63 + 0.62 @@ -277,6 +277,19 @@ + + org.openclover + clover-maven-plugin + 4.3.1 + + 11 + + + **/ZTSRDLGeneratedClient.java + **/*Mock.java + + + diff --git a/clients/java/zts/core/src/main/java/com/yahoo/athenz/zts/ZTSRDLGeneratedClient.java b/clients/java/zts/core/src/main/java/com/yahoo/athenz/zts/ZTSRDLGeneratedClient.java index 46a6364bba6..e4bd57aa12e 100644 --- a/clients/java/zts/core/src/main/java/com/yahoo/athenz/zts/ZTSRDLGeneratedClient.java +++ b/clients/java/zts/core/src/main/java/com/yahoo/athenz/zts/ZTSRDLGeneratedClient.java @@ -551,4 +551,63 @@ public RoleCertificate postRoleCertificateRequestExt(RoleCertificateRequest req) } + public Workloads getWorkloadsByService(String domainName, String serviceName) { + WebTarget target = base.path("/domain/{domainName}/service/{serviceName}/workloads") + .resolveTemplate("domainName", domainName) + .resolveTemplate("serviceName", serviceName); + Invocation.Builder invocationBuilder = target.request("application/json"); + if (credsHeader != null) { + invocationBuilder = credsHeader.startsWith("Cookie.") ? invocationBuilder.cookie(credsHeader.substring(7), + credsToken) : invocationBuilder.header(credsHeader, credsToken); + } + Response response = invocationBuilder.get(); + int code = response.getStatus(); + switch (code) { + case 200: + return response.readEntity(Workloads.class); + default: + throw new ResourceException(code, response.readEntity(ResourceError.class)); + } + + } + + public Workloads getWorkloadsByIP(String ip) { + WebTarget target = base.path("/workloads/{ip}") + .resolveTemplate("ip", ip); + Invocation.Builder invocationBuilder = target.request("application/json"); + if (credsHeader != null) { + invocationBuilder = credsHeader.startsWith("Cookie.") ? invocationBuilder.cookie(credsHeader.substring(7), + credsToken) : invocationBuilder.header(credsHeader, credsToken); + } + Response response = invocationBuilder.get(); + int code = response.getStatus(); + switch (code) { + case 200: + return response.readEntity(Workloads.class); + default: + throw new ResourceException(code, response.readEntity(ResourceError.class)); + } + + } + + public TransportRules getTransportRules(String domainName, String serviceName) { + WebTarget target = base.path("/domain/{domainName}/service/{serviceName}/transportRules") + .resolveTemplate("domainName", domainName) + .resolveTemplate("serviceName", serviceName); + Invocation.Builder invocationBuilder = target.request("application/json"); + if (credsHeader != null) { + invocationBuilder = credsHeader.startsWith("Cookie.") ? invocationBuilder.cookie(credsHeader.substring(7), + credsToken) : invocationBuilder.header(credsHeader, credsToken); + } + Response response = invocationBuilder.get(); + int code = response.getStatus(); + switch (code) { + case 200: + return response.readEntity(TransportRules.class); + default: + throw new ResourceException(code, response.readEntity(ResourceError.class)); + } + + } + } diff --git a/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRule.java b/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRule.java new file mode 100644 index 00000000000..3a160fd4c4b --- /dev/null +++ b/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRule.java @@ -0,0 +1,71 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.zts; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.yahoo.rdl.*; + +// +// TransportRule - Copyright The Athenz Authors Licensed under the terms of the +// Apache version 2.0 license. See LICENSE file for terms. +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class TransportRule { + public String endPoint; + public String sourcePortRange; + public int port; + public String protocol; + + public TransportRule setEndPoint(String endPoint) { + this.endPoint = endPoint; + return this; + } + public String getEndPoint() { + return endPoint; + } + public TransportRule setSourcePortRange(String sourcePortRange) { + this.sourcePortRange = sourcePortRange; + return this; + } + public String getSourcePortRange() { + return sourcePortRange; + } + public TransportRule setPort(int port) { + this.port = port; + return this; + } + public int getPort() { + return port; + } + public TransportRule setProtocol(String protocol) { + this.protocol = protocol; + return this; + } + public String getProtocol() { + return protocol; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != TransportRule.class) { + return false; + } + TransportRule a = (TransportRule) another; + if (endPoint == null ? a.endPoint != null : !endPoint.equals(a.endPoint)) { + return false; + } + if (sourcePortRange == null ? a.sourcePortRange != null : !sourcePortRange.equals(a.sourcePortRange)) { + return false; + } + if (port != a.port) { + return false; + } + if (protocol == null ? a.protocol != null : !protocol.equals(a.protocol)) { + return false; + } + } + return true; + } +} diff --git a/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRules.java b/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRules.java new file mode 100644 index 00000000000..76487924192 --- /dev/null +++ b/core/zts/src/main/java/com/yahoo/athenz/zts/TransportRules.java @@ -0,0 +1,49 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.zts; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.List; +import com.yahoo.rdl.*; + +// +// TransportRules - +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class TransportRules { + public List ingressRules; + public List egressRules; + + public TransportRules setIngressRules(List ingressRules) { + this.ingressRules = ingressRules; + return this; + } + public List getIngressRules() { + return ingressRules; + } + public TransportRules setEgressRules(List egressRules) { + this.egressRules = egressRules; + return this; + } + public List getEgressRules() { + return egressRules; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != TransportRules.class) { + return false; + } + TransportRules a = (TransportRules) another; + if (ingressRules == null ? a.ingressRules != null : !ingressRules.equals(a.ingressRules)) { + return false; + } + if (egressRules == null ? a.egressRules != null : !egressRules.equals(a.egressRules)) { + return false; + } + } + return true; + } +} diff --git a/core/zts/src/main/java/com/yahoo/athenz/zts/Workload.java b/core/zts/src/main/java/com/yahoo/athenz/zts/Workload.java new file mode 100644 index 00000000000..ace856b546d --- /dev/null +++ b/core/zts/src/main/java/com/yahoo/athenz/zts/Workload.java @@ -0,0 +1,93 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.zts; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.List; +import com.yahoo.rdl.*; + +// +// Workload - +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class Workload { + public String domainName; + public String serviceName; + public String uuid; + public List ipAddresses; + public String provider; + public Timestamp updateTime; + + public Workload setDomainName(String domainName) { + this.domainName = domainName; + return this; + } + public String getDomainName() { + return domainName; + } + public Workload setServiceName(String serviceName) { + this.serviceName = serviceName; + return this; + } + public String getServiceName() { + return serviceName; + } + public Workload setUuid(String uuid) { + this.uuid = uuid; + return this; + } + public String getUuid() { + return uuid; + } + public Workload setIpAddresses(List ipAddresses) { + this.ipAddresses = ipAddresses; + return this; + } + public List getIpAddresses() { + return ipAddresses; + } + public Workload setProvider(String provider) { + this.provider = provider; + return this; + } + public String getProvider() { + return provider; + } + public Workload setUpdateTime(Timestamp updateTime) { + this.updateTime = updateTime; + return this; + } + public Timestamp getUpdateTime() { + return updateTime; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != Workload.class) { + return false; + } + Workload a = (Workload) another; + if (domainName == null ? a.domainName != null : !domainName.equals(a.domainName)) { + return false; + } + if (serviceName == null ? a.serviceName != null : !serviceName.equals(a.serviceName)) { + return false; + } + if (uuid == null ? a.uuid != null : !uuid.equals(a.uuid)) { + return false; + } + if (ipAddresses == null ? a.ipAddresses != null : !ipAddresses.equals(a.ipAddresses)) { + return false; + } + if (provider == null ? a.provider != null : !provider.equals(a.provider)) { + return false; + } + if (updateTime == null ? a.updateTime != null : !updateTime.equals(a.updateTime)) { + return false; + } + } + return true; + } +} diff --git a/core/zts/src/main/java/com/yahoo/athenz/zts/Workloads.java b/core/zts/src/main/java/com/yahoo/athenz/zts/Workloads.java new file mode 100644 index 00000000000..c92fc09dab0 --- /dev/null +++ b/core/zts/src/main/java/com/yahoo/athenz/zts/Workloads.java @@ -0,0 +1,38 @@ +// +// This file generated by rdl 1.5.2. Do not modify! +// + +package com.yahoo.athenz.zts; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import java.util.List; +import com.yahoo.rdl.*; + +// +// Workloads - +// +@JsonIgnoreProperties(ignoreUnknown = true) +public class Workloads { + public List workloadList; + + public Workloads setWorkloadList(List workloadList) { + this.workloadList = workloadList; + return this; + } + public List getWorkloadList() { + return workloadList; + } + + @Override + public boolean equals(Object another) { + if (this != another) { + if (another == null || another.getClass() != Workloads.class) { + return false; + } + Workloads a = (Workloads) another; + if (workloadList == null ? a.workloadList != null : !workloadList.equals(a.workloadList)) { + return false; + } + } + return true; + } +} diff --git a/core/zts/src/main/java/com/yahoo/athenz/zts/ZTSSchema.java b/core/zts/src/main/java/com/yahoo/athenz/zts/ZTSSchema.java index c9dd0b0ff2f..71359b6f103 100644 --- a/core/zts/src/main/java/com/yahoo/athenz/zts/ZTSSchema.java +++ b/core/zts/src/main/java/com/yahoo/athenz/zts/ZTSSchema.java @@ -332,6 +332,28 @@ private static Schema build() { .comment("Copyright 2019 Oath Holdings Inc Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. RoleCertificate - a role certificate") .field("x509Certificate", "String", false, ""); + sb.structType("Workload") + .field("domainName", "DomainName", false, "name of the domain, optional for getWorkloadsByService API call") + .field("serviceName", "EntityName", false, "name of the service, , optional for getWorkloadsByService API call") + .field("uuid", "String", false, "unique identifier for the workload, usually defined by provider") + .arrayField("ipAddresses", "String", false, "list of IP addresses associated with the workload, optional for getWorkloadsByIP API call") + .field("provider", "String", false, "infrastructure provider e.g. k8s, AWS, Azure, openstack etc.") + .field("updateTime", "Timestamp", false, "most recent update timestamp in the backend"); + + sb.structType("Workloads") + .arrayField("workloadList", "Workload", false, "list of workloads"); + + sb.structType("TransportRule") + .comment("Copyright The Athenz Authors Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms.") + .field("endPoint", "String", false, "source or destination endpoints defined in terms of CIDR notation") + .field("sourcePortRange", "String", false, "range of port numbers for incoming connections") + .field("port", "Int32", false, "destination / listener port of the service") + .field("protocol", "String", false, "protocol of the connection"); + + sb.structType("TransportRules") + .arrayField("ingressRules", "TransportRule", false, "") + .arrayField("egressRules", "TransportRule", false, ""); + sb.resource("ResourceAccess", "GET", "/access/{action}/{resource}") .comment("Check access for the specified operation on the specified resource for the currently authenticated user. This is the slow centralized access for control-plane purposes. Use distributed mechanisms for decentralized (data-plane) access by fetching signed policies and role tokens for users. With this endpoint the resource is part of the uri and restricted to its strict definition of resource name. If needed, you can use the GetAccessExt api that allows resource name to be less restrictive.") @@ -665,6 +687,55 @@ private static Schema build() { .exception("UNAUTHORIZED", "ResourceError", "") ; + sb.resource("Workloads", "GET", "/domain/{domainName}/service/{serviceName}/workloads") + .name("getWorkloadsByService") + .pathParam("domainName", "DomainName", "name of the domain") + .pathParam("serviceName", "EntityName", "name of the service") + .auth("", "", true) + .expected("OK") + .exception("BAD_REQUEST", "ResourceError", "") + + .exception("FORBIDDEN", "ResourceError", "") + + .exception("NOT_FOUND", "ResourceError", "") + + .exception("TOO_MANY_REQUESTS", "ResourceError", "") + + .exception("UNAUTHORIZED", "ResourceError", "") +; + + sb.resource("Workloads", "GET", "/workloads/{ip}") + .name("getWorkloadsByIP") + .pathParam("ip", "String", "ip address to query") + .auth("", "", true) + .expected("OK") + .exception("BAD_REQUEST", "ResourceError", "") + + .exception("FORBIDDEN", "ResourceError", "") + + .exception("NOT_FOUND", "ResourceError", "") + + .exception("TOO_MANY_REQUESTS", "ResourceError", "") + + .exception("UNAUTHORIZED", "ResourceError", "") +; + + sb.resource("TransportRules", "GET", "/domain/{domainName}/service/{serviceName}/transportRules") + .pathParam("domainName", "DomainName", "name of the domain") + .pathParam("serviceName", "EntityName", "name of the service") + .auth("", "", true) + .expected("OK") + .exception("BAD_REQUEST", "ResourceError", "") + + .exception("FORBIDDEN", "ResourceError", "") + + .exception("NOT_FOUND", "ResourceError", "") + + .exception("TOO_MANY_REQUESTS", "ResourceError", "") + + .exception("UNAUTHORIZED", "ResourceError", "") +; + return sb.build(); } diff --git a/core/zts/src/main/rdl/TransportRule.rdli b/core/zts/src/main/rdl/TransportRule.rdli new file mode 100644 index 00000000000..2e636ce19be --- /dev/null +++ b/core/zts/src/main/rdl/TransportRule.rdli @@ -0,0 +1,20 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +//Workload types +include "TransportRule.tdl"; +include "Names.tdl"; + +resource TransportRules GET "/domain/{domainName}/service/{serviceName}/transportRules" { + DomainName domainName; // name of the domain + EntityName serviceName; // name of the service + + authenticate; + exceptions { + ResourceError BAD_REQUEST; + ResourceError NOT_FOUND; + ResourceError FORBIDDEN; + ResourceError UNAUTHORIZED; + ResourceError TOO_MANY_REQUESTS; + } +} \ No newline at end of file diff --git a/core/zts/src/main/rdl/TransportRule.tdl b/core/zts/src/main/rdl/TransportRule.tdl new file mode 100644 index 00000000000..56217b4d190 --- /dev/null +++ b/core/zts/src/main/rdl/TransportRule.tdl @@ -0,0 +1,14 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +type TransportRule Struct { + String endPoint; // source or destination endpoints defined in terms of CIDR notation + String sourcePortRange; // range of port numbers for incoming connections + Int32 port; // destination / listener port of the service + String protocol; // protocol of the connection +} + +type TransportRules Struct { + Array ingressRules; + Array egressRules; +} \ No newline at end of file diff --git a/core/zts/src/main/rdl/Workload.rdli b/core/zts/src/main/rdl/Workload.rdli new file mode 100644 index 00000000000..af68b0a3ec5 --- /dev/null +++ b/core/zts/src/main/rdl/Workload.rdli @@ -0,0 +1,33 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +//Workload types +include "Workload.tdl"; +include "Names.tdl"; + +resource Workloads GET "/domain/{domainName}/service/{serviceName}/workloads" (name=getWorkloadsByService) { + DomainName domainName; // name of the domain + EntityName serviceName; // name of the service + + authenticate; + exceptions { + ResourceError BAD_REQUEST; + ResourceError NOT_FOUND; + ResourceError FORBIDDEN; + ResourceError UNAUTHORIZED; + ResourceError TOO_MANY_REQUESTS; + } +} + +resource Workloads GET "/workloads/{ip}" (name=getWorkloadsByIP) { + String ip; // ip address to query + + authenticate; + exceptions { + ResourceError BAD_REQUEST; + ResourceError NOT_FOUND; + ResourceError FORBIDDEN; + ResourceError UNAUTHORIZED; + ResourceError TOO_MANY_REQUESTS; + } +} diff --git a/core/zts/src/main/rdl/Workload.tdl b/core/zts/src/main/rdl/Workload.tdl new file mode 100644 index 00000000000..8a50a8162b7 --- /dev/null +++ b/core/zts/src/main/rdl/Workload.tdl @@ -0,0 +1,18 @@ +// Copyright The Athenz Authors +// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. + +//Name types +include "Names.tdl"; + +type Workload Struct { + DomainName domainName; // name of the domain, optional for getWorkloadsByService API call + EntityName serviceName; // name of the service, , optional for getWorkloadsByService API call + String uuid; // unique identifier for the workload, usually defined by provider + Array ipAddresses; // list of IP addresses associated with the workload, optional for getWorkloadsByIP API call + String provider; // infrastructure provider e.g. k8s, AWS, Azure, openstack etc. + Timestamp updateTime; // most recent update timestamp in the backend +} + +type Workloads Struct { + Array workloadList; // list of workloads +} diff --git a/core/zts/src/main/rdl/ZTS.rdl b/core/zts/src/main/rdl/ZTS.rdl index 2b90ea14bcd..c7754c17d8a 100644 --- a/core/zts/src/main/rdl/ZTS.rdl +++ b/core/zts/src/main/rdl/ZTS.rdl @@ -21,3 +21,5 @@ include "Status.rdli"; include "SSHCert.rdli"; include "OAauth.rdli"; include "RoleCert.rdli"; +include "Workload.rdli"; +include "TransportRule.rdli"; diff --git a/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRuleTest.java b/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRuleTest.java new file mode 100644 index 00000000000..ca7f5b71f25 --- /dev/null +++ b/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRuleTest.java @@ -0,0 +1,65 @@ +/* + * 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.zts; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class TransportRuleTest { + @Test + public void testTransportRuleFields() { + TransportRule tr1 = new TransportRule(); + tr1.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + assertNotNull(tr1); + assertEquals(tr1.getEndPoint(), "10.20.30.40/26"); + assertEquals(tr1.getPort(), 4443); + assertEquals(tr1.getProtocol(), "TCP"); + assertEquals(tr1.getSourcePortRange(), "1024-65535"); + assertEquals(tr1, tr1); + + TransportRule tr2 = new TransportRule(); + tr2.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + + assertEquals(tr1, tr2); + + tr2.setEndPoint("20.20.30.40/26"); + assertNotEquals(tr1, tr2); + + tr2.setEndPoint("10.20.30.40/26"); + tr2.setPort(8443); + assertNotEquals(tr1, tr2); + + tr2.setPort(4443); + tr2.setProtocol("UDP"); + assertNotEquals(tr1, tr2); + + tr2.setProtocol("TCP"); + tr2.setSourcePortRange("49152-65535"); + assertNotEquals(tr1, tr2); + + tr2.setSourcePortRange("1024-65535"); + assertEquals(tr1, tr2); + + assertNotEquals(tr1, null); + // for code coverage + assertFalse(tr1.equals("mystring")); + assertNotEquals(tr1, "mystring"); + + assertEquals(tr1, tr1); + + } +} \ No newline at end of file diff --git a/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRulesTest.java b/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRulesTest.java new file mode 100644 index 00000000000..a9c83ab4b0e --- /dev/null +++ b/core/zts/src/test/java/com/yahoo/athenz/zts/TransportRulesTest.java @@ -0,0 +1,81 @@ +/* + * 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.zts; + +import org.testng.annotations.Test; + +import java.util.Collections; +import java.util.List; + +import static org.testng.Assert.*; + +public class TransportRulesTest { + @Test + public void testTransportRulesFields() { + TransportRules trs1 = new TransportRules(); + TransportRule tr1 = new TransportRule(); + tr1.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + + TransportRule tr2 = new TransportRule(); + tr2.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + + List ingressTransportRules1 = Collections.singletonList(tr1); + List egressTransportRules1 = Collections.singletonList(tr2); + + trs1.setIngressRules(ingressTransportRules1); + trs1.setEgressRules(egressTransportRules1); + + assertNotNull(trs1.getIngressRules()); + assertNotNull(trs1.getEgressRules()); + + TransportRules trs2 = new TransportRules(); + TransportRule tr21 = new TransportRule(); + tr2.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + + TransportRule tr22 = new TransportRule(); + tr2.setEndPoint("10.20.30.40/26").setPort(4443).setProtocol("TCP").setSourcePortRange("1024-65535"); + + List ingressTransportRules2 = Collections.singletonList(tr21); + + List egressTransportRules2 = Collections.singletonList(tr22); + + trs2.setIngressRules(ingressTransportRules2); + trs2.setEgressRules(egressTransportRules2); + + assertNotNull(trs2.getIngressRules()); + assertNotNull(trs2.getEgressRules()); + + assertNotEquals(trs1, trs2); + + trs2.setIngressRules(ingressTransportRules1); + trs2.setEgressRules(ingressTransportRules1); + + assertEquals(trs1, trs2); + + trs1.setIngressRules(null); + assertNotEquals(trs1, trs2); + + trs1.setIngressRules(ingressTransportRules1); + trs1.setEgressRules(null); + assertNotEquals(trs1, trs2); + + // for code coverage + assertFalse(trs1.equals("anotherstring")); + + assertNotEquals(trs1, null); + assertNotEquals(trs1, "mystring"); + } +} \ No newline at end of file diff --git a/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadTest.java b/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadTest.java new file mode 100644 index 00000000000..01369d96c05 --- /dev/null +++ b/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadTest.java @@ -0,0 +1,84 @@ +/* + * 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.zts; + +import com.yahoo.rdl.Timestamp; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.testng.Assert.*; + +public class WorkloadTest { + @Test + public void testWorkloadFields() { + Workload wl1 = new Workload(); + List ipAddresses = Collections.singletonList("10.20.30.40"); + wl1.setDomainName("athenz").setServiceName("api").setIpAddresses(ipAddresses).setProvider("kubernetes").setUuid("1234-rsaq-422dcz") + .setUpdateTime(Timestamp.fromMillis(123456789123L)); + + assertNotNull(wl1); + assertEquals(wl1.getDomainName(), "athenz"); + assertEquals(wl1.getServiceName(), "api"); + assertEquals(wl1.getIpAddresses(), ipAddresses); + assertEquals(wl1.getProvider(), "kubernetes"); + assertEquals(wl1.getUuid(), "1234-rsaq-422dcz"); + assertEquals(wl1.getUpdateTime(), Timestamp.fromMillis(123456789123L)); + assertEquals(wl1, wl1); + + Workload wl2 = new Workload(); + wl2.setDomainName("athenz").setServiceName("api").setIpAddresses(ipAddresses).setProvider("kubernetes").setUuid("1234-rsaq-422dcz") + .setUpdateTime(Timestamp.fromMillis(123456789123L)); + + assertEquals(wl1, wl2); + + wl2.setDomainName("sports"); + assertNotEquals(wl1, wl2); + + wl2.setDomainName("athenz"); + wl2.setServiceName("apiv2"); + assertNotEquals(wl1, wl2); + + wl2.setServiceName("api"); + wl2.setIpAddresses(null); + assertNotEquals(wl1, wl2); + + wl2.setIpAddresses(ipAddresses); + wl2.setProvider("aws"); + assertNotEquals(wl1, wl2); + + wl2.setProvider("kubernetes"); + wl2.setUuid("23rwf-ews-13"); + assertNotEquals(wl1, wl2); + + wl2.setUuid("1234-rsaq-422dcz"); + wl2.setUpdateTime(Timestamp.fromMillis(123456789456L)); + assertNotEquals(wl1, wl2); + + wl2.setUpdateTime(Timestamp.fromMillis(123456789123L)); + assertEquals(wl1, wl2); + + assertNotEquals(wl1, null); + // for code coverage + assertFalse(wl1.equals("mystring")); + assertNotEquals(wl1, "mystring"); + + assertEquals(wl1, wl1); + + } +} \ No newline at end of file diff --git a/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadsTest.java b/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadsTest.java new file mode 100644 index 00000000000..04f6738a7f7 --- /dev/null +++ b/core/zts/src/test/java/com/yahoo/athenz/zts/WorkloadsTest.java @@ -0,0 +1,65 @@ +/* + * 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.zts; + +import com.yahoo.rdl.Timestamp; +import org.testng.annotations.Test; + +import java.util.Collections; +import java.util.List; + +import static org.testng.Assert.*; + +public class WorkloadsTest { + @Test + public void testWorkloadsFields() { + Workloads workloads1 = new Workloads(); + Workload wl1 = new Workload(); + List ipAddresses = Collections.singletonList("10.20.30.40"); + wl1.setDomainName("athenz").setServiceName("api").setIpAddresses(ipAddresses).setProvider("kubernetes").setUuid("1234-rsaq-422dcz") + .setUpdateTime(Timestamp.fromMillis(123456789123L)); + + List workloadList1 = Collections.singletonList(wl1); + + workloads1.setWorkloadList(workloadList1); + + assertNotNull(workloads1.getWorkloadList()); + + Workloads workloads2 = new Workloads(); + Workload wl2 = new Workload(); + wl2.setDomainName("athenz").setServiceName("api").setIpAddresses(ipAddresses).setProvider("kubernetes").setUuid("1234-rsaq-422dcz") + .setUpdateTime(Timestamp.fromMillis(123456789123L)); + + List workloadList2 = Collections.singletonList(wl2); + workloads2.setWorkloadList(workloadList2); + + assertNotNull(workloads2.getWorkloadList()); + + workloads2.setWorkloadList(workloadList1); + assertEquals(workloads1, workloads2); + + workloads1.setWorkloadList(null); + assertNotEquals(workloads1, workloads2); + + workloads1.setWorkloadList(workloadList1); + + // for code coverage + assertFalse(workloads1.equals("anotherstring")); + + assertNotEquals(workloads1, null); + assertNotEquals(workloads1, "mystring"); + } +} \ No newline at end of file diff --git a/go.mod b/go.mod index 0744409b562..32140242fc9 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,13 @@ module github.com/AthenZ/athenz require ( github.com/BurntSushi/toml v0.3.1 // indirect github.com/ardielle/ardielle-go v1.5.2 + github.com/ardielle/ardielle-tools v1.5.4 // indirect github.com/aws/aws-sdk-go v1.32.6 github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dimfeld/httptreemux v5.0.1+incompatible github.com/gorilla/mux v1.7.4 + github.com/jawher/mow.cli v1.1.0 // indirect github.com/kr/pretty v0.2.0 // indirect github.com/stretchr/testify v1.5.1 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 diff --git a/go.sum b/go.sum index 0597b330c44..50d5c722233 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ardielle/ardielle-go v1.5.2 h1:TilHTpHIQJ27R1Tl/iITBzMwiUGSlVfiVhwDNGM3Zj4= github.com/ardielle/ardielle-go v1.5.2/go.mod h1:I4hy1n795cUhaVt/ojz83SNVCYIGsAFAONtv2Dr7HUI= +github.com/ardielle/ardielle-tools v1.5.4 h1:2uL/7wZRUF4LGV7r2eTaaeyhkBoqdiqEitSXMd6k8F8= +github.com/ardielle/ardielle-tools v1.5.4/go.mod h1:oZN+JRMnqGiIhrzkRN9l26Cej9dEx4jeNG6A+AdkShk= github.com/aws/aws-sdk-go v1.32.6 h1:HoswAabUWgnrUF7X/9dr4WRgrr8DyscxXvTDm7Qw/5c= github.com/aws/aws-sdk-go v1.32.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -14,6 +16,9 @@ github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk= +github.com/jawher/mow.cli v1.1.0 h1:NdtHXRc0CwZQ507wMvQ/IS+Q3W3x2fycn973/b8Zuk8= +github.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= @@ -26,6 +31,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSHandler.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSHandler.java index 13577687774..ac9e8df9c5f 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSHandler.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSHandler.java @@ -35,6 +35,9 @@ public interface ZTSHandler { JWKList getJWKList(ResourceContext context, Boolean rfc); AccessTokenResponse postAccessTokenRequest(ResourceContext context, String request); RoleCertificate postRoleCertificateRequestExt(ResourceContext context, RoleCertificateRequest req); + Workloads getWorkloadsByService(ResourceContext context, String domainName, String serviceName); + Workloads getWorkloadsByIP(ResourceContext context, String ip); + TransportRules getTransportRules(ResourceContext context, String domainName, String serviceName); Schema getRdlSchema(ResourceContext context); ResourceContext newResourceContext(HttpServletRequest request, HttpServletResponse response, String apiName); void recordMetrics(ResourceContext ctx, int httpStatus); diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java index 820c82ef514..87b64574ed1 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSImpl.java @@ -2282,6 +2282,24 @@ public RoleCertificate postRoleCertificateRequestExt(ResourceContext ctx, RoleCe return roleCertificate; } + @Override + public Workloads getWorkloadsByService(ResourceContext context, String domainName, String serviceName) { + // to be implemented in next PR + return null; + } + + @Override + public Workloads getWorkloadsByIP(ResourceContext context, String ip) { + // to be implemented in next PR + return null; + } + + @Override + public TransportRules getTransportRules(ResourceContext context, String domainName, String serviceName) { + // to be implemented in next PR + return null; + } + boolean isAuthorizedServicePrincipal(final Principal principal) { final String authorizedService = principal.getAuthorizedService(); return (authorizedService != null && !authorizedService.isEmpty()); diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSResources.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSResources.java index 53b152f86a7..3ea2aadd468 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSResources.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/ZTSResources.java @@ -772,6 +772,110 @@ public RoleCertificate postRoleCertificateRequestExt( } } + @GET + @Path("/domain/{domainName}/service/{serviceName}/workloads") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "") + public Workloads getWorkloadsByService( + @Parameter(description = "name of the domain", required = true) @PathParam("domainName") String domainName, + @Parameter(description = "name of the service", required = true) @PathParam("serviceName") String serviceName) { + int code = ResourceException.OK; + ResourceContext context = null; + try { + context = this.delegate.newResourceContext(this.request, this.response, "getWorkloadsByService"); + context.authenticate(); + return this.delegate.getWorkloadsByService(context, domainName, serviceName); + } catch (ResourceException e) { + code = e.getCode(); + switch (code) { + case ResourceException.BAD_REQUEST: + throw typedException(code, e, ResourceError.class); + case ResourceException.FORBIDDEN: + throw typedException(code, e, ResourceError.class); + case ResourceException.NOT_FOUND: + throw typedException(code, e, ResourceError.class); + case ResourceException.TOO_MANY_REQUESTS: + throw typedException(code, e, ResourceError.class); + case ResourceException.UNAUTHORIZED: + throw typedException(code, e, ResourceError.class); + default: + System.err.println("*** Warning: undeclared exception (" + code + ") for resource getWorkloadsByService"); + throw typedException(code, e, ResourceError.class); + } + } finally { + this.delegate.recordMetrics(context, code); + } + } + + @GET + @Path("/workloads/{ip}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "") + public Workloads getWorkloadsByIP( + @Parameter(description = "ip address to query", required = true) @PathParam("ip") String ip) { + int code = ResourceException.OK; + ResourceContext context = null; + try { + context = this.delegate.newResourceContext(this.request, this.response, "getWorkloadsByIP"); + context.authenticate(); + return this.delegate.getWorkloadsByIP(context, ip); + } catch (ResourceException e) { + code = e.getCode(); + switch (code) { + case ResourceException.BAD_REQUEST: + throw typedException(code, e, ResourceError.class); + case ResourceException.FORBIDDEN: + throw typedException(code, e, ResourceError.class); + case ResourceException.NOT_FOUND: + throw typedException(code, e, ResourceError.class); + case ResourceException.TOO_MANY_REQUESTS: + throw typedException(code, e, ResourceError.class); + case ResourceException.UNAUTHORIZED: + throw typedException(code, e, ResourceError.class); + default: + System.err.println("*** Warning: undeclared exception (" + code + ") for resource getWorkloadsByIP"); + throw typedException(code, e, ResourceError.class); + } + } finally { + this.delegate.recordMetrics(context, code); + } + } + + @GET + @Path("/domain/{domainName}/service/{serviceName}/transportRules") + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "") + public TransportRules getTransportRules( + @Parameter(description = "name of the domain", required = true) @PathParam("domainName") String domainName, + @Parameter(description = "name of the service", required = true) @PathParam("serviceName") String serviceName) { + int code = ResourceException.OK; + ResourceContext context = null; + try { + context = this.delegate.newResourceContext(this.request, this.response, "getTransportRules"); + context.authenticate(); + return this.delegate.getTransportRules(context, domainName, serviceName); + } catch (ResourceException e) { + code = e.getCode(); + switch (code) { + case ResourceException.BAD_REQUEST: + throw typedException(code, e, ResourceError.class); + case ResourceException.FORBIDDEN: + throw typedException(code, e, ResourceError.class); + case ResourceException.NOT_FOUND: + throw typedException(code, e, ResourceError.class); + case ResourceException.TOO_MANY_REQUESTS: + throw typedException(code, e, ResourceError.class); + case ResourceException.UNAUTHORIZED: + throw typedException(code, e, ResourceError.class); + default: + System.err.println("*** Warning: undeclared exception (" + code + ") for resource getTransportRules"); + throw typedException(code, e, ResourceError.class); + } + } finally { + this.delegate.recordMetrics(context, code); + } + } + @GET @Path("/schema") @Produces(MediaType.APPLICATION_JSON)