diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000000..52136798542
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+*~
+**/.classpath
+**/.project
+**/.settings
+**/target/
+**/dependency-reduced-pom.xml
+servers/zms/zms_logs/
+servers/zms/zms_root/
+servers/zts/zts_logs/
+servers/zts/zts_store/
+clients/go/zms/pkg/
+clients/go/zms/src/
+clients/go/zts/pkg/
+clients/go/zts/src/
+clients/java/sia/src/test/resources/svc.ntoken
+clients/java/zpe/src/test/resources/upd_pol_dir/
+ui/build/
+ui/node_modules/
+utils/zms_cli/zms-cli
+utils/zpe_policy_updater/tmp_metrics/
+utils/zpe_policy_updater/src/test/resources/sys.auth.new.pol
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 00000000000..6f46a6d0c03
--- /dev/null
+++ b/README.md
@@ -0,0 +1,65 @@
+
+
+Athenz is a set of services and libraries supporting role-based
+authorization (RBAC) for provisioning and configuration (centralized
+authorization) use cases as well as serving/runtime (decentralized
+authorization) use cases. Athenz authorization system utilizes two
+types of tokens: Principal Tokens (N-Tokens) and RoleTokens (Z-Tokens).
+The name "Athenz" is derived from "Auth" and the 'N' and 'Z' tokens.
+
+## Main features
+----------------
+
+Athenz provides both the functionality of a centralized system
+and a certificate and IP-based distributed system to handle
+on-box enforcement.
+
+You get the following advantages using Athenz:
+
+- **Service-based security profile:** Security definitions that
+ automatically trickle down to hosts within the service.
+- **Dynamic provisioning:** Scale fast or move workloads around
+ without manual intervention (IP-less configuration).
+- **Single source of truth:** Consolidated service profile serving
+ various downstream security implementations, including support for
+ non-user entities.
+- **Self-Service:** Real-time configuration and enforcement of
+ resource-based access control (dynamic manageability).
+
+More importantly, we want engineers to use Athenz and **not** build
+their own role-based access control systems that have no central store
+and often rely on network ACLs and manual updating.
+
+## Documentation
+----------------
+
+* Getting Started
+ * [Development Enviornment](docs/dev_environment.md)
+ * [Setup ZMS](docs/setup_zms.md)
+ * [Setup ZTS](docs/setup_zts.md)
+* Architecture
+ * [Data Model](docs/data_model.md)
+ * [System View](docs/system_view.md)
+ * [Authorization Flow](docs/auth_flow.md)
+* Developer Guide
+ * [Centralized Access Control](docs/dev_centralized_access.md)
+ * [Decentralized Access Control](docs/dev_decentralized_access.md)
+ * [System Properties](docs/system_properties.md)
+* User Guide
+ * [ZMS Client Utility](docs/zms_client.md)
+ * [Registering ZMS Service Identity](docs/reg_service_guide.md)
+
+## Contact
+----------
+
+* [Athenz-Dev](https://groups.google.com/d/forum/athenz-dev) for
+ development discussions
+* [Athenz-Users](https://groups.google.com/d/forum/athenz-users) for
+ users questions
+
+## License
+----------
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
diff --git a/assembly/components/zms.xml b/assembly/components/zms.xml
new file mode 100644
index 00000000000..ac0754b9566
--- /dev/null
+++ b/assembly/components/zms.xml
@@ -0,0 +1,87 @@
+
+
+
+ bin
+
+ tar.gz
+
+ true
+
+
+ ${basedir}/../servers/zms/conf
+ conf/zms_server
+
+
+ ${basedir}/../servers/zms/scripts
+ bin
+ 755
+
+ zms_start.sh
+
+
+
+ ${basedir}/../servers/zms/target/dependency
+ lib/jars
+
+
+ .
+ logs/zms_server
+
+ */**
+
+
+
+ .
+ var/zms_server/keys
+
+ */**
+
+
+
+ .
+ var/zms_server/certs
+
+ */**
+
+
+
+
+
+ ${basedir}/../servers/zms/README.md
+ .
+ 644
+
+
+ ${basedir}/../LICENSE
+ .
+ 644
+
+
+
+
+
+ com.yahoo.athenz:zms_server
+
+ lib/jars
+ false
+ runtime
+ false
+
+
+
diff --git a/assembly/components/zpu.xml b/assembly/components/zpu.xml
new file mode 100644
index 00000000000..62c4c8dc6f5
--- /dev/null
+++ b/assembly/components/zpu.xml
@@ -0,0 +1,90 @@
+
+
+
+ bin
+
+ tar.gz
+
+ true
+
+
+ ${basedir}/../utils/zpe_policy_updater/conf
+ conf/zpe_policy_updater
+
+
+ ${basedir}/../utils/zpe_policy_updater/scripts
+ bin
+ 755
+
+ zpu_run.sh
+
+
+
+ .
+ logs/zpe_policy_updater
+
+ */**
+
+
+
+ .
+ var/zpe
+
+ */**
+
+
+
+ .
+ tmp/zpe
+
+ */**
+
+
+
+ .
+ var/zpe_policy_updater/certs
+
+ */**
+
+
+
+
+
+ ${basedir}/../utils/zpe_policy_updater/README.md
+ .
+ 644
+
+
+ ${basedir}/../LICENSE
+ .
+ 644
+
+
+
+
+
+ com.yahoo.athenz:zpe_policy_updater
+
+ lib/jars
+ false
+ runtime
+ false
+
+
+
diff --git a/assembly/components/zts.xml b/assembly/components/zts.xml
new file mode 100644
index 00000000000..e65d5e54cb5
--- /dev/null
+++ b/assembly/components/zts.xml
@@ -0,0 +1,87 @@
+
+
+
+ bin
+
+ tar.gz
+
+ true
+
+
+ ${basedir}/../servers/zts/conf
+ conf/zts_server
+
+
+ ${basedir}/../servers/zts/scripts
+ bin
+ 755
+
+ zts_start.sh
+
+
+
+ ${basedir}/../servers/zts/target/dependency
+ lib/jars
+
+
+ .
+ logs/zts_server
+
+ */**
+
+
+
+ .
+ var/zts_server/keys
+
+ */**
+
+
+
+ .
+ var/zts_server/certs
+
+ */**
+
+
+
+
+
+ ${basedir}/../servers/zts/README.md
+ .
+ 644
+
+
+ ${basedir}/../LICENSE
+ .
+ 644
+
+
+
+
+
+ com.yahoo.athenz:zts_server
+
+ lib/jars
+ false
+ runtime
+ false
+
+
+
diff --git a/assembly/pom.xml b/assembly/pom.xml
new file mode 100644
index 00000000000..b92b2c522f3
--- /dev/null
+++ b/assembly/pom.xml
@@ -0,0 +1,99 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ assembly
+ assembly
+ pom
+
+
+
+ com.yahoo.athenz
+ zms_server
+ ${project.parent.version}
+
+
+ com.yahoo.athenz
+ zts_server
+ ${project.parent.version}
+
+
+ com.yahoo.athenz
+ zpe_policy_updater
+ ${project.parent.version}
+
+
+
+
+
+
+ maven-assembly-plugin
+ 2.6
+
+
+ package-zms-assembly
+ package
+
+ single
+
+
+ posix
+ athenz-zms-${project.version}
+
+ components/zms.xml
+
+
+
+
+ package-zts-assembly
+ package
+
+ single
+
+
+ posix
+ athenz-zts-${project.version}
+
+ components/zts.xml
+
+
+
+
+ package-zpu-assembly
+ package
+
+ single
+
+
+ posix
+ athenz-zpu-${project.version}
+
+ components/zpu.xml
+
+
+
+
+
+
+
+
diff --git a/clients/go/zms/Makefile b/clients/go/zms/Makefile
new file mode 100644
index 00000000000..6e6e2d4de6d
--- /dev/null
+++ b/clients/go/zms/Makefile
@@ -0,0 +1,20 @@
+RDL_FILE=../../../core/zms/src/main/rdl/ZMS.rdl
+RDL_LIB=github.com/ardielle/ardielle-go/rdl
+
+export GOPATH=$(PWD)
+
+all: model.go client.go build
+
+build: src/$(RDL_LIB)
+
+src/$(RDL_LIB):
+ go get $(RDL_LIB)
+
+model.go: $(RDL_FILE)
+ rdl -ps generate -t -o $@ go-model $(RDL_FILE)
+
+client.go: $(RDL_FILE)
+ rdl -ps generate -t -o $@ go-client $(RDL_FILE)
+
+clean::
+ rm -rf model.go client.go zms_schema.go *~ ./src
diff --git a/clients/go/zms/README.md b/clients/go/zms/README.md
new file mode 100644
index 00000000000..5aad5912dd1
--- /dev/null
+++ b/clients/go/zms/README.md
@@ -0,0 +1,54 @@
+# zms-go-client
+
+A Go client library to talk to Athenz ZMS.
+
+The model.go and client.go files are generated from zms_core, and checked in so users of this library need not know that.
+
+Additionally, an implementation of rdl.Authorizer and rdl.Authenticator are provided that use this library to delegate that functionality to Athenz ZMS:
+
+Release Notes:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Version 1.0 (2016-09-06)
+ - Initial opensource release
+
+## Usage
+
+To get it into your workspace:
+
+ go get github.com/yahoo/athenz/clients/go/zms
+
+Then in your Go code:
+
+ import (
+ zms "github.com/yahoo/athenz/clients/go/zms"
+ )
+ func main() {
+ var principal rdl.Principal /* init this from an actual user credential */
+ ...
+ client := zms.NewClient()
+ client.AddCredentials(principal.GetHTTPHeaderName(), principal.GetCredentials())
+ dmn, err := client.GetDomain("athenz") //
+ ...
+ }
+
+To use the ZMSAuthorizer from your RDL-generated server:
+
+ import (
+ zms "github.com/yahoo/athenz/clients/go/zms"
+ )
+ ...
+ endpoint := "localhost:4080"
+ domain := "your.server.domain"
+
+ zmsURL := "http://localhost:10080/zms/v1" //set this to "" for debug mode
+ authn := zms.Authenticator(zmsURL)
+ authz := zms.Authorizer(domain, zmsURL)
+
+ handler := contacts.Init(impl, url, authz, authn)
+ http.ListenAndServe(endpoint, handler)
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
diff --git a/clients/go/zms/auth.go b/clients/go/zms/auth.go
new file mode 100644
index 00000000000..49d640185f7
--- /dev/null
+++ b/clients/go/zms/auth.go
@@ -0,0 +1,112 @@
+// Copyright 2016 Yahoo Inc.
+// Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms.
+
+package zms
+
+import (
+ "fmt"
+ "github.com/ardielle/ardielle-go/rdl"
+ "log"
+ "strings"
+)
+
+//
+// Authenticator - an unoptimized authenticator that delegates to ZMS.
+// The advantage is that there is no local state or config other than the
+// url of ZMS (we don't need ZMS's public key to be local).
+//
+func Authenticator(url string) rdl.Authenticator {
+ return &zmsAuthenticator{url}
+}
+
+type zmsAuthenticator struct {
+ url string //i.e. "http://localhost:10080/zms/v1"
+}
+
+func (ath zmsAuthenticator) HTTPHeader() string {
+ return "Athenz-Principal-Auth"
+}
+
+func (ath zmsAuthenticator) Authenticate(nToken string) rdl.Principal {
+ attrs := make(map[string]string)
+ for _, attr := range strings.Split(nToken, ";") {
+ kv := strings.Split(attr, "=")
+ attrs[kv[0]] = kv[1]
+ }
+ if name, ok := attrs["n"]; ok {
+ if domain, ok := attrs["d"]; ok {
+ //do not verify the token, because we will just pass it off in the authorizer, where ZMS will do that.
+ log.Printf("[Authenticate %s.%s]\n", domain, name)
+ return zmsPrincipal{domain, name, nToken, ath.HTTPHeader()}
+ }
+ }
+ return nil
+}
+
+//zmsPrincipal implements rdl.Principal the interface
+type zmsPrincipal struct {
+ domain string
+ name string
+ creds string
+ header string
+}
+
+func (p zmsPrincipal) GetDomain() string {
+ return p.domain
+}
+
+func (p zmsPrincipal) GetName() string {
+ return p.name
+}
+
+func (p zmsPrincipal) GetYRN() string {
+ return p.domain + "." + p.name
+}
+
+func (p zmsPrincipal) GetCredentials() string {
+ return p.creds
+}
+
+func (p zmsPrincipal) GetHTTPHeaderName() string {
+ return p.header
+}
+
+//
+// Authorizer returns an authorizer that calls zms. If the url is set to
+// "", then the access is logged, but always succeeds (for debug purposes)
+//
+func Authorizer(domain string, url string) rdl.Authorizer {
+ return &zmsAuthorizer{domain: domain, url: url}
+}
+
+type zmsAuthorizer struct {
+ domain string
+ url string
+}
+
+func (auth zmsAuthorizer) Authorize(action string, resource string, principal rdl.Principal) (bool, error) {
+ //this should be done before getting here!
+ if strings.Index(resource, ":") < 0 {
+ //the resource is relative to the service's domain
+ resource = auth.domain + ":" + resource
+ }
+ if auth.url == "" {
+ log.Printf("[DEBUG Authorize %s on %s for %s]\n", action, resource, principal.GetYRN())
+ return true, nil
+ } else {
+ if principal.GetHTTPHeaderName() != "Athenz-Principal-Auth" {
+ return false, fmt.Errorf("Authorizer using" + principal.GetHTTPHeaderName() + " not supported")
+ }
+ zmsClient := NewClient(auth.url, nil)
+ zmsClient.AddCredentials(principal.GetHTTPHeaderName(), principal.GetCredentials())
+ check, err := zmsClient.GetAccess(ActionName(action), YRN(resource), "", "")
+ if err != nil {
+ return false, err
+ }
+ log.Printf("[Authorize %s on %s for %s: %v]\n", action, resource, principal.GetYRN(), check.Granted)
+ if check.Granted {
+ return true, nil
+ }
+ return false, nil
+ }
+}
diff --git a/clients/go/zms/client.go b/clients/go/zms/client.go
new file mode 100644
index 00000000000..5b7c211eab0
--- /dev/null
+++ b/clients/go/zms/client.go
@@ -0,0 +1,2377 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zms
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ rdl "github.com/ardielle/ardielle-go/rdl"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var _ = json.Marshal
+var _ = fmt.Printf
+var _ = rdl.BaseTypeAny
+var _ = ioutil.NopCloser
+
+type ZMSClient struct {
+ URL string
+ Transport http.RoundTripper
+ CredsHeader *string
+ CredsToken *string
+ Timeout time.Duration
+}
+
+// NewClient creates and returns a new HTTP client object for the ZMS service
+func NewClient(url string, transport http.RoundTripper) ZMSClient {
+ return ZMSClient{url, transport, nil, nil, 0}
+}
+
+// AddCredentials adds the credentials to the client for subsequent requests.
+func (client *ZMSClient) AddCredentials(header string, token string) {
+ client.CredsHeader = &header
+ client.CredsToken = &token
+}
+
+func (client ZMSClient) getClient() *http.Client {
+ var c *http.Client
+ if client.Transport != nil {
+ c = &http.Client{Transport: client.Transport}
+ } else {
+ c = &http.Client{}
+ }
+ if client.Timeout > 0 {
+ c.Timeout = client.Timeout
+ }
+ return c
+}
+
+func (client ZMSClient) addAuthHeader(req *http.Request) {
+ if client.CredsHeader != nil && client.CredsToken != nil {
+ if strings.HasPrefix(*client.CredsHeader, "Cookie.") {
+ req.Header.Add("Cookie", (*client.CredsHeader)[7:]+"="+*client.CredsToken)
+ } else {
+ req.Header.Add(*client.CredsHeader, *client.CredsToken)
+ }
+ }
+}
+
+func (client ZMSClient) httpGet(url string, headers map[string]string) (*http.Response, error) {
+ hclient := client.getClient()
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZMSClient) httpDelete(url string, headers map[string]string) (*http.Response, error) {
+ hclient := client.getClient()
+ req, err := http.NewRequest("DELETE", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZMSClient) httpPut(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("PUT", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZMSClient) httpPost(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("POST", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZMSClient) httpPatch(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("PATCH", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZMSClient) httpOptions(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ var contentReader io.Reader = nil
+ if body != nil {
+ contentReader = bytes.NewReader(body)
+ }
+ hclient := client.getClient()
+ req, err := http.NewRequest("OPTIONS", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ if contentReader != nil {
+ req.Header.Add("Content-type", "application/json")
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func encodeStringParam(name string, val string, def string) string {
+ if val == def {
+ return ""
+ }
+ return "&" + name + "=" + url.QueryEscape(val)
+}
+func encodeBoolParam(name string, b bool, def bool) string {
+ if b == def {
+ return ""
+ }
+ return fmt.Sprintf("&%s=%v", name, b)
+}
+func encodeInt8Param(name string, i int8, def int8) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt16Param(name string, i int16, def int16) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt32Param(name string, i int32, def int32) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt64Param(name string, i int64, def int64) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatInt(i, 10)
+}
+func encodeFloat32Param(name string, i float32, def float32) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatFloat(float64(i), 'g', -1, 32)
+}
+func encodeFloat64Param(name string, i float64, def float64) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatFloat(i, 'g', -1, 64)
+}
+func encodeOptionalEnumParam(name string, e interface{}) string {
+ if e == nil {
+ return "\"\""
+ }
+ return fmt.Sprintf("&%s=%v", name, e)
+}
+func encodeOptionalBoolParam(name string, b *bool) string {
+ if b == nil {
+ return ""
+ }
+ return fmt.Sprintf("&%s=%v", name, *b)
+}
+func encodeOptionalInt32Param(name string, i *int32) string {
+ if i == nil {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(*i))
+}
+func encodeOptionalInt64Param(name string, i *int64) string {
+ if i == nil {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(*i))
+}
+func encodeParams(objs ...string) string {
+ s := strings.Join(objs, "")
+ if s == "" {
+ return s
+ }
+ return "?" + s[1:]
+}
+
+func (client ZMSClient) GetDomain(domain DomainName) (*Domain, error) {
+ var data *Domain
+ url := client.URL + "/domain/" + fmt.Sprint(domain)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetDomainList(limit *int32, skip string, prefix string, depth *int32, account string, productId *int32, roleMember ResourceName, roleName ResourceName, modifiedSince string) (*DomainList, error) {
+ var data *DomainList
+ headers := map[string]string{
+ "If-Modified-Since": modifiedSince,
+ }
+ url := client.URL + "/domain" + encodeParams(encodeOptionalInt32Param("limit", limit), encodeStringParam("skip", string(skip), ""), encodeStringParam("prefix", string(prefix), ""), encodeOptionalInt32Param("depth", depth), encodeStringParam("account", string(account), ""), encodeOptionalInt32Param("ypmid", productId), encodeStringParam("member", string(roleMember), ""), encodeStringParam("role", string(roleName), ""))
+ resp, err := client.httpGet(url, headers)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PostTopLevelDomain(auditRef string, detail *TopLevelDomain) (*Domain, error) {
+ var data *Domain
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain"
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PostSubDomain(parent DomainName, auditRef string, detail *SubDomain) (*Domain, error) {
+ var data *Domain
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/subdomain/" + fmt.Sprint(parent)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PostUserDomain(name SimpleName, auditRef string, detail *UserDomain) (*Domain, error) {
+ var data *Domain
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/userdomain/" + fmt.Sprint(name)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteTopLevelDomain(name DomainName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(name)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeleteSubDomain(parent DomainName, name DomainName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/subdomain/" + fmt.Sprint(parent) + "/" + fmt.Sprint(name)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeleteUserDomain(name SimpleName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/userdomain/" + fmt.Sprint(name)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutDomainMeta(name DomainName, auditRef string, detail *DomainMeta) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(name) + "/meta"
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutDomainTemplate(name DomainName, auditRef string, template *DomainTemplate) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(name) + "/template"
+ contentBytes, err := json.Marshal(template)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetDomainTemplateList(name DomainName) (*DomainTemplateList, error) {
+ var data *DomainTemplateList
+ url := client.URL + "/domain/" + fmt.Sprint(name) + "/template"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteDomainTemplate(name DomainName, template SimpleName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(name) + "/template/" + fmt.Sprint(template)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetDomainDataCheck(domainName DomainName) (*DomainDataCheck, error) {
+ var data *DomainDataCheck
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/check"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutEntity(domainName DomainName, entityName EntityName, auditRef string, entity *Entity) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/entity/" + fmt.Sprint(entityName)
+ contentBytes, err := json.Marshal(entity)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetEntity(domainName DomainName, entityName EntityName) (*Entity, error) {
+ var data *Entity
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/entity/" + fmt.Sprint(entityName)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteEntity(domainName DomainName, entityName EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/entity/" + fmt.Sprint(entityName)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetEntityList(domainName DomainName) (*EntityList, error) {
+ var data *EntityList
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/entity"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetRoleList(domainName DomainName, limit *int32, skip string) (*RoleList, error) {
+ var data *RoleList
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role" + encodeParams(encodeOptionalInt32Param("limit", limit), encodeStringParam("skip", string(skip), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetRoles(domainName DomainName, members *bool) (*Roles, error) {
+ var data *Roles
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/roles" + encodeParams(encodeOptionalBoolParam("members", members))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetRole(domainName DomainName, roleName EntityName, auditLog *bool, expand *bool) (*Role, error) {
+ var data *Role
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName) + encodeParams(encodeOptionalBoolParam("auditLog", auditLog), encodeOptionalBoolParam("expand", expand))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutRole(domainName DomainName, roleName EntityName, auditRef string, role *Role) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName)
+ contentBytes, err := json.Marshal(role)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeleteRole(domainName DomainName, roleName EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetMembership(domainName DomainName, roleName EntityName, memberName ResourceName) (*Membership, error) {
+ var data *Membership
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName) + "/member/" + fmt.Sprint(memberName)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutMembership(domainName DomainName, roleName EntityName, memberName ResourceName, auditRef string, membership *Membership) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName) + "/member/" + fmt.Sprint(memberName)
+ contentBytes, err := json.Marshal(membership)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeleteMembership(domainName DomainName, roleName EntityName, memberName ResourceName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName) + "/member/" + fmt.Sprint(memberName)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutDefaultAdmins(domainName DomainName, auditRef string, defaultAdmins *DefaultAdmins) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/admins"
+ contentBytes, err := json.Marshal(defaultAdmins)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetPolicyList(domainName DomainName, limit *int32, skip string) (*PolicyList, error) {
+ var data *PolicyList
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy" + encodeParams(encodeOptionalInt32Param("limit", limit), encodeStringParam("skip", string(skip), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetPolicies(domainName DomainName, assertions *bool) (*Policies, error) {
+ var data *Policies
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policies" + encodeParams(encodeOptionalBoolParam("assertions", assertions))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetPolicy(domainName DomainName, policyName EntityName) (*Policy, error) {
+ var data *Policy
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutPolicy(domainName DomainName, policyName EntityName, auditRef string, policy *Policy) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName)
+ contentBytes, err := json.Marshal(policy)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeletePolicy(domainName DomainName, policyName EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetAssertion(domainName DomainName, policyName EntityName, assertionId int64) (*Assertion, error) {
+ var data *Assertion
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName) + "/assertion/" + fmt.Sprint(assertionId)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutAssertion(domainName DomainName, policyName EntityName, auditRef string, assertion *Assertion) (*Assertion, error) {
+ var data *Assertion
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName) + "/assertion"
+ contentBytes, err := json.Marshal(assertion)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200, 201:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteAssertion(domainName DomainName, policyName EntityName, assertionId int64, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/policy/" + fmt.Sprint(policyName) + "/assertion/" + fmt.Sprint(assertionId)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutServiceIdentity(domain DomainName, service SimpleName, auditRef string, detail *ServiceIdentity) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetServiceIdentity(domain DomainName, service SimpleName) (*ServiceIdentity, error) {
+ var data *ServiceIdentity
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteServiceIdentity(domain DomainName, service SimpleName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetServiceIdentities(domainName DomainName, publickeys *bool, hosts *bool) (*ServiceIdentities, error) {
+ var data *ServiceIdentities
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/services" + encodeParams(encodeOptionalBoolParam("publickeys", publickeys), encodeOptionalBoolParam("hosts", hosts))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetServiceIdentityList(domainName DomainName, limit *int32, skip string) (*ServiceIdentityList, error) {
+ var data *ServiceIdentityList
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service" + encodeParams(encodeOptionalInt32Param("limit", limit), encodeStringParam("skip", string(skip), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetPublicKeyEntry(domain DomainName, service SimpleName, id string) (*PublicKeyEntry, error) {
+ var data *PublicKeyEntry
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/publickey/" + id
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) PutPublicKeyEntry(domain DomainName, service SimpleName, id string, auditRef string, publicKeyEntry *PublicKeyEntry) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/publickey/" + id
+ contentBytes, err := json.Marshal(publicKeyEntry)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeletePublicKeyEntry(domain DomainName, service SimpleName, id string, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/publickey/" + id
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutTenancy(domain DomainName, service ServiceName, auditRef string, detail *Tenancy) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/tenancy/" + fmt.Sprint(service)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetTenancy(domain DomainName, service ServiceName) (*Tenancy, error) {
+ var data *Tenancy
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/tenancy/" + fmt.Sprint(service)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteTenancy(domain DomainName, service ServiceName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/tenancy/" + fmt.Sprint(service)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutTenancyResourceGroup(domain DomainName, service ServiceName, resourceGroup EntityName, auditRef string, detail *TenancyResourceGroup) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/tenancy/" + fmt.Sprint(service) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) DeleteTenancyResourceGroup(domain DomainName, service ServiceName, resourceGroup EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/tenancy/" + fmt.Sprint(service) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutTenantRoles(domain DomainName, service SimpleName, tenantDomain DomainName, auditRef string, detail *TenantRoles) (*TenantRoles, error) {
+ var data *TenantRoles
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200, 201:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetTenantRoles(domain DomainName, service SimpleName, tenantDomain DomainName) (*TenantRoles, error) {
+ var data *TenantRoles
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteTenantRoles(domain DomainName, service SimpleName, tenantDomain DomainName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutTenantResourceGroupRoles(domain DomainName, service SimpleName, tenantDomain DomainName, resourceGroup EntityName, auditRef string, detail *TenantResourceGroupRoles) (*TenantResourceGroupRoles, error) {
+ var data *TenantResourceGroupRoles
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200, 201:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetTenantResourceGroupRoles(domain DomainName, service SimpleName, tenantDomain DomainName, resourceGroup EntityName) (*TenantResourceGroupRoles, error) {
+ var data *TenantResourceGroupRoles
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteTenantResourceGroupRoles(domain DomainName, service SimpleName, tenantDomain DomainName, resourceGroup EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domain) + "/service/" + fmt.Sprint(service) + "/tenant/" + fmt.Sprint(tenantDomain) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) PutProviderResourceGroupRoles(tenantDomain DomainName, provDomain DomainName, provService SimpleName, resourceGroup EntityName, auditRef string, detail *ProviderResourceGroupRoles) (*ProviderResourceGroupRoles, error) {
+ var data *ProviderResourceGroupRoles
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(tenantDomain) + "/provDomain/" + fmt.Sprint(provDomain) + "/provService/" + fmt.Sprint(provService) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ contentBytes, err := json.Marshal(detail)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPut(url, headers, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200, 201:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetProviderResourceGroupRoles(tenantDomain DomainName, provDomain DomainName, provService SimpleName, resourceGroup EntityName) (*ProviderResourceGroupRoles, error) {
+ var data *ProviderResourceGroupRoles
+ url := client.URL + "/domain/" + fmt.Sprint(tenantDomain) + "/provDomain/" + fmt.Sprint(provDomain) + "/provService/" + fmt.Sprint(provService) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) DeleteProviderResourceGroupRoles(tenantDomain DomainName, provDomain DomainName, provService SimpleName, resourceGroup EntityName, auditRef string) error {
+ headers := map[string]string{
+ "Y-Audit-Ref": auditRef,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(tenantDomain) + "/provDomain/" + fmt.Sprint(provDomain) + "/provService/" + fmt.Sprint(provService) + "/resourceGroup/" + fmt.Sprint(resourceGroup)
+ resp, err := client.httpDelete(url, headers)
+ if err != nil {
+ return err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return err
+ }
+ switch resp.StatusCode {
+ case 204:
+ return nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return errobj
+ }
+}
+
+func (client ZMSClient) GetAccess(action ActionName, resource YRN, domain DomainName, checkPrincipal EntityName) (*Access, error) {
+ var data *Access
+ url := client.URL + "/access/" + fmt.Sprint(action) + "/" + fmt.Sprint(resource) + encodeParams(encodeStringParam("domain", string(domain), ""), encodeStringParam("principal", string(checkPrincipal), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetAccessExt(action ActionName, resource string, domain DomainName, checkPrincipal EntityName) (*Access, error) {
+ var data *Access
+ url := client.URL + "/access/" + fmt.Sprint(action) + encodeParams(encodeStringParam("resource", string(resource), ""), encodeStringParam("domain", string(domain), ""), encodeStringParam("principal", string(checkPrincipal), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetResourceAccessList(principal EntityName, action ActionName) (*ResourceAccessList, error) {
+ var data *ResourceAccessList
+ url := client.URL + "/resource" + encodeParams(encodeStringParam("principal", string(principal), ""), encodeStringParam("action", string(action), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetSignedDomains(domain DomainName, metaOnly string, matchingTag string) (*SignedDomains, string, error) {
+ var data *SignedDomains
+ headers := map[string]string{
+ "If-None-Match": matchingTag,
+ }
+ url := client.URL + "/sys/modified_domains" + encodeParams(encodeStringParam("domain", string(domain), ""), encodeStringParam("metaonly", string(metaOnly), ""))
+ resp, err := client.httpGet(url, headers)
+ if err != nil {
+ return nil, "", err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return nil, "", err
+ }
+ switch resp.StatusCode {
+ case 200, 304:
+ if 304 != resp.StatusCode {
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return nil, "", err
+ }
+ }
+ tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
+ return data, tag, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return nil, "", errobj
+ }
+}
+
+func (client ZMSClient) GetUserToken(userName SimpleName, serviceNames string) (*UserToken, error) {
+ var data *UserToken
+ url := client.URL + "/user/" + fmt.Sprint(userName) + "/token" + encodeParams(encodeStringParam("services", string(serviceNames), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) OptionsUserToken(userName SimpleName, serviceNames string) (*UserToken, error) {
+ var data *UserToken
+ url := client.URL + "/user/" + fmt.Sprint(userName) + "/token" + encodeParams(encodeStringParam("services", string(serviceNames), ""))
+ resp, err := client.httpOptions(url, nil, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetServicePrincipal() (*ServicePrincipal, error) {
+ var data *ServicePrincipal
+ url := client.URL + "/principal"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetServerTemplateList() (*ServerTemplateList, error) {
+ var data *ServerTemplateList
+ url := client.URL + "/template"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return data, errobj
+ }
+}
+
+func (client ZMSClient) GetTemplate(template SimpleName) (*Template, error) {
+ var data *Template
+ url := client.URL + "/template/" + fmt.Sprint(template)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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/zms/model.go b/clients/go/zms/model.go
new file mode 100644
index 00000000000..d6c96612a8b
--- /dev/null
+++ b/clients/go/zms/model.go
@@ -0,0 +1,3827 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zms
+
+import (
+ "encoding/json"
+ "fmt"
+ rdl "github.com/ardielle/ardielle-go/rdl"
+)
+
+var _ = rdl.Version
+var _ = json.Marshal
+var _ = fmt.Printf
+
+//
+// SimpleName - Copyright 2016 Yahoo Inc. Licensed under the terms of the
+// Apache version 2.0 license. See LICENSE file for terms. Common name types
+// used by several API definitions A simple identifier, an element of compound
+// name.
+//
+type SimpleName string
+
+//
+// CompoundName - A compound name. Most names in this API are compound names.
+//
+type CompoundName string
+
+//
+// DomainName - A domain name is the general qualifier prefix, as its
+// uniqueness is managed.
+//
+type DomainName string
+
+//
+// EntityName - An entity name is a short form of a resource name, including
+// only the domain and entity.
+//
+type EntityName string
+
+//
+// ServiceName - A service name will generally be a unique subdomain.
+//
+type ServiceName string
+
+//
+// LocationName - A location name is not yet defined, but will be a dotted name
+// like everything else.
+//
+type LocationName string
+
+//
+// ActionName - An action (operation) name.
+//
+type ActionName string
+
+//
+// ResourceName - A shorthand for a YRN with no service or location. The 'tail'
+// of a YRN, just the domain:entity. Note that the EntityName part is optional,
+// that is, a domain name followed by a colon is valid resource name.
+//
+type ResourceName string
+
+//
+// YRN - A full Yahoo Resource name (YRN).
+//
+type YRN string
+
+//
+// YBase64 - The Y-specific URL-safe Base64 variant.
+//
+type YBase64 string
+
+//
+// YEncoded - YEncoded includes ybase64 chars, as well as = and %. This can
+// represent a user cookie and URL-encoded values.
+//
+type YEncoded string
+
+//
+// AuthorityName - Used as the prefix in a signed assertion. This uniquely
+// identifies a signing authority. i.e. "user"
+//
+type AuthorityName string
+
+//
+// SignedToken - A signed assertion if identity. i.e. the user cookie value.
+// This token will only make sense to the authority that generated it, so it is
+// beneficial to have something in the value that is cheaply recognized to
+// quickly reject if it belongs to another authority. In addition to the
+// YEncoded set our token includes ; to separate components and , to separate
+// roles and : for IPv6 addresses
+//
+type SignedToken string
+
+//
+// Domain - A domain is an independent partition of users, roles, and
+// resources. Its name represents the definition of a namespace; the only way a
+// new namespace can be created, from the top, is by creating Domains.
+// Administration of a domain is governed by the parent domain (using
+// reverse-DNS namespaces). The top level domains are governed by the special
+// "sys.auth" domain.
+//
+type Domain struct {
+
+ //
+ // the common name to be referred to, the symbolic id. It is immutable
+ //
+ Name DomainName `json:"name"`
+
+ //
+ // the last modification timestamp of any object or attribute in this domain
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // unique identifier of the domain. generated on create, never reused
+ //
+ Id *rdl.UUID `json:"id,omitempty" rdl:"optional"`
+
+ //
+ // description of the domain
+ //
+ Description string `json:"description,omitempty" rdl:"optional"`
+
+ //
+ // a reference to an Organization
+ //
+ Org ResourceName `json:"org,omitempty" rdl:"optional"`
+
+ //
+ // Future use only, currently not used
+ //
+ Enabled *bool `json:"enabled,omitempty" rdl:"optional"`
+
+ //
+ // Flag indicates whether or not domain modifications should be logged for
+ // SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for
+ // any API defining it.
+ //
+ AuditEnabled *bool `json:"auditEnabled,omitempty" rdl:"optional"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+}
+
+//
+// NewDomain - creates an initialized Domain instance, returns a pointer to it
+//
+func NewDomain(init ...*Domain) *Domain {
+ var o *Domain
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Domain)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Domain) Init() *Domain {
+ if pTypeDef.Enabled == nil {
+ d := true
+ pTypeDef.Enabled = &d
+ }
+ if pTypeDef.AuditEnabled == nil {
+ d := false
+ pTypeDef.AuditEnabled = &d
+ }
+ return pTypeDef
+}
+
+type rawDomain Domain
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Domain
+//
+func (pTypeDef *Domain) UnmarshalJSON(b []byte) error {
+ var r rawDomain
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Domain(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Domain) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Domain.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Domain.name does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// RoleList - The representation for an enumeration of roles in the namespace,
+// with pagination.
+//
+type RoleList struct {
+
+ //
+ // list of role names
+ //
+ Names []EntityName `json:"names"`
+
+ //
+ // if the response is a paginated list, this attribute specifies the value to
+ // be used in the next role list request as the value for the skip query
+ // parameter.
+ //
+ Next string `json:"next,omitempty" rdl:"optional"`
+}
+
+//
+// NewRoleList - creates an initialized RoleList instance, returns a pointer to it
+//
+func NewRoleList(init ...*RoleList) *RoleList {
+ var o *RoleList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(RoleList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *RoleList) Init() *RoleList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawRoleList RoleList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a RoleList
+//
+func (pTypeDef *RoleList) UnmarshalJSON(b []byte) error {
+ var r rawRoleList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := RoleList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *RoleList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("RoleList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// RoleAuditLog - An audit log entry for role membership change.
+//
+type RoleAuditLog struct {
+
+ //
+ // name of the role member
+ //
+ Member ResourceName `json:"member"`
+
+ //
+ // name of the principal executing the change
+ //
+ Admin ResourceName `json:"admin"`
+
+ //
+ // timestamp of the entry
+ //
+ Created rdl.Timestamp `json:"created"`
+
+ //
+ // log action - either add or delete
+ //
+ Action string `json:"action"`
+
+ //
+ // audit reference string for the change as supplied by admin
+ //
+ AuditRef string `json:"auditRef,omitempty" rdl:"optional"`
+}
+
+//
+// NewRoleAuditLog - creates an initialized RoleAuditLog instance, returns a pointer to it
+//
+func NewRoleAuditLog(init ...*RoleAuditLog) *RoleAuditLog {
+ var o *RoleAuditLog
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(RoleAuditLog)
+ }
+ return o
+}
+
+type rawRoleAuditLog RoleAuditLog
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a RoleAuditLog
+//
+func (pTypeDef *RoleAuditLog) UnmarshalJSON(b []byte) error {
+ var r rawRoleAuditLog
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := RoleAuditLog(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *RoleAuditLog) Validate() error {
+ if pTypeDef.Member == "" {
+ return fmt.Errorf("RoleAuditLog.member is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ResourceName", pTypeDef.Member)
+ if !val.Valid {
+ return fmt.Errorf("RoleAuditLog.member does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Admin == "" {
+ return fmt.Errorf("RoleAuditLog.admin is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ResourceName", pTypeDef.Admin)
+ if !val.Valid {
+ return fmt.Errorf("RoleAuditLog.admin does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Created.IsZero() {
+ return fmt.Errorf("RoleAuditLog: Missing required field: created")
+ }
+ if pTypeDef.Action == "" {
+ return fmt.Errorf("RoleAuditLog.action is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Action)
+ if !val.Valid {
+ return fmt.Errorf("RoleAuditLog.action does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Role - The representation for a Role with set of members.
+//
+type Role struct {
+
+ //
+ // name of the role
+ //
+ Name ResourceName `json:"name"`
+
+ //
+ // last modification timestamp of the role
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // an explicit list of members. Might be empty or null, if trust is set
+ //
+ Members []ResourceName `json:"members,omitempty" rdl:"optional"`
+
+ //
+ // a trusted domain to delegate membership decisions to
+ //
+ Trust DomainName `json:"trust,omitempty" rdl:"optional"`
+
+ //
+ // an audit log for role membership changes
+ //
+ AuditLog []*RoleAuditLog `json:"auditLog,omitempty" rdl:"optional"`
+}
+
+//
+// NewRole - creates an initialized Role instance, returns a pointer to it
+//
+func NewRole(init ...*Role) *Role {
+ var o *Role
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Role)
+ }
+ return o
+}
+
+type rawRole Role
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Role
+//
+func (pTypeDef *Role) UnmarshalJSON(b []byte) error {
+ var r rawRole
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Role(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Role) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Role.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ResourceName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Role.name does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Roles - The representation for a list of roles with full details
+//
+type Roles struct {
+
+ //
+ // list of role objects
+ //
+ List []*Role `json:"list"`
+}
+
+//
+// NewRoles - creates an initialized Roles instance, returns a pointer to it
+//
+func NewRoles(init ...*Roles) *Roles {
+ var o *Roles
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Roles)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Roles) Init() *Roles {
+ if pTypeDef.List == nil {
+ pTypeDef.List = make([]*Role, 0)
+ }
+ return pTypeDef
+}
+
+type rawRoles Roles
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Roles
+//
+func (pTypeDef *Roles) UnmarshalJSON(b []byte) error {
+ var r rawRoles
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Roles(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Roles) Validate() error {
+ if pTypeDef.List == nil {
+ return fmt.Errorf("Roles: Missing required field: list")
+ }
+ return nil
+}
+
+//
+// Membership - The representation for a role membership.
+//
+type Membership struct {
+
+ //
+ // name of the member
+ //
+ MemberName ResourceName `json:"memberName"`
+
+ //
+ // flag to indicate whether or the user is a member or not
+ //
+ IsMember *bool `json:"isMember,omitempty" rdl:"optional"`
+
+ //
+ // name of the role
+ //
+ RoleName ResourceName `json:"roleName,omitempty" rdl:"optional"`
+}
+
+//
+// NewMembership - creates an initialized Membership instance, returns a pointer to it
+//
+func NewMembership(init ...*Membership) *Membership {
+ var o *Membership
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Membership)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Membership) Init() *Membership {
+ if pTypeDef.IsMember == nil {
+ d := true
+ pTypeDef.IsMember = &d
+ }
+ return pTypeDef
+}
+
+type rawMembership Membership
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Membership
+//
+func (pTypeDef *Membership) UnmarshalJSON(b []byte) error {
+ var r rawMembership
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Membership(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Membership) Validate() error {
+ if pTypeDef.MemberName == "" {
+ return fmt.Errorf("Membership.memberName is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ResourceName", pTypeDef.MemberName)
+ if !val.Valid {
+ return fmt.Errorf("Membership.memberName does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// DefaultAdmins - The list of domain administrators.
+//
+type DefaultAdmins struct {
+
+ //
+ // list of domain administrators
+ //
+ Admins []ResourceName `json:"admins"`
+}
+
+//
+// NewDefaultAdmins - creates an initialized DefaultAdmins instance, returns a pointer to it
+//
+func NewDefaultAdmins(init ...*DefaultAdmins) *DefaultAdmins {
+ var o *DefaultAdmins
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DefaultAdmins)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DefaultAdmins) Init() *DefaultAdmins {
+ if pTypeDef.Admins == nil {
+ pTypeDef.Admins = make([]ResourceName, 0)
+ }
+ return pTypeDef
+}
+
+type rawDefaultAdmins DefaultAdmins
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DefaultAdmins
+//
+func (pTypeDef *DefaultAdmins) UnmarshalJSON(b []byte) error {
+ var r rawDefaultAdmins
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DefaultAdmins(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DefaultAdmins) Validate() error {
+ if pTypeDef.Admins == nil {
+ return fmt.Errorf("DefaultAdmins: Missing required field: admins")
+ }
+ return nil
+}
+
+//
+// AssertionEffect - Every assertion can have the effect of ALLOW or DENY.
+//
+type AssertionEffect int
+
+//
+// AssertionEffect constants
+//
+const (
+ _ AssertionEffect = iota
+ ALLOW
+ DENY
+)
+
+var namesAssertionEffect = []string{
+ ALLOW: "ALLOW",
+ DENY: "DENY",
+}
+
+//
+// NewAssertionEffect - return a string representation of the enum
+//
+func NewAssertionEffect(init ...interface{}) AssertionEffect {
+ if len(init) == 1 {
+ switch v := init[0].(type) {
+ case AssertionEffect:
+ return v
+ case int:
+ return AssertionEffect(v)
+ case int32:
+ return AssertionEffect(v)
+ case string:
+ for i, s := range namesAssertionEffect {
+ if s == v {
+ return AssertionEffect(i)
+ }
+ }
+ default:
+ panic("Bad init value for AssertionEffect enum")
+ }
+ }
+ return AssertionEffect(0) //default to the first enum value
+}
+
+//
+// String - return a string representation of the enum
+//
+func (e AssertionEffect) String() string {
+ return namesAssertionEffect[e]
+}
+
+//
+// SymbolSet - return an array of all valid string representations (symbols) of the enum
+//
+func (e AssertionEffect) SymbolSet() []string {
+ return namesAssertionEffect
+}
+
+//
+// MarshalJSON is defined for proper JSON encoding of a AssertionEffect
+//
+func (e AssertionEffect) MarshalJSON() ([]byte, error) {
+ return json.Marshal(e.String())
+}
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a AssertionEffect
+//
+func (e *AssertionEffect) UnmarshalJSON(b []byte) error {
+ var j string
+ err := json.Unmarshal(b, &j)
+ if err == nil {
+ s := string(j)
+ for v, s2 := range namesAssertionEffect {
+ if s == s2 {
+ *e = AssertionEffect(v)
+ return nil
+ }
+ }
+ err = fmt.Errorf("Bad enum symbol for type AssertionEffect: %s", s)
+ }
+ return err
+}
+
+//
+// Assertion - A representation for the encapsulation of an action to be
+// performed on a resource by a principal.
+//
+type Assertion struct {
+
+ //
+ // the subject of the assertion - a role
+ //
+ Role string `json:"role"`
+
+ //
+ // the object of the assertion. Must be in the local namespace. Can contain
+ // wildcards
+ //
+ Resource string `json:"resource"`
+
+ //
+ // the predicate of the assertion. Can contain wildcards
+ //
+ Action string `json:"action"`
+
+ //
+ // the effect of the assertion in the policy language
+ //
+ Effect *AssertionEffect `json:"effect,omitempty" rdl:"optional"`
+
+ //
+ // assertion id - auto generated by server. Not required during put
+ // operations.
+ //
+ Id *int64 `json:"id,omitempty" rdl:"optional"`
+}
+
+//
+// NewAssertion - creates an initialized Assertion instance, returns a pointer to it
+//
+func NewAssertion(init ...*Assertion) *Assertion {
+ var o *Assertion
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Assertion)
+ }
+ return o
+}
+
+type rawAssertion Assertion
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Assertion
+//
+func (pTypeDef *Assertion) UnmarshalJSON(b []byte) error {
+ var r rawAssertion
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Assertion(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Assertion) Validate() error {
+ if pTypeDef.Role == "" {
+ return fmt.Errorf("Assertion.role is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Role)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.role does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Resource == "" {
+ return fmt.Errorf("Assertion.resource is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Resource)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.resource does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Action == "" {
+ return fmt.Errorf("Assertion.action is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Action)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.action does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Policy - The representation for a Policy with set of assertions.
+//
+type Policy struct {
+
+ //
+ // name of the policy
+ //
+ Name ResourceName `json:"name"`
+
+ //
+ // last modification timestamp of this policy
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // list of defined assertions for this policy
+ //
+ Assertions []*Assertion `json:"assertions"`
+}
+
+//
+// NewPolicy - creates an initialized Policy instance, returns a pointer to it
+//
+func NewPolicy(init ...*Policy) *Policy {
+ var o *Policy
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Policy)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Policy) Init() *Policy {
+ if pTypeDef.Assertions == nil {
+ pTypeDef.Assertions = make([]*Assertion, 0)
+ }
+ return pTypeDef
+}
+
+type rawPolicy Policy
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Policy
+//
+func (pTypeDef *Policy) UnmarshalJSON(b []byte) error {
+ var r rawPolicy
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Policy(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Policy) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Policy.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ResourceName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Policy.name does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Assertions == nil {
+ return fmt.Errorf("Policy: Missing required field: assertions")
+ }
+ return nil
+}
+
+//
+// Policies - The representation of list of policy objects
+//
+type Policies struct {
+
+ //
+ // list of policy objects
+ //
+ List []*Policy `json:"list"`
+}
+
+//
+// NewPolicies - creates an initialized Policies instance, returns a pointer to it
+//
+func NewPolicies(init ...*Policies) *Policies {
+ var o *Policies
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Policies)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Policies) Init() *Policies {
+ if pTypeDef.List == nil {
+ pTypeDef.List = make([]*Policy, 0)
+ }
+ return pTypeDef
+}
+
+type rawPolicies Policies
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Policies
+//
+func (pTypeDef *Policies) UnmarshalJSON(b []byte) error {
+ var r rawPolicies
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Policies(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Policies) Validate() error {
+ if pTypeDef.List == nil {
+ return fmt.Errorf("Policies: Missing required field: list")
+ }
+ return nil
+}
+
+//
+// Template - Solution Template object defined on the server
+//
+type Template struct {
+
+ //
+ // list of roles in the template
+ //
+ Roles []*Role `json:"roles"`
+
+ //
+ // list of policies defined in this template
+ //
+ Policies []*Policy `json:"policies"`
+}
+
+//
+// NewTemplate - creates an initialized Template instance, returns a pointer to it
+//
+func NewTemplate(init ...*Template) *Template {
+ var o *Template
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Template)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Template) Init() *Template {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]*Role, 0)
+ }
+ if pTypeDef.Policies == nil {
+ pTypeDef.Policies = make([]*Policy, 0)
+ }
+ return pTypeDef
+}
+
+type rawTemplate Template
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Template
+//
+func (pTypeDef *Template) UnmarshalJSON(b []byte) error {
+ var r rawTemplate
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Template(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Template) Validate() error {
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("Template: Missing required field: roles")
+ }
+ if pTypeDef.Policies == nil {
+ return fmt.Errorf("Template: Missing required field: policies")
+ }
+ return nil
+}
+
+//
+// TemplateList - List of template names that is the base struct for server and
+// domain templates
+//
+type TemplateList struct {
+
+ //
+ // list of template names
+ //
+ TemplateNames []SimpleName `json:"templateNames"`
+}
+
+//
+// NewTemplateList - creates an initialized TemplateList instance, returns a pointer to it
+//
+func NewTemplateList(init ...*TemplateList) *TemplateList {
+ var o *TemplateList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TemplateList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *TemplateList) Init() *TemplateList {
+ if pTypeDef.TemplateNames == nil {
+ pTypeDef.TemplateNames = make([]SimpleName, 0)
+ }
+ return pTypeDef
+}
+
+type rawTemplateList TemplateList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TemplateList
+//
+func (pTypeDef *TemplateList) UnmarshalJSON(b []byte) error {
+ var r rawTemplateList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TemplateList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TemplateList) Validate() error {
+ if pTypeDef.TemplateNames == nil {
+ return fmt.Errorf("TemplateList: Missing required field: templateNames")
+ }
+ return nil
+}
+
+//
+// DomainTemplate - solution template(s) to be applied to a domain
+//
+type DomainTemplate struct {
+
+ //
+ // list of template names
+ //
+ TemplateNames []SimpleName `json:"templateNames"`
+}
+
+//
+// NewDomainTemplate - creates an initialized DomainTemplate instance, returns a pointer to it
+//
+func NewDomainTemplate(init ...*DomainTemplate) *DomainTemplate {
+ var o *DomainTemplate
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainTemplate)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainTemplate) Init() *DomainTemplate {
+ if pTypeDef.TemplateNames == nil {
+ pTypeDef.TemplateNames = make([]SimpleName, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainTemplate DomainTemplate
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainTemplate
+//
+func (pTypeDef *DomainTemplate) UnmarshalJSON(b []byte) error {
+ var r rawDomainTemplate
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainTemplate(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainTemplate) Validate() error {
+ if pTypeDef.TemplateNames == nil {
+ return fmt.Errorf("DomainTemplate: Missing required field: templateNames")
+ }
+ return nil
+}
+
+//
+// DomainTemplateList - List of solution templates to be applied to a domain
+//
+type DomainTemplateList struct {
+
+ //
+ // list of template names
+ //
+ TemplateNames []SimpleName `json:"templateNames"`
+}
+
+//
+// NewDomainTemplateList - creates an initialized DomainTemplateList instance, returns a pointer to it
+//
+func NewDomainTemplateList(init ...*DomainTemplateList) *DomainTemplateList {
+ var o *DomainTemplateList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainTemplateList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainTemplateList) Init() *DomainTemplateList {
+ if pTypeDef.TemplateNames == nil {
+ pTypeDef.TemplateNames = make([]SimpleName, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainTemplateList DomainTemplateList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainTemplateList
+//
+func (pTypeDef *DomainTemplateList) UnmarshalJSON(b []byte) error {
+ var r rawDomainTemplateList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainTemplateList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainTemplateList) Validate() error {
+ if pTypeDef.TemplateNames == nil {
+ return fmt.Errorf("DomainTemplateList: Missing required field: templateNames")
+ }
+ return nil
+}
+
+//
+// ServerTemplateList - List of solution templates available in the server
+//
+type ServerTemplateList struct {
+
+ //
+ // list of template names
+ //
+ TemplateNames []SimpleName `json:"templateNames"`
+}
+
+//
+// NewServerTemplateList - creates an initialized ServerTemplateList instance, returns a pointer to it
+//
+func NewServerTemplateList(init ...*ServerTemplateList) *ServerTemplateList {
+ var o *ServerTemplateList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServerTemplateList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ServerTemplateList) Init() *ServerTemplateList {
+ if pTypeDef.TemplateNames == nil {
+ pTypeDef.TemplateNames = make([]SimpleName, 0)
+ }
+ return pTypeDef
+}
+
+type rawServerTemplateList ServerTemplateList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServerTemplateList
+//
+func (pTypeDef *ServerTemplateList) UnmarshalJSON(b []byte) error {
+ var r rawServerTemplateList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServerTemplateList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServerTemplateList) Validate() error {
+ if pTypeDef.TemplateNames == nil {
+ return fmt.Errorf("ServerTemplateList: Missing required field: templateNames")
+ }
+ return nil
+}
+
+//
+// DomainList - A paginated list of domains.
+//
+type DomainList struct {
+
+ //
+ // list of domain names
+ //
+ Names []DomainName `json:"names"`
+
+ //
+ // if the response is a paginated list, this attribute specifies the value to
+ // be used in the next domain list request as the value for the skip query
+ // parameter.
+ //
+ Next string `json:"next,omitempty" rdl:"optional"`
+}
+
+//
+// NewDomainList - creates an initialized DomainList instance, returns a pointer to it
+//
+func NewDomainList(init ...*DomainList) *DomainList {
+ var o *DomainList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainList) Init() *DomainList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]DomainName, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainList DomainList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainList
+//
+func (pTypeDef *DomainList) UnmarshalJSON(b []byte) error {
+ var r rawDomainList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("DomainList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// DomainMeta - Set of metadata attributes that all domains may have and can be
+// changed.
+//
+type DomainMeta struct {
+
+ //
+ // a description of the domain
+ //
+ Description string `json:"description,omitempty" rdl:"optional"`
+
+ //
+ // a reference to an Organization. (i.e. org:media)
+ //
+ Org ResourceName `json:"org,omitempty" rdl:"optional"`
+
+ //
+ // Future use only, currently not used
+ //
+ Enabled *bool `json:"enabled,omitempty" rdl:"optional"`
+
+ //
+ // Flag indicates whether or not domain modifications should be logged for
+ // SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for
+ // any API defining it.
+ //
+ AuditEnabled *bool `json:"auditEnabled,omitempty" rdl:"optional"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+}
+
+//
+// NewDomainMeta - creates an initialized DomainMeta instance, returns a pointer to it
+//
+func NewDomainMeta(init ...*DomainMeta) *DomainMeta {
+ var o *DomainMeta
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainMeta)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainMeta) Init() *DomainMeta {
+ if pTypeDef.Enabled == nil {
+ d := true
+ pTypeDef.Enabled = &d
+ }
+ if pTypeDef.AuditEnabled == nil {
+ d := false
+ pTypeDef.AuditEnabled = &d
+ }
+ return pTypeDef
+}
+
+type rawDomainMeta DomainMeta
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainMeta
+//
+func (pTypeDef *DomainMeta) UnmarshalJSON(b []byte) error {
+ var r rawDomainMeta
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainMeta(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainMeta) Validate() error {
+ return nil
+}
+
+//
+// TopLevelDomain - Top Level Domain object. The required attributes include
+// the name of the domain and list of domain administrators.
+//
+type TopLevelDomain struct {
+
+ //
+ // a description of the domain
+ //
+ Description string `json:"description,omitempty" rdl:"optional"`
+
+ //
+ // a reference to an Organization. (i.e. org:media)
+ //
+ Org ResourceName `json:"org,omitempty" rdl:"optional"`
+
+ //
+ // Future use only, currently not used
+ //
+ Enabled *bool `json:"enabled,omitempty" rdl:"optional"`
+
+ //
+ // Flag indicates whether or not domain modifications should be logged for
+ // SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for
+ // any API defining it.
+ //
+ AuditEnabled *bool `json:"auditEnabled,omitempty" rdl:"optional"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+
+ //
+ // name of the domain
+ //
+ Name SimpleName `json:"name"`
+
+ //
+ // list of domain administrators
+ //
+ AdminUsers []ResourceName `json:"adminUsers"`
+
+ //
+ // list of solution template names
+ //
+ Templates *DomainTemplateList `json:"templates,omitempty" rdl:"optional"`
+}
+
+//
+// NewTopLevelDomain - creates an initialized TopLevelDomain instance, returns a pointer to it
+//
+func NewTopLevelDomain(init ...*TopLevelDomain) *TopLevelDomain {
+ var o *TopLevelDomain
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TopLevelDomain)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *TopLevelDomain) Init() *TopLevelDomain {
+ if pTypeDef.Enabled == nil {
+ d := true
+ pTypeDef.Enabled = &d
+ }
+ if pTypeDef.AuditEnabled == nil {
+ d := false
+ pTypeDef.AuditEnabled = &d
+ }
+ if pTypeDef.AdminUsers == nil {
+ pTypeDef.AdminUsers = make([]ResourceName, 0)
+ }
+ return pTypeDef
+}
+
+type rawTopLevelDomain TopLevelDomain
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TopLevelDomain
+//
+func (pTypeDef *TopLevelDomain) UnmarshalJSON(b []byte) error {
+ var r rawTopLevelDomain
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TopLevelDomain(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TopLevelDomain) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("TopLevelDomain.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("TopLevelDomain.name does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.AdminUsers == nil {
+ return fmt.Errorf("TopLevelDomain: Missing required field: adminUsers")
+ }
+ return nil
+}
+
+//
+// SubDomain - A Subdomain is a TopLevelDomain, except it has a parent.
+//
+type SubDomain struct {
+
+ //
+ // a description of the domain
+ //
+ Description string `json:"description,omitempty" rdl:"optional"`
+
+ //
+ // a reference to an Organization. (i.e. org:media)
+ //
+ Org ResourceName `json:"org,omitempty" rdl:"optional"`
+
+ //
+ // Future use only, currently not used
+ //
+ Enabled *bool `json:"enabled,omitempty" rdl:"optional"`
+
+ //
+ // Flag indicates whether or not domain modifications should be logged for
+ // SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for
+ // any API defining it.
+ //
+ AuditEnabled *bool `json:"auditEnabled,omitempty" rdl:"optional"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+
+ //
+ // name of the domain
+ //
+ Name SimpleName `json:"name"`
+
+ //
+ // list of domain administrators
+ //
+ AdminUsers []ResourceName `json:"adminUsers"`
+
+ //
+ // list of solution template names
+ //
+ Templates *DomainTemplateList `json:"templates,omitempty" rdl:"optional"`
+
+ //
+ // name of the parent domain
+ //
+ Parent DomainName `json:"parent"`
+}
+
+//
+// NewSubDomain - creates an initialized SubDomain instance, returns a pointer to it
+//
+func NewSubDomain(init ...*SubDomain) *SubDomain {
+ var o *SubDomain
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(SubDomain)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *SubDomain) Init() *SubDomain {
+ if pTypeDef.Enabled == nil {
+ d := true
+ pTypeDef.Enabled = &d
+ }
+ if pTypeDef.AuditEnabled == nil {
+ d := false
+ pTypeDef.AuditEnabled = &d
+ }
+ if pTypeDef.AdminUsers == nil {
+ pTypeDef.AdminUsers = make([]ResourceName, 0)
+ }
+ return pTypeDef
+}
+
+type rawSubDomain SubDomain
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a SubDomain
+//
+func (pTypeDef *SubDomain) UnmarshalJSON(b []byte) error {
+ var r rawSubDomain
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := SubDomain(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *SubDomain) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("SubDomain.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("SubDomain.name does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.AdminUsers == nil {
+ return fmt.Errorf("SubDomain: Missing required field: adminUsers")
+ }
+ if pTypeDef.Parent == "" {
+ return fmt.Errorf("SubDomain.parent is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Parent)
+ if !val.Valid {
+ return fmt.Errorf("SubDomain.parent does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// UserDomain - A UserDomain is the user's own top level domain in user - e.g.
+// user.hga
+//
+type UserDomain struct {
+
+ //
+ // a description of the domain
+ //
+ Description string `json:"description,omitempty" rdl:"optional"`
+
+ //
+ // a reference to an Organization. (i.e. org:media)
+ //
+ Org ResourceName `json:"org,omitempty" rdl:"optional"`
+
+ //
+ // Future use only, currently not used
+ //
+ Enabled *bool `json:"enabled,omitempty" rdl:"optional"`
+
+ //
+ // Flag indicates whether or not domain modifications should be logged for
+ // SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for
+ // any API defining it.
+ //
+ AuditEnabled *bool `json:"auditEnabled,omitempty" rdl:"optional"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+
+ //
+ // user id which will be the domain name
+ //
+ Name SimpleName `json:"name"`
+
+ //
+ // list of solution template names
+ //
+ Templates *DomainTemplateList `json:"templates,omitempty" rdl:"optional"`
+}
+
+//
+// NewUserDomain - creates an initialized UserDomain instance, returns a pointer to it
+//
+func NewUserDomain(init ...*UserDomain) *UserDomain {
+ var o *UserDomain
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(UserDomain)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *UserDomain) Init() *UserDomain {
+ if pTypeDef.Enabled == nil {
+ d := true
+ pTypeDef.Enabled = &d
+ }
+ if pTypeDef.AuditEnabled == nil {
+ d := false
+ pTypeDef.AuditEnabled = &d
+ }
+ return pTypeDef
+}
+
+type rawUserDomain UserDomain
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a UserDomain
+//
+func (pTypeDef *UserDomain) UnmarshalJSON(b []byte) error {
+ var r rawUserDomain
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := UserDomain(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *UserDomain) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("UserDomain.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("UserDomain.name does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// DanglingPolicy - A dangling policy where the assertion is referencing a role
+// name that doesn't exist in the domain
+//
+type DanglingPolicy struct {
+ PolicyName EntityName `json:"policyName"`
+ RoleName EntityName `json:"roleName"`
+}
+
+//
+// NewDanglingPolicy - creates an initialized DanglingPolicy instance, returns a pointer to it
+//
+func NewDanglingPolicy(init ...*DanglingPolicy) *DanglingPolicy {
+ var o *DanglingPolicy
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DanglingPolicy)
+ }
+ return o
+}
+
+type rawDanglingPolicy DanglingPolicy
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DanglingPolicy
+//
+func (pTypeDef *DanglingPolicy) UnmarshalJSON(b []byte) error {
+ var r rawDanglingPolicy
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DanglingPolicy(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DanglingPolicy) Validate() error {
+ if pTypeDef.PolicyName == "" {
+ return fmt.Errorf("DanglingPolicy.policyName is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.PolicyName)
+ if !val.Valid {
+ return fmt.Errorf("DanglingPolicy.policyName does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.RoleName == "" {
+ return fmt.Errorf("DanglingPolicy.roleName is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.RoleName)
+ if !val.Valid {
+ return fmt.Errorf("DanglingPolicy.roleName does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// DomainDataCheck - Domain data object representing the results of a check
+// operation looking for dangling roles, policies and trust relationships that
+// are set either on tenant or provider side only
+//
+type DomainDataCheck struct {
+
+ //
+ // Names of roles not specified in any assertion. Might be empty or null if no
+ // dangling roles.
+ //
+ DanglingRoles []EntityName `json:"danglingRoles,omitempty" rdl:"optional"`
+
+ //
+ // Policy+role tuples where role doesnt exist. Might be empty or null if no
+ // dangling policies.
+ //
+ DanglingPolicies []*DanglingPolicy `json:"danglingPolicies,omitempty" rdl:"optional"`
+
+ //
+ // total number of policies
+ //
+ PolicyCount int32 `json:"policyCount"`
+
+ //
+ // total number of assertions
+ //
+ AssertionCount int32 `json:"assertionCount"`
+
+ //
+ // total number of assertions containing roles as wildcards
+ //
+ RoleWildCardCount int32 `json:"roleWildCardCount"`
+
+ //
+ // Service names (domain.service) that dont contain trust role if this is a
+ // tenant domain. Might be empty or null, if not a tenant or if all providers
+ // support this tenant.
+ //
+ ProvidersWithoutTrust []ServiceName `json:"providersWithoutTrust,omitempty" rdl:"optional"`
+
+ //
+ // Names of Tenant domains that dont contain assume role assertions if this is
+ // a provider domain. Might be empty or null, if not a provider or if all
+ // tenants support use this provider.
+ //
+ TenantsWithoutAssumeRole []DomainName `json:"tenantsWithoutAssumeRole,omitempty" rdl:"optional"`
+}
+
+//
+// NewDomainDataCheck - creates an initialized DomainDataCheck instance, returns a pointer to it
+//
+func NewDomainDataCheck(init ...*DomainDataCheck) *DomainDataCheck {
+ var o *DomainDataCheck
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainDataCheck)
+ }
+ return o
+}
+
+type rawDomainDataCheck DomainDataCheck
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainDataCheck
+//
+func (pTypeDef *DomainDataCheck) UnmarshalJSON(b []byte) error {
+ var r rawDomainDataCheck
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainDataCheck(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainDataCheck) Validate() error {
+ return nil
+}
+
+//
+// Entity - An entity is a name and a structured value. some entity
+// names/prefixes are reserved (i.e. "role", "policy", "meta", "domain",
+// "service")
+//
+type Entity struct {
+
+ //
+ // name of the entity object
+ //
+ Name EntityName `json:"name"`
+
+ //
+ // value of the entity
+ //
+ Value rdl.Struct `json:"value"`
+}
+
+//
+// NewEntity - creates an initialized Entity instance, returns a pointer to it
+//
+func NewEntity(init ...*Entity) *Entity {
+ var o *Entity
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Entity)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Entity) Init() *Entity {
+ if pTypeDef.Value == nil {
+ pTypeDef.Value = make(rdl.Struct)
+ }
+ return pTypeDef
+}
+
+type rawEntity Entity
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Entity
+//
+func (pTypeDef *Entity) UnmarshalJSON(b []byte) error {
+ var r rawEntity
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Entity(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Entity) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Entity.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Entity.name does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Value == nil {
+ return fmt.Errorf("Entity: Missing required field: value")
+ }
+ return nil
+}
+
+//
+// EntityList - The representation for an enumeration of entities in the
+// namespace
+//
+type EntityList struct {
+
+ //
+ // list of entity names
+ //
+ Names []EntityName `json:"names"`
+}
+
+//
+// NewEntityList - creates an initialized EntityList instance, returns a pointer to it
+//
+func NewEntityList(init ...*EntityList) *EntityList {
+ var o *EntityList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(EntityList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *EntityList) Init() *EntityList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawEntityList EntityList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a EntityList
+//
+func (pTypeDef *EntityList) UnmarshalJSON(b []byte) error {
+ var r rawEntityList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := EntityList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *EntityList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("EntityList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// PolicyList - The representation for an enumeration of policies in the
+// namespace, with pagination.
+//
+type PolicyList struct {
+
+ //
+ // list of policy names
+ //
+ Names []EntityName `json:"names"`
+
+ //
+ // if the response is a paginated list, this attribute specifies the value to
+ // be used in the next policy list request as the value for the skip query
+ // parameter.
+ //
+ Next string `json:"next,omitempty" rdl:"optional"`
+}
+
+//
+// NewPolicyList - creates an initialized PolicyList instance, returns a pointer to it
+//
+func NewPolicyList(init ...*PolicyList) *PolicyList {
+ var o *PolicyList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(PolicyList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *PolicyList) Init() *PolicyList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawPolicyList PolicyList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a PolicyList
+//
+func (pTypeDef *PolicyList) UnmarshalJSON(b []byte) error {
+ var r rawPolicyList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := PolicyList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *PolicyList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("PolicyList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// PublicKeyEntry - The representation of the public key in a service identity
+// object.
+//
+type PublicKeyEntry struct {
+
+ //
+ // the public key for the service
+ //
+ Key string `json:"key"`
+
+ //
+ // the key identifier (version or zone name)
+ //
+ Id string `json:"id"`
+}
+
+//
+// NewPublicKeyEntry - creates an initialized PublicKeyEntry instance, returns a pointer to it
+//
+func NewPublicKeyEntry(init ...*PublicKeyEntry) *PublicKeyEntry {
+ var o *PublicKeyEntry
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(PublicKeyEntry)
+ }
+ return o
+}
+
+type rawPublicKeyEntry PublicKeyEntry
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a PublicKeyEntry
+//
+func (pTypeDef *PublicKeyEntry) UnmarshalJSON(b []byte) error {
+ var r rawPublicKeyEntry
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := PublicKeyEntry(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *PublicKeyEntry) Validate() error {
+ if pTypeDef.Key == "" {
+ return fmt.Errorf("PublicKeyEntry.key is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Key)
+ if !val.Valid {
+ return fmt.Errorf("PublicKeyEntry.key does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Id == "" {
+ return fmt.Errorf("PublicKeyEntry.id is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Id)
+ if !val.Valid {
+ return fmt.Errorf("PublicKeyEntry.id does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ServiceIdentity - The representation of the service identity object.
+//
+type ServiceIdentity struct {
+
+ //
+ // the full name of the service, i.e. "sports.storage"
+ //
+ Name ServiceName `json:"name"`
+
+ //
+ // array of public keys for key rotation
+ //
+ PublicKeys []*PublicKeyEntry `json:"publicKeys,omitempty" rdl:"optional"`
+
+ //
+ // if present, then this service can provision tenants via this endpoint.
+ //
+ ProviderEndpoint string `json:"providerEndpoint,omitempty" rdl:"optional"`
+
+ //
+ // the timestamp when this entry was last modified
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // the path of the executable that runs the service
+ //
+ Executable string `json:"executable,omitempty" rdl:"optional"`
+
+ //
+ // list of host names that this service can run on
+ //
+ Hosts []string `json:"hosts,omitempty" rdl:"optional"`
+
+ //
+ // local (unix) user name this service can run as
+ //
+ User string `json:"user,omitempty" rdl:"optional"`
+
+ //
+ // local (unix) group name this service can run as
+ //
+ Group string `json:"group,omitempty" rdl:"optional"`
+}
+
+//
+// NewServiceIdentity - creates an initialized ServiceIdentity instance, returns a pointer to it
+//
+func NewServiceIdentity(init ...*ServiceIdentity) *ServiceIdentity {
+ var o *ServiceIdentity
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServiceIdentity)
+ }
+ return o
+}
+
+type rawServiceIdentity ServiceIdentity
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServiceIdentity
+//
+func (pTypeDef *ServiceIdentity) UnmarshalJSON(b []byte) error {
+ var r rawServiceIdentity
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServiceIdentity(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServiceIdentity) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("ServiceIdentity.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ServiceName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("ServiceIdentity.name does not contain a valid ServiceName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ServiceIdentities - The representation of list of services
+//
+type ServiceIdentities struct {
+
+ //
+ // list of services
+ //
+ List []*ServiceIdentity `json:"list"`
+}
+
+//
+// NewServiceIdentities - creates an initialized ServiceIdentities instance, returns a pointer to it
+//
+func NewServiceIdentities(init ...*ServiceIdentities) *ServiceIdentities {
+ var o *ServiceIdentities
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServiceIdentities)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ServiceIdentities) Init() *ServiceIdentities {
+ if pTypeDef.List == nil {
+ pTypeDef.List = make([]*ServiceIdentity, 0)
+ }
+ return pTypeDef
+}
+
+type rawServiceIdentities ServiceIdentities
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServiceIdentities
+//
+func (pTypeDef *ServiceIdentities) UnmarshalJSON(b []byte) error {
+ var r rawServiceIdentities
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServiceIdentities(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServiceIdentities) Validate() error {
+ if pTypeDef.List == nil {
+ return fmt.Errorf("ServiceIdentities: Missing required field: list")
+ }
+ return nil
+}
+
+//
+// ServiceIdentityList - The representation for an enumeration of services in
+// the namespace, with pagination.
+//
+type ServiceIdentityList struct {
+
+ //
+ // list of service names
+ //
+ Names []EntityName `json:"names"`
+
+ //
+ // if the response is a paginated list, this attribute specifies the value to
+ // be used in the next service list request as the value for the skip query
+ // parameter.
+ //
+ Next string `json:"next,omitempty" rdl:"optional"`
+}
+
+//
+// NewServiceIdentityList - creates an initialized ServiceIdentityList instance, returns a pointer to it
+//
+func NewServiceIdentityList(init ...*ServiceIdentityList) *ServiceIdentityList {
+ var o *ServiceIdentityList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServiceIdentityList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ServiceIdentityList) Init() *ServiceIdentityList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawServiceIdentityList ServiceIdentityList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServiceIdentityList
+//
+func (pTypeDef *ServiceIdentityList) UnmarshalJSON(b []byte) error {
+ var r rawServiceIdentityList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServiceIdentityList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServiceIdentityList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("ServiceIdentityList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// Tenancy - A representation of tenant.
+//
+type Tenancy struct {
+
+ //
+ // the domain that is to get a tenancy
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // the provider service on which the tenancy is to reside
+ //
+ Service ServiceName `json:"service"`
+
+ //
+ // registered resource groups for this tenant
+ //
+ ResourceGroups []EntityName `json:"resourceGroups,omitempty" rdl:"optional"`
+}
+
+//
+// NewTenancy - creates an initialized Tenancy instance, returns a pointer to it
+//
+func NewTenancy(init ...*Tenancy) *Tenancy {
+ var o *Tenancy
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Tenancy)
+ }
+ return o
+}
+
+type rawTenancy Tenancy
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Tenancy
+//
+func (pTypeDef *Tenancy) UnmarshalJSON(b []byte) error {
+ var r rawTenancy
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Tenancy(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Tenancy) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("Tenancy.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("Tenancy.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("Tenancy.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ServiceName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("Tenancy.service does not contain a valid ServiceName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// TenancyResourceGroup -
+//
+type TenancyResourceGroup struct {
+
+ //
+ // the domain that is to get a tenancy
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // the provider service on which the tenancy is to reside
+ //
+ Service ServiceName `json:"service"`
+
+ //
+ // registered resource group for this tenant
+ //
+ ResourceGroup EntityName `json:"resourceGroup"`
+}
+
+//
+// NewTenancyResourceGroup - creates an initialized TenancyResourceGroup instance, returns a pointer to it
+//
+func NewTenancyResourceGroup(init ...*TenancyResourceGroup) *TenancyResourceGroup {
+ var o *TenancyResourceGroup
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TenancyResourceGroup)
+ }
+ return o
+}
+
+type rawTenancyResourceGroup TenancyResourceGroup
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TenancyResourceGroup
+//
+func (pTypeDef *TenancyResourceGroup) UnmarshalJSON(b []byte) error {
+ var r rawTenancyResourceGroup
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TenancyResourceGroup(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TenancyResourceGroup) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("TenancyResourceGroup.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("TenancyResourceGroup.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("TenancyResourceGroup.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "ServiceName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("TenancyResourceGroup.service does not contain a valid ServiceName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.ResourceGroup == "" {
+ return fmt.Errorf("TenancyResourceGroup.resourceGroup is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.ResourceGroup)
+ if !val.Valid {
+ return fmt.Errorf("TenancyResourceGroup.resourceGroup does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// TenantRoleAction - A representation of tenant role action.
+//
+type TenantRoleAction struct {
+
+ //
+ // name of the role
+ //
+ Role SimpleName `json:"role"`
+
+ //
+ // action value for the generated policy assertion
+ //
+ Action string `json:"action"`
+}
+
+//
+// NewTenantRoleAction - creates an initialized TenantRoleAction instance, returns a pointer to it
+//
+func NewTenantRoleAction(init ...*TenantRoleAction) *TenantRoleAction {
+ var o *TenantRoleAction
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TenantRoleAction)
+ }
+ return o
+}
+
+type rawTenantRoleAction TenantRoleAction
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TenantRoleAction
+//
+func (pTypeDef *TenantRoleAction) UnmarshalJSON(b []byte) error {
+ var r rawTenantRoleAction
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TenantRoleAction(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TenantRoleAction) Validate() error {
+ if pTypeDef.Role == "" {
+ return fmt.Errorf("TenantRoleAction.role is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Role)
+ if !val.Valid {
+ return fmt.Errorf("TenantRoleAction.role does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Action == "" {
+ return fmt.Errorf("TenantRoleAction.action is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Action)
+ if !val.Valid {
+ return fmt.Errorf("TenantRoleAction.action does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// TenantRoles - A representation of tenant roles to be provisioned.
+//
+type TenantRoles struct {
+
+ //
+ // name of the provider domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // name of the provider service
+ //
+ Service SimpleName `json:"service"`
+
+ //
+ // name of the tenant domain
+ //
+ Tenant DomainName `json:"tenant"`
+
+ //
+ // the role/action pairs to provision
+ //
+ Roles []*TenantRoleAction `json:"roles"`
+}
+
+//
+// NewTenantRoles - creates an initialized TenantRoles instance, returns a pointer to it
+//
+func NewTenantRoles(init ...*TenantRoles) *TenantRoles {
+ var o *TenantRoles
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TenantRoles)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *TenantRoles) Init() *TenantRoles {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]*TenantRoleAction, 0)
+ }
+ return pTypeDef
+}
+
+type rawTenantRoles TenantRoles
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TenantRoles
+//
+func (pTypeDef *TenantRoles) UnmarshalJSON(b []byte) error {
+ var r rawTenantRoles
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TenantRoles(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TenantRoles) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("TenantRoles.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("TenantRoles.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("TenantRoles.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("TenantRoles.service does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Tenant == "" {
+ return fmt.Errorf("TenantRoles.tenant is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Tenant)
+ if !val.Valid {
+ return fmt.Errorf("TenantRoles.tenant does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("TenantRoles: Missing required field: roles")
+ }
+ return nil
+}
+
+//
+// TenantResourceGroupRoles - A representation of tenant roles for resource
+// groups to be provisioned.
+//
+type TenantResourceGroupRoles struct {
+
+ //
+ // name of the provider domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // name of the provider service
+ //
+ Service SimpleName `json:"service"`
+
+ //
+ // name of the tenant domain
+ //
+ Tenant DomainName `json:"tenant"`
+
+ //
+ // the role/action pairs to provision
+ //
+ Roles []*TenantRoleAction `json:"roles"`
+
+ //
+ // tenant resource group
+ //
+ ResourceGroup EntityName `json:"resourceGroup"`
+}
+
+//
+// NewTenantResourceGroupRoles - creates an initialized TenantResourceGroupRoles instance, returns a pointer to it
+//
+func NewTenantResourceGroupRoles(init ...*TenantResourceGroupRoles) *TenantResourceGroupRoles {
+ var o *TenantResourceGroupRoles
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TenantResourceGroupRoles)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *TenantResourceGroupRoles) Init() *TenantResourceGroupRoles {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]*TenantRoleAction, 0)
+ }
+ return pTypeDef
+}
+
+type rawTenantResourceGroupRoles TenantResourceGroupRoles
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TenantResourceGroupRoles
+//
+func (pTypeDef *TenantResourceGroupRoles) UnmarshalJSON(b []byte) error {
+ var r rawTenantResourceGroupRoles
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TenantResourceGroupRoles(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TenantResourceGroupRoles) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("TenantResourceGroupRoles.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("TenantResourceGroupRoles.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("TenantResourceGroupRoles.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("TenantResourceGroupRoles.service does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Tenant == "" {
+ return fmt.Errorf("TenantResourceGroupRoles.tenant is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Tenant)
+ if !val.Valid {
+ return fmt.Errorf("TenantResourceGroupRoles.tenant does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("TenantResourceGroupRoles: Missing required field: roles")
+ }
+ if pTypeDef.ResourceGroup == "" {
+ return fmt.Errorf("TenantResourceGroupRoles.resourceGroup is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.ResourceGroup)
+ if !val.Valid {
+ return fmt.Errorf("TenantResourceGroupRoles.resourceGroup does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ProviderResourceGroupRoles - A representation of provider roles to be
+// provisioned.
+//
+type ProviderResourceGroupRoles struct {
+
+ //
+ // name of the provider domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // name of the provider service
+ //
+ Service SimpleName `json:"service"`
+
+ //
+ // name of the tenant domain
+ //
+ Tenant DomainName `json:"tenant"`
+
+ //
+ // the role/action pairs to provision
+ //
+ Roles []*TenantRoleAction `json:"roles"`
+
+ //
+ // tenant resource group
+ //
+ ResourceGroup EntityName `json:"resourceGroup"`
+}
+
+//
+// NewProviderResourceGroupRoles - creates an initialized ProviderResourceGroupRoles instance, returns a pointer to it
+//
+func NewProviderResourceGroupRoles(init ...*ProviderResourceGroupRoles) *ProviderResourceGroupRoles {
+ var o *ProviderResourceGroupRoles
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ProviderResourceGroupRoles)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ProviderResourceGroupRoles) Init() *ProviderResourceGroupRoles {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]*TenantRoleAction, 0)
+ }
+ return pTypeDef
+}
+
+type rawProviderResourceGroupRoles ProviderResourceGroupRoles
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ProviderResourceGroupRoles
+//
+func (pTypeDef *ProviderResourceGroupRoles) UnmarshalJSON(b []byte) error {
+ var r rawProviderResourceGroupRoles
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ProviderResourceGroupRoles(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ProviderResourceGroupRoles) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("ProviderResourceGroupRoles.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("ProviderResourceGroupRoles.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("ProviderResourceGroupRoles.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SimpleName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("ProviderResourceGroupRoles.service does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Tenant == "" {
+ return fmt.Errorf("ProviderResourceGroupRoles.tenant is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Tenant)
+ if !val.Valid {
+ return fmt.Errorf("ProviderResourceGroupRoles.tenant does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("ProviderResourceGroupRoles: Missing required field: roles")
+ }
+ if pTypeDef.ResourceGroup == "" {
+ return fmt.Errorf("ProviderResourceGroupRoles.resourceGroup is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.ResourceGroup)
+ if !val.Valid {
+ return fmt.Errorf("ProviderResourceGroupRoles.resourceGroup does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Access - Access can be checked and returned as this resource.
+//
+type Access struct {
+
+ //
+ // true (allowed) or false (denied)
+ //
+ Granted bool `json:"granted"`
+}
+
+//
+// NewAccess - creates an initialized Access instance, returns a pointer to it
+//
+func NewAccess(init ...*Access) *Access {
+ var o *Access
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Access)
+ }
+ return o
+}
+
+type rawAccess Access
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Access
+//
+func (pTypeDef *Access) UnmarshalJSON(b []byte) error {
+ var r rawAccess
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Access(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Access) Validate() error {
+ return nil
+}
+
+//
+// ResourceAccess -
+//
+type ResourceAccess struct {
+ Principal EntityName `json:"principal"`
+ Assertions []*Assertion `json:"assertions"`
+}
+
+//
+// NewResourceAccess - creates an initialized ResourceAccess instance, returns a pointer to it
+//
+func NewResourceAccess(init ...*ResourceAccess) *ResourceAccess {
+ var o *ResourceAccess
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ResourceAccess)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ResourceAccess) Init() *ResourceAccess {
+ if pTypeDef.Assertions == nil {
+ pTypeDef.Assertions = make([]*Assertion, 0)
+ }
+ return pTypeDef
+}
+
+type rawResourceAccess ResourceAccess
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ResourceAccess
+//
+func (pTypeDef *ResourceAccess) UnmarshalJSON(b []byte) error {
+ var r rawResourceAccess
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ResourceAccess(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ResourceAccess) Validate() error {
+ if pTypeDef.Principal == "" {
+ return fmt.Errorf("ResourceAccess.principal is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.Principal)
+ if !val.Valid {
+ return fmt.Errorf("ResourceAccess.principal does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Assertions == nil {
+ return fmt.Errorf("ResourceAccess: Missing required field: assertions")
+ }
+ return nil
+}
+
+//
+// ResourceAccessList -
+//
+type ResourceAccessList struct {
+ Resources []*ResourceAccess `json:"resources"`
+}
+
+//
+// NewResourceAccessList - creates an initialized ResourceAccessList instance, returns a pointer to it
+//
+func NewResourceAccessList(init ...*ResourceAccessList) *ResourceAccessList {
+ var o *ResourceAccessList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ResourceAccessList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ResourceAccessList) Init() *ResourceAccessList {
+ if pTypeDef.Resources == nil {
+ pTypeDef.Resources = make([]*ResourceAccess, 0)
+ }
+ return pTypeDef
+}
+
+type rawResourceAccessList ResourceAccessList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ResourceAccessList
+//
+func (pTypeDef *ResourceAccessList) UnmarshalJSON(b []byte) error {
+ var r rawResourceAccessList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ResourceAccessList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ResourceAccessList) Validate() error {
+ if pTypeDef.Resources == nil {
+ return fmt.Errorf("ResourceAccessList: Missing required field: resources")
+ }
+ return nil
+}
+
+//
+// DomainModified - Tuple of domain-name and modification time-stamps. This
+// object is returned when the caller has requested list of domains modified
+// since a specific timestamp.
+//
+type DomainModified struct {
+
+ //
+ // name of the domain
+ //
+ Name DomainName `json:"name"`
+
+ //
+ // last modified timestamp of the domain
+ //
+ Modified int64 `json:"modified"`
+}
+
+//
+// NewDomainModified - creates an initialized DomainModified instance, returns a pointer to it
+//
+func NewDomainModified(init ...*DomainModified) *DomainModified {
+ var o *DomainModified
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainModified)
+ }
+ return o
+}
+
+type rawDomainModified DomainModified
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainModified
+//
+func (pTypeDef *DomainModified) UnmarshalJSON(b []byte) error {
+ var r rawDomainModified
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainModified(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainModified) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("DomainModified.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("DomainModified.name does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// DomainModifiedList - A list of {domain, modified-timestamp} tuples.
+//
+type DomainModifiedList struct {
+
+ //
+ // list of modified domains
+ //
+ NameModList []*DomainModified `json:"nameModList"`
+}
+
+//
+// NewDomainModifiedList - creates an initialized DomainModifiedList instance, returns a pointer to it
+//
+func NewDomainModifiedList(init ...*DomainModifiedList) *DomainModifiedList {
+ var o *DomainModifiedList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainModifiedList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainModifiedList) Init() *DomainModifiedList {
+ if pTypeDef.NameModList == nil {
+ pTypeDef.NameModList = make([]*DomainModified, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainModifiedList DomainModifiedList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainModifiedList
+//
+func (pTypeDef *DomainModifiedList) UnmarshalJSON(b []byte) error {
+ var r rawDomainModifiedList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainModifiedList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainModifiedList) Validate() error {
+ if pTypeDef.NameModList == nil {
+ return fmt.Errorf("DomainModifiedList: Missing required field: nameModList")
+ }
+ return nil
+}
+
+//
+// DomainPolicies - We need to include the name of the domain in this struct
+// since this data will be passed back to ZPU through ZTS so we need to sign not
+// only the list of policies but also the corresponding domain name that the
+// policies belong to.
+//
+type DomainPolicies struct {
+
+ //
+ // name of the domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // list of policies defined in this server
+ //
+ Policies []*Policy `json:"policies"`
+}
+
+//
+// NewDomainPolicies - creates an initialized DomainPolicies instance, returns a pointer to it
+//
+func NewDomainPolicies(init ...*DomainPolicies) *DomainPolicies {
+ var o *DomainPolicies
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainPolicies)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainPolicies) Init() *DomainPolicies {
+ if pTypeDef.Policies == nil {
+ pTypeDef.Policies = make([]*Policy, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainPolicies DomainPolicies
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainPolicies
+//
+func (pTypeDef *DomainPolicies) UnmarshalJSON(b []byte) error {
+ var r rawDomainPolicies
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainPolicies(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainPolicies) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("DomainPolicies.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("DomainPolicies.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Policies == nil {
+ return fmt.Errorf("DomainPolicies: Missing required field: policies")
+ }
+ return nil
+}
+
+//
+// SignedPolicies - A signed bulk transfer of policies. The data is signed with
+// server's private key.
+//
+type SignedPolicies struct {
+
+ //
+ // list of policies defined in a domain
+ //
+ Contents *DomainPolicies `json:"contents"`
+
+ //
+ // signature generated based on the domain policies object
+ //
+ Signature string `json:"signature"`
+
+ //
+ // the identifier of the key used to generate the signature
+ //
+ KeyId string `json:"keyId"`
+}
+
+//
+// NewSignedPolicies - creates an initialized SignedPolicies instance, returns a pointer to it
+//
+func NewSignedPolicies(init ...*SignedPolicies) *SignedPolicies {
+ var o *SignedPolicies
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(SignedPolicies)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *SignedPolicies) Init() *SignedPolicies {
+ if pTypeDef.Contents == nil {
+ pTypeDef.Contents = NewDomainPolicies()
+ }
+ return pTypeDef
+}
+
+type rawSignedPolicies SignedPolicies
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a SignedPolicies
+//
+func (pTypeDef *SignedPolicies) UnmarshalJSON(b []byte) error {
+ var r rawSignedPolicies
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := SignedPolicies(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *SignedPolicies) Validate() error {
+ if pTypeDef.Contents == nil {
+ return fmt.Errorf("SignedPolicies: Missing required field: contents")
+ }
+ if pTypeDef.Signature == "" {
+ return fmt.Errorf("SignedPolicies.signature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Signature)
+ if !val.Valid {
+ return fmt.Errorf("SignedPolicies.signature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.KeyId == "" {
+ return fmt.Errorf("SignedPolicies.keyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.KeyId)
+ if !val.Valid {
+ return fmt.Errorf("SignedPolicies.keyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// DomainData - A domain object that includes its roles, policies and services.
+//
+type DomainData struct {
+
+ //
+ // name of the domain
+ //
+ Name DomainName `json:"name"`
+
+ //
+ // associated cloud (i.e. aws) account id
+ //
+ Account string `json:"account,omitempty" rdl:"optional"`
+
+ //
+ // associated product id
+ //
+ YpmId *int32 `json:"ypmId,omitempty" rdl:"optional"`
+
+ //
+ // list of roles in the domain
+ //
+ Roles []*Role `json:"roles"`
+
+ //
+ // list of policies in the domain signed with ZMS private key
+ //
+ Policies *SignedPolicies `json:"policies"`
+
+ //
+ // list of services in the domain
+ //
+ Services []*ServiceIdentity `json:"services"`
+
+ //
+ // list of entities in the domain
+ //
+ Entities []*Entity `json:"entities"`
+
+ //
+ // last modification timestamp
+ //
+ Modified rdl.Timestamp `json:"modified"`
+}
+
+//
+// NewDomainData - creates an initialized DomainData instance, returns a pointer to it
+//
+func NewDomainData(init ...*DomainData) *DomainData {
+ var o *DomainData
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainData)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainData) Init() *DomainData {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]*Role, 0)
+ }
+ if pTypeDef.Policies == nil {
+ pTypeDef.Policies = NewSignedPolicies()
+ }
+ if pTypeDef.Services == nil {
+ pTypeDef.Services = make([]*ServiceIdentity, 0)
+ }
+ if pTypeDef.Entities == nil {
+ pTypeDef.Entities = make([]*Entity, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainData DomainData
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainData
+//
+func (pTypeDef *DomainData) UnmarshalJSON(b []byte) error {
+ var r rawDomainData
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainData(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainData) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("DomainData.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("DomainData.name does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("DomainData: Missing required field: roles")
+ }
+ if pTypeDef.Policies == nil {
+ return fmt.Errorf("DomainData: Missing required field: policies")
+ }
+ if pTypeDef.Services == nil {
+ return fmt.Errorf("DomainData: Missing required field: services")
+ }
+ if pTypeDef.Entities == nil {
+ return fmt.Errorf("DomainData: Missing required field: entities")
+ }
+ if pTypeDef.Modified.IsZero() {
+ return fmt.Errorf("DomainData: Missing required field: modified")
+ }
+ return nil
+}
+
+//
+// SignedDomain - A domain object signed with server's private key
+//
+type SignedDomain struct {
+
+ //
+ // domain object with its roles, policies and services
+ //
+ Domain *DomainData `json:"domain"`
+
+ //
+ // signature generated based on the domain object
+ //
+ Signature string `json:"signature"`
+
+ //
+ // the identifier of the key used to generate the signature
+ //
+ KeyId string `json:"keyId"`
+}
+
+//
+// NewSignedDomain - creates an initialized SignedDomain instance, returns a pointer to it
+//
+func NewSignedDomain(init ...*SignedDomain) *SignedDomain {
+ var o *SignedDomain
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(SignedDomain)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *SignedDomain) Init() *SignedDomain {
+ if pTypeDef.Domain == nil {
+ pTypeDef.Domain = NewDomainData()
+ }
+ return pTypeDef
+}
+
+type rawSignedDomain SignedDomain
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a SignedDomain
+//
+func (pTypeDef *SignedDomain) UnmarshalJSON(b []byte) error {
+ var r rawSignedDomain
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := SignedDomain(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *SignedDomain) Validate() error {
+ if pTypeDef.Domain == nil {
+ return fmt.Errorf("SignedDomain: Missing required field: domain")
+ }
+ if pTypeDef.Signature == "" {
+ return fmt.Errorf("SignedDomain.signature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.Signature)
+ if !val.Valid {
+ return fmt.Errorf("SignedDomain.signature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.KeyId == "" {
+ return fmt.Errorf("SignedDomain.keyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "String", pTypeDef.KeyId)
+ if !val.Valid {
+ return fmt.Errorf("SignedDomain.keyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// SignedDomains - A list of signed domain objects
+//
+type SignedDomains struct {
+ Domains []*SignedDomain `json:"domains"`
+}
+
+//
+// NewSignedDomains - creates an initialized SignedDomains instance, returns a pointer to it
+//
+func NewSignedDomains(init ...*SignedDomains) *SignedDomains {
+ var o *SignedDomains
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(SignedDomains)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *SignedDomains) Init() *SignedDomains {
+ if pTypeDef.Domains == nil {
+ pTypeDef.Domains = make([]*SignedDomain, 0)
+ }
+ return pTypeDef
+}
+
+type rawSignedDomains SignedDomains
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a SignedDomains
+//
+func (pTypeDef *SignedDomains) UnmarshalJSON(b []byte) error {
+ var r rawSignedDomains
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := SignedDomains(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *SignedDomains) Validate() error {
+ if pTypeDef.Domains == nil {
+ return fmt.Errorf("SignedDomains: Missing required field: domains")
+ }
+ return nil
+}
+
+//
+// UserToken - A user token generated based on user's credentials
+//
+type UserToken struct {
+
+ //
+ // Signed user token identifying a specific authenticated user
+ //
+ Token SignedToken `json:"token"`
+}
+
+//
+// NewUserToken - creates an initialized UserToken instance, returns a pointer to it
+//
+func NewUserToken(init ...*UserToken) *UserToken {
+ var o *UserToken
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(UserToken)
+ }
+ return o
+}
+
+type rawUserToken UserToken
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a UserToken
+//
+func (pTypeDef *UserToken) UnmarshalJSON(b []byte) error {
+ var r rawUserToken
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := UserToken(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *UserToken) Validate() error {
+ if pTypeDef.Token == "" {
+ return fmt.Errorf("UserToken.token is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SignedToken", pTypeDef.Token)
+ if !val.Valid {
+ return fmt.Errorf("UserToken.token does not contain a valid SignedToken (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ServicePrincipal - A service principal object identifying a given service.
+//
+type ServicePrincipal struct {
+
+ //
+ // name of the domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // name of the service
+ //
+ Service EntityName `json:"service"`
+
+ //
+ // service's signed token
+ //
+ Token SignedToken `json:"token"`
+}
+
+//
+// NewServicePrincipal - creates an initialized ServicePrincipal instance, returns a pointer to it
+//
+func NewServicePrincipal(init ...*ServicePrincipal) *ServicePrincipal {
+ var o *ServicePrincipal
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServicePrincipal)
+ }
+ return o
+}
+
+type rawServicePrincipal ServicePrincipal
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServicePrincipal
+//
+func (pTypeDef *ServicePrincipal) UnmarshalJSON(b []byte) error {
+ var r rawServicePrincipal
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServicePrincipal(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServicePrincipal) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("ServicePrincipal.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("ServicePrincipal.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("ServicePrincipal.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "EntityName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("ServicePrincipal.service does not contain a valid EntityName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Token == "" {
+ return fmt.Errorf("ServicePrincipal.token is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZMSSchema(), "SignedToken", pTypeDef.Token)
+ if !val.Valid {
+ return fmt.Errorf("ServicePrincipal.token does not contain a valid SignedToken (%v)", val.Error)
+ }
+ }
+ return nil
+}
diff --git a/clients/go/zms/zms_schema.go b/clients/go/zms/zms_schema.go
new file mode 100644
index 00000000000..6779d012123
--- /dev/null
+++ b/clients/go/zms/zms_schema.go
@@ -0,0 +1,1233 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zms
+
+import (
+ rdl "github.com/ardielle/ardielle-go/rdl"
+)
+
+var schema *rdl.Schema
+
+func init() {
+ sb := rdl.NewSchemaBuilder("ZMS")
+ sb.Version(1)
+ sb.Namespace("com.yahoo.athenz.zms")
+ sb.Comment("Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. The Authorization Management Service (ZMS) Classes")
+
+ tSimpleName := rdl.NewStringTypeBuilder("SimpleName")
+ tSimpleName.Comment("Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. Common name types used by several API definitions A simple identifier, an element of compound name.")
+ tSimpleName.Pattern("[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tSimpleName.Build())
+
+ tCompoundName := rdl.NewStringTypeBuilder("CompoundName")
+ tCompoundName.Comment("A compound name. Most names in this API are compound names.")
+ tCompoundName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tCompoundName.Build())
+
+ tDomainName := rdl.NewStringTypeBuilder("DomainName")
+ tDomainName.Comment("A domain name is the general qualifier prefix, as its uniqueness is managed.")
+ tDomainName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tDomainName.Build())
+
+ tEntityName := rdl.NewStringTypeBuilder("EntityName")
+ tEntityName.Comment("An entity name is a short form of a resource name, including only the domain and entity.")
+ tEntityName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tEntityName.Build())
+
+ tServiceName := rdl.NewStringTypeBuilder("ServiceName")
+ tServiceName.Comment("A service name will generally be a unique subdomain.")
+ tServiceName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tServiceName.Build())
+
+ tLocationName := rdl.NewStringTypeBuilder("LocationName")
+ tLocationName.Comment("A location name is not yet defined, but will be a dotted name like everything else.")
+ tLocationName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tLocationName.Build())
+
+ tActionName := rdl.NewStringTypeBuilder("ActionName")
+ tActionName.Comment("An action (operation) name.")
+ tActionName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tActionName.Build())
+
+ tResourceName := rdl.NewStringTypeBuilder("ResourceName")
+ tResourceName.Comment("A shorthand for a YRN with no service or location. The 'tail' of a YRN, just the domain:entity. Note that the EntityName part is optional, that is, a domain name followed by a colon is valid resource name.")
+ tResourceName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*(:([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?")
+ sb.AddType(tResourceName.Build())
+
+ tYRN := rdl.NewStringTypeBuilder("YRN")
+ tYRN.Comment("A full Yahoo Resource name (YRN).")
+ tYRN.Pattern("(yrn:(([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?:(([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?:)?([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*(:([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?")
+ sb.AddType(tYRN.Build())
+
+ tYBase64 := rdl.NewStringTypeBuilder("YBase64")
+ tYBase64.Comment("The Y-specific URL-safe Base64 variant.")
+ tYBase64.Pattern("[a-zA-Z0-9\\._-]+")
+ sb.AddType(tYBase64.Build())
+
+ tYEncoded := rdl.NewStringTypeBuilder("YEncoded")
+ tYEncoded.Comment("YEncoded includes ybase64 chars, as well as = and %. This can represent a user cookie and URL-encoded values.")
+ tYEncoded.Pattern("[a-zA-Z0-9\\._%=-]*")
+ sb.AddType(tYEncoded.Build())
+
+ tAuthorityName := rdl.NewStringTypeBuilder("AuthorityName")
+ tAuthorityName.Comment("Used as the prefix in a signed assertion. This uniquely identifies a signing authority. i.e. \"user\"")
+ tAuthorityName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tAuthorityName.Build())
+
+ tSignedToken := rdl.NewStringTypeBuilder("SignedToken")
+ tSignedToken.Comment("A signed assertion if identity. i.e. the user cookie value. This token will only make sense to the authority that generated it, so it is beneficial to have something in the value that is cheaply recognized to quickly reject if it belongs to another authority. In addition to the YEncoded set our token includes ; to separate components and , to separate roles and : for IPv6 addresses")
+ tSignedToken.Pattern("[a-zA-Z0-9\\._%=:;,-]*")
+ sb.AddType(tSignedToken.Build())
+
+ tDomain := rdl.NewStructTypeBuilder("Struct", "Domain")
+ tDomain.Comment("A domain is an independent partition of users, roles, and resources. Its name represents the definition of a namespace; the only way a new namespace can be created, from the top, is by creating Domains. Administration of a domain is governed by the parent domain (using reverse-DNS namespaces). The top level domains are governed by the special \"sys.auth\" domain.")
+ tDomain.Field("name", "DomainName", false, nil, "the common name to be referred to, the symbolic id. It is immutable")
+ tDomain.Field("modified", "Timestamp", true, nil, "the last modification timestamp of any object or attribute in this domain")
+ tDomain.Field("id", "UUID", true, nil, "unique identifier of the domain. generated on create, never reused")
+ tDomain.Field("description", "String", true, nil, "description of the domain")
+ tDomain.Field("org", "ResourceName", true, nil, "a reference to an Organization")
+ tDomain.Field("enabled", "Bool", true, true, "Future use only, currently not used")
+ tDomain.Field("auditEnabled", "Bool", true, false, "Flag indicates whether or not domain modifications should be logged for SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for any API defining it.")
+ tDomain.Field("account", "String", true, nil, "associated cloud (i.e. aws) account id")
+ tDomain.Field("ypmId", "Int32", true, nil, "associated product id")
+ sb.AddType(tDomain.Build())
+
+ tRoleList := rdl.NewStructTypeBuilder("Struct", "RoleList")
+ tRoleList.Comment("The representation for an enumeration of roles in the namespace, with pagination.")
+ tRoleList.ArrayField("names", "EntityName", false, "list of role names")
+ tRoleList.Field("next", "String", true, nil, "if the response is a paginated list, this attribute specifies the value to be used in the next role list request as the value for the skip query parameter.")
+ sb.AddType(tRoleList.Build())
+
+ tRoleAuditLog := rdl.NewStructTypeBuilder("Struct", "RoleAuditLog")
+ tRoleAuditLog.Comment("An audit log entry for role membership change.")
+ tRoleAuditLog.Field("member", "ResourceName", false, nil, "name of the role member")
+ tRoleAuditLog.Field("admin", "ResourceName", false, nil, "name of the principal executing the change")
+ tRoleAuditLog.Field("created", "Timestamp", false, nil, "timestamp of the entry")
+ tRoleAuditLog.Field("action", "String", false, nil, "log action - either add or delete")
+ tRoleAuditLog.Field("auditRef", "String", true, nil, "audit reference string for the change as supplied by admin")
+ sb.AddType(tRoleAuditLog.Build())
+
+ tRole := rdl.NewStructTypeBuilder("Struct", "Role")
+ tRole.Comment("The representation for a Role with set of members.")
+ tRole.Field("name", "ResourceName", false, nil, "name of the role")
+ tRole.Field("modified", "Timestamp", true, nil, "last modification timestamp of the role")
+ tRole.ArrayField("members", "ResourceName", true, "an explicit list of members. Might be empty or null, if trust is set")
+ tRole.Field("trust", "DomainName", true, nil, "a trusted domain to delegate membership decisions to")
+ tRole.ArrayField("auditLog", "RoleAuditLog", true, "an audit log for role membership changes")
+ sb.AddType(tRole.Build())
+
+ tRoles := rdl.NewStructTypeBuilder("Struct", "Roles")
+ tRoles.Comment("The representation for a list of roles with full details")
+ tRoles.ArrayField("list", "Role", false, "list of role objects")
+ sb.AddType(tRoles.Build())
+
+ tMembership := rdl.NewStructTypeBuilder("Struct", "Membership")
+ tMembership.Comment("The representation for a role membership.")
+ tMembership.Field("memberName", "ResourceName", false, nil, "name of the member")
+ tMembership.Field("isMember", "Bool", true, true, "flag to indicate whether or the user is a member or not")
+ tMembership.Field("roleName", "ResourceName", true, nil, "name of the role")
+ sb.AddType(tMembership.Build())
+
+ tDefaultAdmins := rdl.NewStructTypeBuilder("Struct", "DefaultAdmins")
+ tDefaultAdmins.Comment("The list of domain administrators.")
+ tDefaultAdmins.ArrayField("admins", "ResourceName", false, "list of domain administrators")
+ sb.AddType(tDefaultAdmins.Build())
+
+ tAssertionEffect := rdl.NewEnumTypeBuilder("Enum", "AssertionEffect")
+ tAssertionEffect.Comment("Every assertion can have the effect of ALLOW or DENY.")
+ tAssertionEffect.Element("ALLOW", "Every assertion can have the effect of ALLOW or DENY.")
+ tAssertionEffect.Element("DENY", "")
+ sb.AddType(tAssertionEffect.Build())
+
+ tAssertion := rdl.NewStructTypeBuilder("Struct", "Assertion")
+ tAssertion.Comment("A representation for the encapsulation of an action to be performed on a resource by a principal.")
+ tAssertion.Field("role", "String", false, nil, "the subject of the assertion - a role")
+ tAssertion.Field("resource", "String", false, nil, "the object of the assertion. Must be in the local namespace. Can contain wildcards")
+ tAssertion.Field("action", "String", false, nil, "the predicate of the assertion. Can contain wildcards")
+ tAssertion.Field("effect", "AssertionEffect", true, ALLOW, "the effect of the assertion in the policy language")
+ tAssertion.Field("id", "Int64", true, nil, "assertion id - auto generated by server. Not required during put operations.")
+ sb.AddType(tAssertion.Build())
+
+ tPolicy := rdl.NewStructTypeBuilder("Struct", "Policy")
+ tPolicy.Comment("The representation for a Policy with set of assertions.")
+ tPolicy.Field("name", "ResourceName", false, nil, "name of the policy")
+ tPolicy.Field("modified", "Timestamp", true, nil, "last modification timestamp of this policy")
+ tPolicy.ArrayField("assertions", "Assertion", false, "list of defined assertions for this policy")
+ sb.AddType(tPolicy.Build())
+
+ tPolicies := rdl.NewStructTypeBuilder("Struct", "Policies")
+ tPolicies.Comment("The representation of list of policy objects")
+ tPolicies.ArrayField("list", "Policy", false, "list of policy objects")
+ sb.AddType(tPolicies.Build())
+
+ tTemplate := rdl.NewStructTypeBuilder("Struct", "Template")
+ tTemplate.Comment("Solution Template object defined on the server")
+ tTemplate.ArrayField("roles", "Role", false, "list of roles in the template")
+ tTemplate.ArrayField("policies", "Policy", false, "list of policies defined in this template")
+ sb.AddType(tTemplate.Build())
+
+ tTemplateList := rdl.NewStructTypeBuilder("Struct", "TemplateList")
+ tTemplateList.Comment("List of template names that is the base struct for server and domain templates")
+ tTemplateList.ArrayField("templateNames", "SimpleName", false, "list of template names")
+ sb.AddType(tTemplateList.Build())
+
+ tDomainTemplate := rdl.NewStructTypeBuilder("TemplateList", "DomainTemplate")
+ tDomainTemplate.Comment("solution template(s) to be applied to a domain")
+ sb.AddType(tDomainTemplate.Build())
+
+ tDomainTemplateList := rdl.NewStructTypeBuilder("TemplateList", "DomainTemplateList")
+ tDomainTemplateList.Comment("List of solution templates to be applied to a domain")
+ sb.AddType(tDomainTemplateList.Build())
+
+ tServerTemplateList := rdl.NewStructTypeBuilder("TemplateList", "ServerTemplateList")
+ tServerTemplateList.Comment("List of solution templates available in the server")
+ sb.AddType(tServerTemplateList.Build())
+
+ tDomainList := rdl.NewStructTypeBuilder("Struct", "DomainList")
+ tDomainList.Comment("A paginated list of domains.")
+ tDomainList.ArrayField("names", "DomainName", false, "list of domain names")
+ tDomainList.Field("next", "String", true, nil, "if the response is a paginated list, this attribute specifies the value to be used in the next domain list request as the value for the skip query parameter.")
+ sb.AddType(tDomainList.Build())
+
+ tDomainMeta := rdl.NewStructTypeBuilder("Struct", "DomainMeta")
+ tDomainMeta.Comment("Set of metadata attributes that all domains may have and can be changed.")
+ tDomainMeta.Field("description", "String", true, nil, "a description of the domain")
+ tDomainMeta.Field("org", "ResourceName", true, nil, "a reference to an Organization. (i.e. org:media)")
+ tDomainMeta.Field("enabled", "Bool", true, true, "Future use only, currently not used")
+ tDomainMeta.Field("auditEnabled", "Bool", true, false, "Flag indicates whether or not domain modifications should be logged for SOX+Auditing. If true, the auditRef parameter must be supplied(not empty) for any API defining it.")
+ tDomainMeta.Field("account", "String", true, nil, "associated cloud (i.e. aws) account id")
+ tDomainMeta.Field("ypmId", "Int32", true, nil, "associated product id")
+ sb.AddType(tDomainMeta.Build())
+
+ tTopLevelDomain := rdl.NewStructTypeBuilder("DomainMeta", "TopLevelDomain")
+ tTopLevelDomain.Comment("Top Level Domain object. The required attributes include the name of the domain and list of domain administrators.")
+ tTopLevelDomain.Field("name", "SimpleName", false, nil, "name of the domain")
+ tTopLevelDomain.ArrayField("adminUsers", "ResourceName", false, "list of domain administrators")
+ tTopLevelDomain.Field("templates", "DomainTemplateList", true, nil, "list of solution template names")
+ sb.AddType(tTopLevelDomain.Build())
+
+ tSubDomain := rdl.NewStructTypeBuilder("TopLevelDomain", "SubDomain")
+ tSubDomain.Comment("A Subdomain is a TopLevelDomain, except it has a parent.")
+ tSubDomain.Field("parent", "DomainName", false, nil, "name of the parent domain")
+ sb.AddType(tSubDomain.Build())
+
+ tUserDomain := rdl.NewStructTypeBuilder("DomainMeta", "UserDomain")
+ tUserDomain.Comment("A UserDomain is the user's own top level domain in user - e.g. user.hga")
+ tUserDomain.Field("name", "SimpleName", false, nil, "user id which will be the domain name")
+ tUserDomain.Field("templates", "DomainTemplateList", true, nil, "list of solution template names")
+ sb.AddType(tUserDomain.Build())
+
+ tDanglingPolicy := rdl.NewStructTypeBuilder("Struct", "DanglingPolicy")
+ tDanglingPolicy.Comment("A dangling policy where the assertion is referencing a role name that doesn't exist in the domain")
+ tDanglingPolicy.Field("policyName", "EntityName", false, nil, "")
+ tDanglingPolicy.Field("roleName", "EntityName", false, nil, "")
+ sb.AddType(tDanglingPolicy.Build())
+
+ tDomainDataCheck := rdl.NewStructTypeBuilder("Struct", "DomainDataCheck")
+ tDomainDataCheck.Comment("Domain data object representing the results of a check operation looking for dangling roles, policies and trust relationships that are set either on tenant or provider side only")
+ tDomainDataCheck.ArrayField("danglingRoles", "EntityName", true, "Names of roles not specified in any assertion. Might be empty or null if no dangling roles.")
+ tDomainDataCheck.ArrayField("danglingPolicies", "DanglingPolicy", true, "Policy+role tuples where role doesnt exist. Might be empty or null if no dangling policies.")
+ tDomainDataCheck.Field("policyCount", "Int32", false, nil, "total number of policies")
+ tDomainDataCheck.Field("assertionCount", "Int32", false, nil, "total number of assertions")
+ tDomainDataCheck.Field("roleWildCardCount", "Int32", false, nil, "total number of assertions containing roles as wildcards")
+ tDomainDataCheck.ArrayField("providersWithoutTrust", "ServiceName", true, "Service names (domain.service) that dont contain trust role if this is a tenant domain. Might be empty or null, if not a tenant or if all providers support this tenant.")
+ tDomainDataCheck.ArrayField("tenantsWithoutAssumeRole", "DomainName", true, "Names of Tenant domains that dont contain assume role assertions if this is a provider domain. Might be empty or null, if not a provider or if all tenants support use this provider.")
+ sb.AddType(tDomainDataCheck.Build())
+
+ tEntity := rdl.NewStructTypeBuilder("Struct", "Entity")
+ tEntity.Comment("An entity is a name and a structured value. some entity names/prefixes are reserved (i.e. \"role\", \"policy\", \"meta\", \"domain\", \"service\")")
+ tEntity.Field("name", "EntityName", false, nil, "name of the entity object")
+ tEntity.Field("value", "Struct", false, nil, "value of the entity")
+ sb.AddType(tEntity.Build())
+
+ tEntityList := rdl.NewStructTypeBuilder("Struct", "EntityList")
+ tEntityList.Comment("The representation for an enumeration of entities in the namespace")
+ tEntityList.ArrayField("names", "EntityName", false, "list of entity names")
+ sb.AddType(tEntityList.Build())
+
+ tPolicyList := rdl.NewStructTypeBuilder("Struct", "PolicyList")
+ tPolicyList.Comment("The representation for an enumeration of policies in the namespace, with pagination.")
+ tPolicyList.ArrayField("names", "EntityName", false, "list of policy names")
+ tPolicyList.Field("next", "String", true, nil, "if the response is a paginated list, this attribute specifies the value to be used in the next policy list request as the value for the skip query parameter.")
+ sb.AddType(tPolicyList.Build())
+
+ tPublicKeyEntry := rdl.NewStructTypeBuilder("Struct", "PublicKeyEntry")
+ tPublicKeyEntry.Comment("The representation of the public key in a service identity object.")
+ tPublicKeyEntry.Field("key", "String", false, nil, "the public key for the service")
+ tPublicKeyEntry.Field("id", "String", false, nil, "the key identifier (version or zone name)")
+ sb.AddType(tPublicKeyEntry.Build())
+
+ tServiceIdentity := rdl.NewStructTypeBuilder("Struct", "ServiceIdentity")
+ tServiceIdentity.Comment("The representation of the service identity object.")
+ tServiceIdentity.Field("name", "ServiceName", false, nil, "the full name of the service, i.e. \"sports.storage\"")
+ tServiceIdentity.ArrayField("publicKeys", "PublicKeyEntry", true, "array of public keys for key rotation")
+ tServiceIdentity.Field("providerEndpoint", "String", true, nil, "if present, then this service can provision tenants via this endpoint.")
+ tServiceIdentity.Field("modified", "Timestamp", true, nil, "the timestamp when this entry was last modified")
+ tServiceIdentity.Field("executable", "String", true, nil, "the path of the executable that runs the service")
+ tServiceIdentity.ArrayField("hosts", "String", true, "list of host names that this service can run on")
+ tServiceIdentity.Field("user", "String", true, nil, "local (unix) user name this service can run as")
+ tServiceIdentity.Field("group", "String", true, nil, "local (unix) group name this service can run as")
+ sb.AddType(tServiceIdentity.Build())
+
+ tServiceIdentities := rdl.NewStructTypeBuilder("Struct", "ServiceIdentities")
+ tServiceIdentities.Comment("The representation of list of services")
+ tServiceIdentities.ArrayField("list", "ServiceIdentity", false, "list of services")
+ sb.AddType(tServiceIdentities.Build())
+
+ tServiceIdentityList := rdl.NewStructTypeBuilder("Struct", "ServiceIdentityList")
+ tServiceIdentityList.Comment("The representation for an enumeration of services in the namespace, with pagination.")
+ tServiceIdentityList.ArrayField("names", "EntityName", false, "list of service names")
+ tServiceIdentityList.Field("next", "String", true, nil, "if the response is a paginated list, this attribute specifies the value to be used in the next service list request as the value for the skip query parameter.")
+ sb.AddType(tServiceIdentityList.Build())
+
+ tTenancy := rdl.NewStructTypeBuilder("Struct", "Tenancy")
+ tTenancy.Comment("A representation of tenant.")
+ tTenancy.Field("domain", "DomainName", false, nil, "the domain that is to get a tenancy")
+ tTenancy.Field("service", "ServiceName", false, nil, "the provider service on which the tenancy is to reside")
+ tTenancy.ArrayField("resourceGroups", "EntityName", true, "registered resource groups for this tenant")
+ sb.AddType(tTenancy.Build())
+
+ tTenancyResourceGroup := rdl.NewStructTypeBuilder("Struct", "TenancyResourceGroup")
+ tTenancyResourceGroup.Field("domain", "DomainName", false, nil, "the domain that is to get a tenancy")
+ tTenancyResourceGroup.Field("service", "ServiceName", false, nil, "the provider service on which the tenancy is to reside")
+ tTenancyResourceGroup.Field("resourceGroup", "EntityName", false, nil, "registered resource group for this tenant")
+ sb.AddType(tTenancyResourceGroup.Build())
+
+ tTenantRoleAction := rdl.NewStructTypeBuilder("Struct", "TenantRoleAction")
+ tTenantRoleAction.Comment("A representation of tenant role action.")
+ tTenantRoleAction.Field("role", "SimpleName", false, nil, "name of the role")
+ tTenantRoleAction.Field("action", "String", false, nil, "action value for the generated policy assertion")
+ sb.AddType(tTenantRoleAction.Build())
+
+ tTenantRoles := rdl.NewStructTypeBuilder("Struct", "TenantRoles")
+ tTenantRoles.Comment("A representation of tenant roles to be provisioned.")
+ tTenantRoles.Field("domain", "DomainName", false, nil, "name of the provider domain")
+ tTenantRoles.Field("service", "SimpleName", false, nil, "name of the provider service")
+ tTenantRoles.Field("tenant", "DomainName", false, nil, "name of the tenant domain")
+ tTenantRoles.ArrayField("roles", "TenantRoleAction", false, "the role/action pairs to provision")
+ sb.AddType(tTenantRoles.Build())
+
+ tTenantResourceGroupRoles := rdl.NewStructTypeBuilder("Struct", "TenantResourceGroupRoles")
+ tTenantResourceGroupRoles.Comment("A representation of tenant roles for resource groups to be provisioned.")
+ tTenantResourceGroupRoles.Field("domain", "DomainName", false, nil, "name of the provider domain")
+ tTenantResourceGroupRoles.Field("service", "SimpleName", false, nil, "name of the provider service")
+ tTenantResourceGroupRoles.Field("tenant", "DomainName", false, nil, "name of the tenant domain")
+ tTenantResourceGroupRoles.ArrayField("roles", "TenantRoleAction", false, "the role/action pairs to provision")
+ tTenantResourceGroupRoles.Field("resourceGroup", "EntityName", false, nil, "tenant resource group")
+ sb.AddType(tTenantResourceGroupRoles.Build())
+
+ tProviderResourceGroupRoles := rdl.NewStructTypeBuilder("Struct", "ProviderResourceGroupRoles")
+ tProviderResourceGroupRoles.Comment("A representation of provider roles to be provisioned.")
+ tProviderResourceGroupRoles.Field("domain", "DomainName", false, nil, "name of the provider domain")
+ tProviderResourceGroupRoles.Field("service", "SimpleName", false, nil, "name of the provider service")
+ tProviderResourceGroupRoles.Field("tenant", "DomainName", false, nil, "name of the tenant domain")
+ tProviderResourceGroupRoles.ArrayField("roles", "TenantRoleAction", false, "the role/action pairs to provision")
+ tProviderResourceGroupRoles.Field("resourceGroup", "EntityName", false, nil, "tenant resource group")
+ sb.AddType(tProviderResourceGroupRoles.Build())
+
+ tAccess := rdl.NewStructTypeBuilder("Struct", "Access")
+ tAccess.Comment("Access can be checked and returned as this resource.")
+ tAccess.Field("granted", "Bool", false, nil, "true (allowed) or false (denied)")
+ sb.AddType(tAccess.Build())
+
+ tResourceAccess := rdl.NewStructTypeBuilder("Struct", "ResourceAccess")
+ tResourceAccess.Field("principal", "EntityName", false, nil, "")
+ tResourceAccess.ArrayField("assertions", "Assertion", false, "")
+ sb.AddType(tResourceAccess.Build())
+
+ tResourceAccessList := rdl.NewStructTypeBuilder("Struct", "ResourceAccessList")
+ tResourceAccessList.ArrayField("resources", "ResourceAccess", false, "")
+ sb.AddType(tResourceAccessList.Build())
+
+ tDomainModified := rdl.NewStructTypeBuilder("Struct", "DomainModified")
+ tDomainModified.Comment("Tuple of domain-name and modification time-stamps. This object is returned when the caller has requested list of domains modified since a specific timestamp.")
+ tDomainModified.Field("name", "DomainName", false, nil, "name of the domain")
+ tDomainModified.Field("modified", "Int64", false, nil, "last modified timestamp of the domain")
+ sb.AddType(tDomainModified.Build())
+
+ tDomainModifiedList := rdl.NewStructTypeBuilder("Struct", "DomainModifiedList")
+ tDomainModifiedList.Comment("A list of {domain, modified-timestamp} tuples.")
+ tDomainModifiedList.ArrayField("nameModList", "DomainModified", false, "list of modified domains")
+ sb.AddType(tDomainModifiedList.Build())
+
+ tDomainPolicies := rdl.NewStructTypeBuilder("Struct", "DomainPolicies")
+ tDomainPolicies.Comment("We need to include the name of the domain in this struct since this data will be passed back to ZPU through ZTS so we need to sign not only the list of policies but also the corresponding domain name that the policies belong to.")
+ tDomainPolicies.Field("domain", "DomainName", false, nil, "name of the domain")
+ tDomainPolicies.ArrayField("policies", "Policy", false, "list of policies defined in this server")
+ sb.AddType(tDomainPolicies.Build())
+
+ tSignedPolicies := rdl.NewStructTypeBuilder("Struct", "SignedPolicies")
+ tSignedPolicies.Comment("A signed bulk transfer of policies. The data is signed with server's private key.")
+ tSignedPolicies.Field("contents", "DomainPolicies", false, nil, "list of policies defined in a domain")
+ tSignedPolicies.Field("signature", "String", false, nil, "signature generated based on the domain policies object")
+ tSignedPolicies.Field("keyId", "String", false, nil, "the identifier of the key used to generate the signature")
+ sb.AddType(tSignedPolicies.Build())
+
+ tDomainData := rdl.NewStructTypeBuilder("Struct", "DomainData")
+ tDomainData.Comment("A domain object that includes its roles, policies and services.")
+ tDomainData.Field("name", "DomainName", false, nil, "name of the domain")
+ tDomainData.Field("account", "String", true, nil, "associated cloud (i.e. aws) account id")
+ tDomainData.Field("ypmId", "Int32", true, nil, "associated product id")
+ tDomainData.ArrayField("roles", "Role", false, "list of roles in the domain")
+ tDomainData.Field("policies", "SignedPolicies", false, nil, "list of policies in the domain signed with ZMS private key")
+ tDomainData.ArrayField("services", "ServiceIdentity", false, "list of services in the domain")
+ tDomainData.ArrayField("entities", "Entity", false, "list of entities in the domain")
+ tDomainData.Field("modified", "Timestamp", false, nil, "last modification timestamp")
+ sb.AddType(tDomainData.Build())
+
+ tSignedDomain := rdl.NewStructTypeBuilder("Struct", "SignedDomain")
+ tSignedDomain.Comment("A domain object signed with server's private key")
+ tSignedDomain.Field("domain", "DomainData", false, nil, "domain object with its roles, policies and services")
+ tSignedDomain.Field("signature", "String", false, nil, "signature generated based on the domain object")
+ tSignedDomain.Field("keyId", "String", false, nil, "the identifier of the key used to generate the signature")
+ sb.AddType(tSignedDomain.Build())
+
+ tSignedDomains := rdl.NewStructTypeBuilder("Struct", "SignedDomains")
+ tSignedDomains.Comment("A list of signed domain objects")
+ tSignedDomains.ArrayField("domains", "SignedDomain", false, "")
+ sb.AddType(tSignedDomains.Build())
+
+ tUserToken := rdl.NewStructTypeBuilder("Struct", "UserToken")
+ tUserToken.Comment("A user token generated based on user's credentials")
+ tUserToken.Field("token", "SignedToken", false, nil, "Signed user token identifying a specific authenticated user")
+ sb.AddType(tUserToken.Build())
+
+ tServicePrincipal := rdl.NewStructTypeBuilder("Struct", "ServicePrincipal")
+ tServicePrincipal.Comment("A service principal object identifying a given service.")
+ tServicePrincipal.Field("domain", "DomainName", false, nil, "name of the domain")
+ tServicePrincipal.Field("service", "EntityName", false, nil, "name of the service")
+ tServicePrincipal.Field("token", "SignedToken", false, nil, "service's signed token")
+ sb.AddType(tServicePrincipal.Build())
+
+ rGetDomain := rdl.NewResourceBuilder("Domain", "GET", "/domain/{domain}")
+ rGetDomain.Comment("Get info for the specified domain, by name. This request only returns the configured domain attributes and not any domain objects like roles, policies or service identities.")
+ rGetDomain.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetDomain.Auth("", "", true, "")
+ rGetDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rGetDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rGetDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetDomain.Build())
+
+ rGetDomainList := rdl.NewResourceBuilder("DomainList", "GET", "/domain")
+ rGetDomainList.Comment("Enumerate domains. Can be filtered by prefix and depth, and paginated. This operation can be expensive, as it may span multiple domains.")
+ rGetDomainList.Input("limit", "Int32", false, "limit", "", true, nil, "restrict the number of results in this call")
+ rGetDomainList.Input("skip", "String", false, "skip", "", true, nil, "restrict the set to those after the specified \"next\" token returned from a previous call")
+ rGetDomainList.Input("prefix", "String", false, "prefix", "", true, nil, "restrict to names that start with the prefix")
+ rGetDomainList.Input("depth", "Int32", false, "depth", "", true, nil, "restrict the depth of the name, specifying the number of '.' characters that can appear")
+ rGetDomainList.Input("account", "String", false, "account", "", true, nil, "restrict to domain names that have specified account name")
+ rGetDomainList.Input("productId", "Int32", false, "ypmid", "", true, nil, "restrict the domain names that have specified product id")
+ rGetDomainList.Input("roleMember", "ResourceName", false, "member", "", true, nil, "restrict the domain names where the specified user is in a role - see roleName")
+ rGetDomainList.Input("roleName", "ResourceName", false, "role", "", true, nil, "restrict the domain names where the specified user is in this role - see roleMember")
+ rGetDomainList.Input("modifiedSince", "String", false, "", "If-Modified-Since", false, nil, "This header specifies to the server to return any domains modified since this HTTP date")
+ rGetDomainList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetDomainList.Build())
+
+ rPostTopLevelDomain := rdl.NewResourceBuilder("Domain", "POST", "/domain")
+ rPostTopLevelDomain.Comment("Create a new top level domain. This is a privileged action for the \"sys.auth\" administrators.")
+ rPostTopLevelDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPostTopLevelDomain.Input("detail", "TopLevelDomain", false, "", "", false, nil, "TopLevelDomain object to be created")
+ rPostTopLevelDomain.Auth("create", "sys.auth:domain", false, "")
+ rPostTopLevelDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostTopLevelDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rPostTopLevelDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostTopLevelDomain.Build())
+
+ rPostSubDomain := rdl.NewResourceBuilder("Domain", "POST", "/subdomain/{parent}")
+ rPostSubDomain.Comment("Create a new subdomain. The domain administrators of the {parent} domain have the privilege to create subdomains.")
+ rPostSubDomain.Input("parent", "DomainName", true, "", "", false, nil, "name of the parent domain")
+ rPostSubDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPostSubDomain.Input("detail", "SubDomain", false, "", "", false, nil, "Subdomain object to be created")
+ rPostSubDomain.Auth("create", "{parent}:domain", false, "")
+ rPostSubDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostSubDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rPostSubDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rPostSubDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostSubDomain.Build())
+
+ rPostUserDomain := rdl.NewResourceBuilder("Domain", "POST", "/userdomain/{name}")
+ rPostUserDomain.Comment("Create a new user domain. The user domain will be created in the user top level domain and the user himself will be set as the administrator for this domain.")
+ rPostUserDomain.Input("name", "SimpleName", true, "", "", false, nil, "name of the domain which will be the user id")
+ rPostUserDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPostUserDomain.Input("detail", "UserDomain", false, "", "", false, nil, "UserDomain object to be created")
+ rPostUserDomain.Auth("create", "user.{name}:domain", false, "")
+ rPostUserDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostUserDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rPostUserDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rPostUserDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostUserDomain.Build())
+
+ rDeleteTopLevelDomain := rdl.NewResourceBuilder("TopLevelDomain", "DELETE", "/domain/{name}")
+ rDeleteTopLevelDomain.Comment("Delete the specified domain. This is a privileged action for the \"sys.auth\" administrators. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteTopLevelDomain.Input("name", "DomainName", true, "", "", false, nil, "name of the domain to be deleted")
+ rDeleteTopLevelDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteTopLevelDomain.Auth("delete", "sys.auth:domain", false, "")
+ rDeleteTopLevelDomain.Expected("NO_CONTENT")
+ rDeleteTopLevelDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteTopLevelDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteTopLevelDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteTopLevelDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteTopLevelDomain.Build())
+
+ rDeleteSubDomain := rdl.NewResourceBuilder("SubDomain", "DELETE", "/subdomain/{parent}/{name}")
+ rDeleteSubDomain.Comment("Delete the specified subdomain. Caller must have domain delete permissions in parent. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteSubDomain.Input("parent", "DomainName", true, "", "", false, nil, "name of the parent domain")
+ rDeleteSubDomain.Input("name", "DomainName", true, "", "", false, nil, "name of the subdomain to be deleted")
+ rDeleteSubDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteSubDomain.Auth("delete", "{parent}:domain", false, "")
+ rDeleteSubDomain.Expected("NO_CONTENT")
+ rDeleteSubDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteSubDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteSubDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteSubDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteSubDomain.Build())
+
+ rDeleteUserDomain := rdl.NewResourceBuilder("UserDomain", "DELETE", "/userdomain/{name}")
+ rDeleteUserDomain.Comment("Delete the specified userdomain. Caller must have domain delete permissions in the domain. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteUserDomain.Input("name", "SimpleName", true, "", "", false, nil, "name of the domain to be deleted which will be the user id")
+ rDeleteUserDomain.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteUserDomain.Auth("delete", "user.{name}:domain", false, "")
+ rDeleteUserDomain.Expected("NO_CONTENT")
+ rDeleteUserDomain.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteUserDomain.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteUserDomain.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteUserDomain.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteUserDomain.Build())
+
+ rPutDomainMeta := rdl.NewResourceBuilder("Domain", "PUT", "/domain/{name}/meta")
+ rPutDomainMeta.Comment("Update the specified top level domain metadata. Note that entities in the domain are not affected. Caller must have update privileges on the domain itself.")
+ rPutDomainMeta.Input("name", "DomainName", true, "", "", false, nil, "name of the domain to be updated")
+ rPutDomainMeta.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutDomainMeta.Input("detail", "DomainMeta", false, "", "", false, nil, "DomainMeta object with updated attribute values")
+ rPutDomainMeta.Auth("update", "{name}:", false, "")
+ rPutDomainMeta.Expected("NO_CONTENT")
+ rPutDomainMeta.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutDomainMeta.Exception("CONFLICT", "ResourceError", "")
+ rPutDomainMeta.Exception("FORBIDDEN", "ResourceError", "")
+ rPutDomainMeta.Exception("NOT_FOUND", "ResourceError", "")
+ rPutDomainMeta.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutDomainMeta.Build())
+
+ rPutDomainTemplate := rdl.NewResourceBuilder("DomainTemplate", "PUT", "/domain/{name}/template")
+ rPutDomainTemplate.Comment("Update the given domain by applying the roles and policies defined in the specified solution template(s). Caller must have UPDATE privileges on the domain itself.")
+ rPutDomainTemplate.Input("name", "DomainName", true, "", "", false, nil, "name of the domain to be updated")
+ rPutDomainTemplate.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutDomainTemplate.Input("template", "DomainTemplate", false, "", "", false, nil, "DomainTemplate object with solution template name(s)")
+ rPutDomainTemplate.Auth("update", "{name}:", false, "")
+ rPutDomainTemplate.Expected("NO_CONTENT")
+ rPutDomainTemplate.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutDomainTemplate.Exception("CONFLICT", "ResourceError", "")
+ rPutDomainTemplate.Exception("FORBIDDEN", "ResourceError", "")
+ rPutDomainTemplate.Exception("NOT_FOUND", "ResourceError", "")
+ rPutDomainTemplate.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutDomainTemplate.Build())
+
+ rGetDomainTemplateList := rdl.NewResourceBuilder("DomainTemplateList", "GET", "/domain/{name}/template")
+ rGetDomainTemplateList.Comment("Get the list of solution templates applied to a domain")
+ rGetDomainTemplateList.Input("name", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetDomainTemplateList.Auth("", "", true, "")
+ rGetDomainTemplateList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetDomainTemplateList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetDomainTemplateList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetDomainTemplateList.Build())
+
+ rDeleteDomainTemplate := rdl.NewResourceBuilder("DomainTemplate", "DELETE", "/domain/{name}/template/{template}")
+ rDeleteDomainTemplate.Comment("Update the given domain by deleting the specified template from the domain template list. Cycles through the roles and policies defined in the template and deletes them. Caller must have delete privileges on the domain itself.")
+ rDeleteDomainTemplate.Input("name", "DomainName", true, "", "", false, nil, "name of the domain to be updated")
+ rDeleteDomainTemplate.Input("template", "SimpleName", true, "", "", false, nil, "name of the solution template")
+ rDeleteDomainTemplate.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteDomainTemplate.Auth("delete", "{name}:", false, "")
+ rDeleteDomainTemplate.Expected("NO_CONTENT")
+ rDeleteDomainTemplate.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteDomainTemplate.Exception("CONFLICT", "ResourceError", "")
+ rDeleteDomainTemplate.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteDomainTemplate.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteDomainTemplate.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteDomainTemplate.Build())
+
+ rGetDomainDataCheck := rdl.NewResourceBuilder("DomainDataCheck", "GET", "/domain/{domainName}/check")
+ rGetDomainDataCheck.Comment("Carry out data check operation for the specified domain.")
+ rGetDomainDataCheck.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetDomainDataCheck.Auth("", "", true, "")
+ rGetDomainDataCheck.Exception("FORBIDDEN", "ResourceError", "")
+ rGetDomainDataCheck.Exception("NOT_FOUND", "ResourceError", "")
+ rGetDomainDataCheck.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetDomainDataCheck.Build())
+
+ rPutEntity := rdl.NewResourceBuilder("Entity", "PUT", "/domain/{domainName}/entity/{entityName}")
+ rPutEntity.Comment("Put an entity into the domain.")
+ rPutEntity.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutEntity.Input("entityName", "EntityName", true, "", "", false, nil, "name of entity")
+ rPutEntity.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutEntity.Input("entity", "Entity", false, "", "", false, nil, "Entity object to be added to the domain")
+ rPutEntity.Auth("update", "{domainName}:{entityName}", false, "")
+ rPutEntity.Expected("NO_CONTENT")
+ rPutEntity.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutEntity.Exception("CONFLICT", "ResourceError", "")
+ rPutEntity.Exception("FORBIDDEN", "ResourceError", "")
+ rPutEntity.Exception("NOT_FOUND", "ResourceError", "")
+ rPutEntity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutEntity.Build())
+
+ rGetEntity := rdl.NewResourceBuilder("Entity", "GET", "/domain/{domainName}/entity/{entityName}")
+ rGetEntity.Comment("Get a entity from a domain. open for all authenticated users to read")
+ rGetEntity.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetEntity.Input("entityName", "EntityName", true, "", "", false, nil, "name of entity")
+ rGetEntity.Auth("", "", true, "")
+ rGetEntity.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetEntity.Exception("FORBIDDEN", "ResourceError", "")
+ rGetEntity.Exception("NOT_FOUND", "ResourceError", "")
+ rGetEntity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetEntity.Build())
+
+ rDeleteEntity := rdl.NewResourceBuilder("Entity", "DELETE", "/domain/{domainName}/entity/{entityName}")
+ rDeleteEntity.Comment("Delete the entity from the domain. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteEntity.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeleteEntity.Input("entityName", "EntityName", true, "", "", false, nil, "name of entity")
+ rDeleteEntity.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteEntity.Auth("delete", "{domainName}:{entityName}", false, "")
+ rDeleteEntity.Expected("NO_CONTENT")
+ rDeleteEntity.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteEntity.Exception("CONFLICT", "ResourceError", "")
+ rDeleteEntity.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteEntity.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteEntity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteEntity.Build())
+
+ rGetEntityList := rdl.NewResourceBuilder("EntityList", "GET", "/domain/{domainName}/entity")
+ rGetEntityList.Comment("Enumerate entities provisioned in this domain.")
+ rGetEntityList.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetEntityList.Auth("", "", true, "")
+ rGetEntityList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetEntityList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetEntityList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetEntityList.Build())
+
+ rGetRoleList := rdl.NewResourceBuilder("RoleList", "GET", "/domain/{domainName}/role")
+ rGetRoleList.Comment("Enumerate roles provisioned in this domain.")
+ rGetRoleList.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetRoleList.Input("limit", "Int32", false, "limit", "", true, nil, "restrict the number of results in this call")
+ rGetRoleList.Input("skip", "String", false, "skip", "", true, nil, "restrict the set to those after the specified \"next\" token returned from a previous call")
+ rGetRoleList.Auth("", "", true, "")
+ rGetRoleList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetRoleList.Exception("FORBIDDEN", "ResourceError", "")
+ rGetRoleList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetRoleList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetRoleList.Build())
+
+ rGetRoles := rdl.NewResourceBuilder("Roles", "GET", "/domain/{domainName}/roles")
+ rGetRoles.Comment("Get the list of all roles in a domain with optional flag whether or not include members")
+ rGetRoles.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetRoles.Input("members", "Bool", false, "members", "", true, false, "return list of members in the role")
+ rGetRoles.Auth("", "", true, "")
+ rGetRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rGetRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetRoles.Build())
+
+ rGetRole := rdl.NewResourceBuilder("Role", "GET", "/domain/{domainName}/role/{roleName}")
+ rGetRole.Comment("Get the specified role in the domain.")
+ rGetRole.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetRole.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role to be retrieved")
+ rGetRole.Input("auditLog", "Bool", false, "auditLog", "", true, false, "flag to indicate whether or not to return role audit log")
+ rGetRole.Input("expand", "Bool", false, "expand", "", true, false, "expand delegated trust roles and return trusted members")
+ rGetRole.Auth("", "", true, "")
+ rGetRole.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetRole.Exception("FORBIDDEN", "ResourceError", "")
+ rGetRole.Exception("NOT_FOUND", "ResourceError", "")
+ rGetRole.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetRole.Build())
+
+ rPutRole := rdl.NewResourceBuilder("Role", "PUT", "/domain/{domainName}/role/{roleName}")
+ rPutRole.Comment("Create/update the specified role.")
+ rPutRole.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutRole.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role to be added/updated")
+ rPutRole.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutRole.Input("role", "Role", false, "", "", false, nil, "Role object to be added/updated in the domain")
+ rPutRole.Auth("update", "{domainName}:role.{roleName}", false, "")
+ rPutRole.Expected("NO_CONTENT")
+ rPutRole.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutRole.Exception("CONFLICT", "ResourceError", "")
+ rPutRole.Exception("FORBIDDEN", "ResourceError", "")
+ rPutRole.Exception("NOT_FOUND", "ResourceError", "")
+ rPutRole.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutRole.Build())
+
+ rDeleteRole := rdl.NewResourceBuilder("Role", "DELETE", "/domain/{domainName}/role/{roleName}")
+ rDeleteRole.Comment("Delete the specified role. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteRole.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeleteRole.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role to be deleted")
+ rDeleteRole.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteRole.Auth("delete", "{domainName}:role.{roleName}", false, "")
+ rDeleteRole.Expected("NO_CONTENT")
+ rDeleteRole.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteRole.Exception("CONFLICT", "ResourceError", "")
+ rDeleteRole.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteRole.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteRole.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteRole.Build())
+
+ rGetMembership := rdl.NewResourceBuilder("Membership", "GET", "/domain/{domainName}/role/{roleName}/member/{memberName}")
+ rGetMembership.Comment("Get the membership status for a specified user in a role.")
+ rGetMembership.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetMembership.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role")
+ rGetMembership.Input("memberName", "ResourceName", true, "", "", false, nil, "user name to be checked for membership")
+ rGetMembership.Auth("", "", true, "")
+ rGetMembership.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetMembership.Exception("FORBIDDEN", "ResourceError", "")
+ rGetMembership.Exception("NOT_FOUND", "ResourceError", "")
+ rGetMembership.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetMembership.Build())
+
+ rPutMembership := rdl.NewResourceBuilder("Membership", "PUT", "/domain/{domainName}/role/{roleName}/member/{memberName}")
+ rPutMembership.Comment("Add the specified user to the role's member list.")
+ rPutMembership.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutMembership.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role")
+ rPutMembership.Input("memberName", "ResourceName", true, "", "", false, nil, "name of the user to be added as a member")
+ rPutMembership.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutMembership.Input("membership", "Membership", false, "", "", false, nil, "Membership object (must contain role/member names as specified in the URI)")
+ rPutMembership.Auth("update", "{domainName}:role.{roleName}", false, "")
+ rPutMembership.Expected("NO_CONTENT")
+ rPutMembership.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutMembership.Exception("CONFLICT", "ResourceError", "")
+ rPutMembership.Exception("FORBIDDEN", "ResourceError", "")
+ rPutMembership.Exception("NOT_FOUND", "ResourceError", "")
+ rPutMembership.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutMembership.Build())
+
+ rDeleteMembership := rdl.NewResourceBuilder("Membership", "DELETE", "/domain/{domainName}/role/{roleName}/member/{memberName}")
+ rDeleteMembership.Comment("Delete the specified role membership. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteMembership.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeleteMembership.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role")
+ rDeleteMembership.Input("memberName", "ResourceName", true, "", "", false, nil, "name of the user to be removed as a member")
+ rDeleteMembership.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteMembership.Auth("update", "{domainName}:role.{roleName}", false, "")
+ rDeleteMembership.Expected("NO_CONTENT")
+ rDeleteMembership.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteMembership.Exception("CONFLICT", "ResourceError", "")
+ rDeleteMembership.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteMembership.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteMembership.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteMembership.Build())
+
+ rPutDefaultAdmins := rdl.NewResourceBuilder("DefaultAdmins", "PUT", "/domain/{domainName}/admins")
+ rPutDefaultAdmins.Comment("Verify and, if necessary, fix domain roles and policies to make sure the given set of users have administrative access to the domain. This request is only restricted to \"sys.auth\" domain administrators and can be used when the domain administrators incorrectly have blocked their own access to their domains.")
+ rPutDefaultAdmins.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutDefaultAdmins.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutDefaultAdmins.Input("defaultAdmins", "DefaultAdmins", false, "", "", false, nil, "list of domain administrators")
+ rPutDefaultAdmins.Auth("update", "sys.auth:domain", false, "")
+ rPutDefaultAdmins.Expected("NO_CONTENT")
+ rPutDefaultAdmins.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutDefaultAdmins.Exception("FORBIDDEN", "ResourceError", "")
+ rPutDefaultAdmins.Exception("NOT_FOUND", "ResourceError", "")
+ rPutDefaultAdmins.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutDefaultAdmins.Build())
+
+ rGetPolicyList := rdl.NewResourceBuilder("PolicyList", "GET", "/domain/{domainName}/policy")
+ rGetPolicyList.Comment("List policies provisioned in this namespace.")
+ rGetPolicyList.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetPolicyList.Input("limit", "Int32", false, "limit", "", true, nil, "restrict the number of results in this call")
+ rGetPolicyList.Input("skip", "String", false, "skip", "", true, nil, "restrict the set to those after the specified \"next\" token returned from a previous call")
+ rGetPolicyList.Auth("", "", true, "")
+ rGetPolicyList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetPolicyList.Exception("FORBIDDEN", "ResourceError", "")
+ rGetPolicyList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetPolicyList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetPolicyList.Build())
+
+ rGetPolicies := rdl.NewResourceBuilder("Policies", "GET", "/domain/{domainName}/policies")
+ rGetPolicies.Comment("List policies provisioned in this namespace.")
+ rGetPolicies.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetPolicies.Input("assertions", "Bool", false, "assertions", "", true, false, "return list of assertions in the policy")
+ rGetPolicies.Auth("", "", true, "")
+ rGetPolicies.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetPolicies.Exception("NOT_FOUND", "ResourceError", "")
+ rGetPolicies.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetPolicies.Build())
+
+ rGetPolicy := rdl.NewResourceBuilder("Policy", "GET", "/domain/{domainName}/policy/{policyName}")
+ rGetPolicy.Comment("Read the specified policy.")
+ rGetPolicy.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetPolicy.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy to be retrieved")
+ rGetPolicy.Auth("", "", true, "")
+ rGetPolicy.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetPolicy.Exception("FORBIDDEN", "ResourceError", "")
+ rGetPolicy.Exception("NOT_FOUND", "ResourceError", "")
+ rGetPolicy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetPolicy.Build())
+
+ rPutPolicy := rdl.NewResourceBuilder("Policy", "PUT", "/domain/{domainName}/policy/{policyName}")
+ rPutPolicy.Comment("Create or update the specified policy.")
+ rPutPolicy.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutPolicy.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy to be added/updated")
+ rPutPolicy.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutPolicy.Input("policy", "Policy", false, "", "", false, nil, "Policy object to be added or updated in the domain")
+ rPutPolicy.Auth("update", "{domainName}:policy.{policyName}", false, "")
+ rPutPolicy.Expected("NO_CONTENT")
+ rPutPolicy.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutPolicy.Exception("CONFLICT", "ResourceError", "")
+ rPutPolicy.Exception("FORBIDDEN", "ResourceError", "")
+ rPutPolicy.Exception("NOT_FOUND", "ResourceError", "")
+ rPutPolicy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutPolicy.Build())
+
+ rDeletePolicy := rdl.NewResourceBuilder("Policy", "DELETE", "/domain/{domainName}/policy/{policyName}")
+ rDeletePolicy.Comment("Delete the specified policy. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeletePolicy.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeletePolicy.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy to be deleted")
+ rDeletePolicy.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeletePolicy.Auth("delete", "{domainName}:policy.{policyName}", false, "")
+ rDeletePolicy.Expected("NO_CONTENT")
+ rDeletePolicy.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeletePolicy.Exception("CONFLICT", "ResourceError", "")
+ rDeletePolicy.Exception("FORBIDDEN", "ResourceError", "")
+ rDeletePolicy.Exception("NOT_FOUND", "ResourceError", "")
+ rDeletePolicy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeletePolicy.Build())
+
+ rGetAssertion := rdl.NewResourceBuilder("Assertion", "GET", "/domain/{domainName}/policy/{policyName}/assertion/{assertionId}")
+ rGetAssertion.Comment("Get the assertion details with specified id in the given policy")
+ rGetAssertion.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetAssertion.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy")
+ rGetAssertion.Input("assertionId", "Int64", true, "", "", false, nil, "assertion id")
+ rGetAssertion.Auth("", "", true, "")
+ rGetAssertion.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetAssertion.Exception("FORBIDDEN", "ResourceError", "")
+ rGetAssertion.Exception("NOT_FOUND", "ResourceError", "")
+ rGetAssertion.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetAssertion.Build())
+
+ rPutAssertion := rdl.NewResourceBuilder("Assertion", "PUT", "/domain/{domainName}/policy/{policyName}/assertion")
+ rPutAssertion.Comment("Add the specified assertion to the given policy")
+ rPutAssertion.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutAssertion.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy")
+ rPutAssertion.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutAssertion.Input("assertion", "Assertion", false, "", "", false, nil, "Assertion object to be added to the given policy")
+ rPutAssertion.Auth("update", "{domainName}:policy.{policyName}", false, "")
+ rPutAssertion.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutAssertion.Exception("CONFLICT", "ResourceError", "")
+ rPutAssertion.Exception("FORBIDDEN", "ResourceError", "")
+ rPutAssertion.Exception("NOT_FOUND", "ResourceError", "")
+ rPutAssertion.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutAssertion.Build())
+
+ rDeleteAssertion := rdl.NewResourceBuilder("Assertion", "DELETE", "/domain/{domainName}/policy/{policyName}/assertion/{assertionId}")
+ rDeleteAssertion.Comment("Delete the specified policy assertion. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteAssertion.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeleteAssertion.Input("policyName", "EntityName", true, "", "", false, nil, "name of the policy")
+ rDeleteAssertion.Input("assertionId", "Int64", true, "", "", false, nil, "assertion id")
+ rDeleteAssertion.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteAssertion.Auth("update", "{domainName}:policy.{policyName}", false, "")
+ rDeleteAssertion.Expected("NO_CONTENT")
+ rDeleteAssertion.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteAssertion.Exception("CONFLICT", "ResourceError", "")
+ rDeleteAssertion.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteAssertion.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteAssertion.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteAssertion.Build())
+
+ rPutServiceIdentity := rdl.NewResourceBuilder("ServiceIdentity", "PUT", "/domain/{domain}/service/{service}")
+ rPutServiceIdentity.Comment("Register the specified ServiceIdentity in the specified domain")
+ rPutServiceIdentity.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutServiceIdentity.Input("service", "SimpleName", true, "", "", false, nil, "name of the service")
+ rPutServiceIdentity.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutServiceIdentity.Input("detail", "ServiceIdentity", false, "", "", false, nil, "ServiceIdentity object to be added/updated in the domain")
+ rPutServiceIdentity.Auth("update", "{domain}:service", false, "")
+ rPutServiceIdentity.Expected("NO_CONTENT")
+ rPutServiceIdentity.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutServiceIdentity.Exception("CONFLICT", "ResourceError", "")
+ rPutServiceIdentity.Exception("FORBIDDEN", "ResourceError", "")
+ rPutServiceIdentity.Exception("NOT_FOUND", "ResourceError", "")
+ rPutServiceIdentity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutServiceIdentity.Build())
+
+ rGetServiceIdentity := rdl.NewResourceBuilder("ServiceIdentity", "GET", "/domain/{domain}/service/{service}")
+ rGetServiceIdentity.Comment("Get info for the specified ServiceIdentity.")
+ rGetServiceIdentity.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetServiceIdentity.Input("service", "SimpleName", true, "", "", false, nil, "name of the service to be retrieved")
+ rGetServiceIdentity.Auth("", "", true, "")
+ rGetServiceIdentity.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServiceIdentity.Exception("FORBIDDEN", "ResourceError", "")
+ rGetServiceIdentity.Exception("NOT_FOUND", "ResourceError", "")
+ rGetServiceIdentity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServiceIdentity.Build())
+
+ rDeleteServiceIdentity := rdl.NewResourceBuilder("ServiceIdentity", "DELETE", "/domain/{domain}/service/{service}")
+ rDeleteServiceIdentity.Comment("Delete the specified ServiceIdentity. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteServiceIdentity.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeleteServiceIdentity.Input("service", "SimpleName", true, "", "", false, nil, "name of the service to be deleted")
+ rDeleteServiceIdentity.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteServiceIdentity.Auth("delete", "{domain}:service", false, "")
+ rDeleteServiceIdentity.Expected("NO_CONTENT")
+ rDeleteServiceIdentity.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteServiceIdentity.Exception("CONFLICT", "ResourceError", "")
+ rDeleteServiceIdentity.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteServiceIdentity.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteServiceIdentity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteServiceIdentity.Build())
+
+ rGetServiceIdentities := rdl.NewResourceBuilder("ServiceIdentities", "GET", "/domain/{domainName}/services")
+ rGetServiceIdentities.Comment("Retrieve list of service identities")
+ rGetServiceIdentities.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetServiceIdentities.Input("publickeys", "Bool", false, "publickeys", "", true, false, "return list of public keys in the service")
+ rGetServiceIdentities.Input("hosts", "Bool", false, "hosts", "", true, false, "return list of hosts in the service")
+ rGetServiceIdentities.Auth("", "", true, "")
+ rGetServiceIdentities.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServiceIdentities.Exception("NOT_FOUND", "ResourceError", "")
+ rGetServiceIdentities.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServiceIdentities.Build())
+
+ rGetServiceIdentityList := rdl.NewResourceBuilder("ServiceIdentityList", "GET", "/domain/{domainName}/service")
+ rGetServiceIdentityList.Comment("Enumerate services provisioned in this domain.")
+ rGetServiceIdentityList.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetServiceIdentityList.Input("limit", "Int32", false, "limit", "", true, nil, "restrict the number of results in this call")
+ rGetServiceIdentityList.Input("skip", "String", false, "skip", "", true, nil, "restrict the set to those after the specified \"next\" token returned from a previous call")
+ rGetServiceIdentityList.Auth("", "", true, "")
+ rGetServiceIdentityList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServiceIdentityList.Exception("FORBIDDEN", "ResourceError", "")
+ rGetServiceIdentityList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetServiceIdentityList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServiceIdentityList.Build())
+
+ rGetPublicKeyEntry := rdl.NewResourceBuilder("PublicKeyEntry", "GET", "/domain/{domain}/service/{service}/publickey/{id}")
+ rGetPublicKeyEntry.Comment("Retrieve the specified public key from the service.")
+ rGetPublicKeyEntry.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetPublicKeyEntry.Input("service", "SimpleName", true, "", "", false, nil, "name of the service")
+ rGetPublicKeyEntry.Input("id", "String", true, "", "", false, nil, "the identifier of the public key to be retrieved")
+ rGetPublicKeyEntry.Auth("", "", true, "")
+ rGetPublicKeyEntry.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetPublicKeyEntry.Exception("FORBIDDEN", "ResourceError", "")
+ rGetPublicKeyEntry.Exception("NOT_FOUND", "ResourceError", "")
+ rGetPublicKeyEntry.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetPublicKeyEntry.Build())
+
+ rPutPublicKeyEntry := rdl.NewResourceBuilder("PublicKeyEntry", "PUT", "/domain/{domain}/service/{service}/publickey/{id}")
+ rPutPublicKeyEntry.Comment("Add the specified public key to the service.")
+ rPutPublicKeyEntry.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rPutPublicKeyEntry.Input("service", "SimpleName", true, "", "", false, nil, "name of the service")
+ rPutPublicKeyEntry.Input("id", "String", true, "", "", false, nil, "the identifier of the public key to be added")
+ rPutPublicKeyEntry.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutPublicKeyEntry.Input("publicKeyEntry", "PublicKeyEntry", false, "", "", false, nil, "PublicKeyEntry object to be added/updated in the service")
+ rPutPublicKeyEntry.Auth("update", "{domain}:service.{service}", false, "")
+ rPutPublicKeyEntry.Expected("NO_CONTENT")
+ rPutPublicKeyEntry.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutPublicKeyEntry.Exception("CONFLICT", "ResourceError", "")
+ rPutPublicKeyEntry.Exception("FORBIDDEN", "ResourceError", "")
+ rPutPublicKeyEntry.Exception("NOT_FOUND", "ResourceError", "")
+ rPutPublicKeyEntry.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutPublicKeyEntry.Build())
+
+ rDeletePublicKeyEntry := rdl.NewResourceBuilder("PublicKeyEntry", "DELETE", "/domain/{domain}/service/{service}/publickey/{id}")
+ rDeletePublicKeyEntry.Comment("Remove the specified public key from the service. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeletePublicKeyEntry.Input("domain", "DomainName", true, "", "", false, nil, "name of the domain")
+ rDeletePublicKeyEntry.Input("service", "SimpleName", true, "", "", false, nil, "name of the service")
+ rDeletePublicKeyEntry.Input("id", "String", true, "", "", false, nil, "the identifier of the public key to be deleted")
+ rDeletePublicKeyEntry.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeletePublicKeyEntry.Auth("update", "{domain}:service.{service}", false, "")
+ rDeletePublicKeyEntry.Expected("NO_CONTENT")
+ rDeletePublicKeyEntry.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeletePublicKeyEntry.Exception("CONFLICT", "ResourceError", "")
+ rDeletePublicKeyEntry.Exception("FORBIDDEN", "ResourceError", "")
+ rDeletePublicKeyEntry.Exception("NOT_FOUND", "ResourceError", "")
+ rDeletePublicKeyEntry.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeletePublicKeyEntry.Build())
+
+ rPutTenancy := rdl.NewResourceBuilder("Tenancy", "PUT", "/domain/{domain}/tenancy/{service}")
+ rPutTenancy.Comment("Add a tenant for the specified service.")
+ rPutTenancy.Input("domain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rPutTenancy.Input("service", "ServiceName", true, "", "", false, nil, "name of the provider service")
+ rPutTenancy.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutTenancy.Input("detail", "Tenancy", false, "", "", false, nil, "tenancy object")
+ rPutTenancy.Auth("update", "{domain}:tenancy", false, "")
+ rPutTenancy.Expected("NO_CONTENT")
+ rPutTenancy.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutTenancy.Exception("CONFLICT", "ResourceError", "")
+ rPutTenancy.Exception("FORBIDDEN", "ResourceError", "")
+ rPutTenancy.Exception("NOT_FOUND", "ResourceError", "")
+ rPutTenancy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutTenancy.Build())
+
+ rGetTenancy := rdl.NewResourceBuilder("Tenancy", "GET", "/domain/{domain}/tenancy/{service}")
+ rGetTenancy.Comment("Retrieve the specified tenant.")
+ rGetTenancy.Input("domain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rGetTenancy.Input("service", "ServiceName", true, "", "", false, nil, "name of the provider service")
+ rGetTenancy.Auth("", "", true, "")
+ rGetTenancy.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetTenancy.Exception("FORBIDDEN", "ResourceError", "")
+ rGetTenancy.Exception("NOT_FOUND", "ResourceError", "")
+ rGetTenancy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetTenancy.Build())
+
+ rDeleteTenancy := rdl.NewResourceBuilder("Tenancy", "DELETE", "/domain/{domain}/tenancy/{service}")
+ rDeleteTenancy.Comment("Delete the tenant from the specified service. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteTenancy.Input("domain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rDeleteTenancy.Input("service", "ServiceName", true, "", "", false, nil, "name of the provider service")
+ rDeleteTenancy.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteTenancy.Auth("delete", "{domain}:tenancy", false, "")
+ rDeleteTenancy.Expected("NO_CONTENT")
+ rDeleteTenancy.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteTenancy.Exception("CONFLICT", "ResourceError", "")
+ rDeleteTenancy.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteTenancy.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteTenancy.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteTenancy.Build())
+
+ rPutTenancyResourceGroup := rdl.NewResourceBuilder("TenancyResourceGroup", "PUT", "/domain/{domain}/tenancy/{service}/resourceGroup/{resourceGroup}")
+ rPutTenancyResourceGroup.Comment("Add a new resource group for the tenant for the specified service.")
+ rPutTenancyResourceGroup.Input("domain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rPutTenancyResourceGroup.Input("service", "ServiceName", true, "", "", false, nil, "name of the provider service")
+ rPutTenancyResourceGroup.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rPutTenancyResourceGroup.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutTenancyResourceGroup.Input("detail", "TenancyResourceGroup", false, "", "", false, nil, "tenancy resource group object")
+ rPutTenancyResourceGroup.Auth("update", "{domain}:tenancy.{service}", false, "")
+ rPutTenancyResourceGroup.Expected("NO_CONTENT")
+ rPutTenancyResourceGroup.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutTenancyResourceGroup.Exception("CONFLICT", "ResourceError", "")
+ rPutTenancyResourceGroup.Exception("FORBIDDEN", "ResourceError", "")
+ rPutTenancyResourceGroup.Exception("NOT_FOUND", "ResourceError", "")
+ rPutTenancyResourceGroup.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutTenancyResourceGroup.Build())
+
+ rDeleteTenancyResourceGroup := rdl.NewResourceBuilder("TenancyResourceGroup", "DELETE", "/domain/{domain}/tenancy/{service}/resourceGroup/{resourceGroup}")
+ rDeleteTenancyResourceGroup.Comment("Delete the specified resource group for tenant from the specified service.")
+ rDeleteTenancyResourceGroup.Input("domain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rDeleteTenancyResourceGroup.Input("service", "ServiceName", true, "", "", false, nil, "name of the provider service")
+ rDeleteTenancyResourceGroup.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rDeleteTenancyResourceGroup.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteTenancyResourceGroup.Auth("update", "{domain}:tenancy.{service}", false, "")
+ rDeleteTenancyResourceGroup.Expected("NO_CONTENT")
+ rDeleteTenancyResourceGroup.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteTenancyResourceGroup.Exception("CONFLICT", "ResourceError", "")
+ rDeleteTenancyResourceGroup.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteTenancyResourceGroup.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteTenancyResourceGroup.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteTenancyResourceGroup.Build())
+
+ rPutTenantRoles := rdl.NewResourceBuilder("TenantRoles", "PUT", "/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ rPutTenantRoles.Comment("Create/update set of roles for a given tenant.")
+ rPutTenantRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rPutTenantRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rPutTenantRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rPutTenantRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutTenantRoles.Input("detail", "TenantRoles", false, "", "", false, nil, "list of roles to be added/updated for the tenant")
+ rPutTenantRoles.Auth("update", "{domain}:tenant.{tenantDomain}", false, "")
+ rPutTenantRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutTenantRoles.Exception("CONFLICT", "ResourceError", "")
+ rPutTenantRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rPutTenantRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rPutTenantRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutTenantRoles.Build())
+
+ rGetTenantRoles := rdl.NewResourceBuilder("TenantRoles", "GET", "/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ rGetTenantRoles.Comment("Retrieve the configured set of roles for the tenant.")
+ rGetTenantRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rGetTenantRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rGetTenantRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rGetTenantRoles.Auth("", "", true, "")
+ rGetTenantRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetTenantRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rGetTenantRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rGetTenantRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetTenantRoles.Build())
+
+ rDeleteTenantRoles := rdl.NewResourceBuilder("TenantRoles", "DELETE", "/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ rDeleteTenantRoles.Comment("Delete the configured set of roles for the tenant. Upon successful completion of this delete request, the server will return NO_CONTENT status code without any data (no object will be returned).")
+ rDeleteTenantRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rDeleteTenantRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rDeleteTenantRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rDeleteTenantRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteTenantRoles.Auth("delete", "{domain}:tenant.{tenantDomain}", false, "")
+ rDeleteTenantRoles.Expected("NO_CONTENT")
+ rDeleteTenantRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteTenantRoles.Exception("CONFLICT", "ResourceError", "")
+ rDeleteTenantRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteTenantRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteTenantRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteTenantRoles.Build())
+
+ rPutTenantResourceGroupRoles := rdl.NewResourceBuilder("TenantResourceGroupRoles", "PUT", "/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ rPutTenantResourceGroupRoles.Comment("Create/update set of roles for a given tenant and resource group")
+ rPutTenantResourceGroupRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rPutTenantResourceGroupRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rPutTenantResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rPutTenantResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rPutTenantResourceGroupRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutTenantResourceGroupRoles.Input("detail", "TenantResourceGroupRoles", false, "", "", false, nil, "list of roles to be added/updated for the tenant")
+ rPutTenantResourceGroupRoles.Auth("update", "{domain}:tenant.{tenantDomain}", false, "")
+ rPutTenantResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutTenantResourceGroupRoles.Exception("CONFLICT", "ResourceError", "")
+ rPutTenantResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rPutTenantResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rPutTenantResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutTenantResourceGroupRoles.Build())
+
+ rGetTenantResourceGroupRoles := rdl.NewResourceBuilder("TenantResourceGroupRoles", "GET", "/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ rGetTenantResourceGroupRoles.Comment("Retrieve the configured set of roles for the tenant and resource group")
+ rGetTenantResourceGroupRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rGetTenantResourceGroupRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rGetTenantResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rGetTenantResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rGetTenantResourceGroupRoles.Auth("", "", true, "")
+ rGetTenantResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetTenantResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rGetTenantResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rGetTenantResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetTenantResourceGroupRoles.Build())
+
+ rDeleteTenantResourceGroupRoles := rdl.NewResourceBuilder("TenantResourceGroupRoles", "DELETE", "/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ rDeleteTenantResourceGroupRoles.Comment("Delete the configured set of roles for the tenant and resource group")
+ rDeleteTenantResourceGroupRoles.Input("domain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rDeleteTenantResourceGroupRoles.Input("service", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rDeleteTenantResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rDeleteTenantResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rDeleteTenantResourceGroupRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteTenantResourceGroupRoles.Auth("update", "{domain}:tenant.{tenantDomain}", false, "")
+ rDeleteTenantResourceGroupRoles.Expected("NO_CONTENT")
+ rDeleteTenantResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteTenantResourceGroupRoles.Exception("CONFLICT", "ResourceError", "")
+ rDeleteTenantResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteTenantResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteTenantResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteTenantResourceGroupRoles.Build())
+
+ rPutProviderResourceGroupRoles := rdl.NewResourceBuilder("ProviderResourceGroupRoles", "PUT", "/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ rPutProviderResourceGroupRoles.Comment("Create/update set of roles for a given provider and resource group")
+ rPutProviderResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rPutProviderResourceGroupRoles.Input("provDomain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rPutProviderResourceGroupRoles.Input("provService", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rPutProviderResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rPutProviderResourceGroupRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rPutProviderResourceGroupRoles.Input("detail", "ProviderResourceGroupRoles", false, "", "", false, nil, "list of roles to be added/updated for the provider")
+ rPutProviderResourceGroupRoles.Auth("update", "{tenantDomain}:tenancy.{provDomain}.{provService}", false, "")
+ rPutProviderResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rPutProviderResourceGroupRoles.Exception("CONFLICT", "ResourceError", "")
+ rPutProviderResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rPutProviderResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rPutProviderResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPutProviderResourceGroupRoles.Build())
+
+ rGetProviderResourceGroupRoles := rdl.NewResourceBuilder("ProviderResourceGroupRoles", "GET", "/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ rGetProviderResourceGroupRoles.Comment("Retrieve the configured set of roles for the provider and resource group")
+ rGetProviderResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rGetProviderResourceGroupRoles.Input("provDomain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rGetProviderResourceGroupRoles.Input("provService", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rGetProviderResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rGetProviderResourceGroupRoles.Auth("", "", true, "")
+ rGetProviderResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetProviderResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rGetProviderResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rGetProviderResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetProviderResourceGroupRoles.Build())
+
+ rDeleteProviderResourceGroupRoles := rdl.NewResourceBuilder("ProviderResourceGroupRoles", "DELETE", "/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ rDeleteProviderResourceGroupRoles.Comment("Delete the configured set of roles for the provider and resource group")
+ rDeleteProviderResourceGroupRoles.Input("tenantDomain", "DomainName", true, "", "", false, nil, "name of the tenant domain")
+ rDeleteProviderResourceGroupRoles.Input("provDomain", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rDeleteProviderResourceGroupRoles.Input("provService", "SimpleName", true, "", "", false, nil, "name of the provider service")
+ rDeleteProviderResourceGroupRoles.Input("resourceGroup", "EntityName", true, "", "", false, nil, "tenant resource group")
+ rDeleteProviderResourceGroupRoles.Input("auditRef", "String", false, "", "Y-Audit-Ref", false, nil, "Audit param required(not empty) if domain auditEnabled is true.")
+ rDeleteProviderResourceGroupRoles.Auth("update", "{tenantDomain}:tenancy.{provDomain}.{provService}", false, "")
+ rDeleteProviderResourceGroupRoles.Expected("NO_CONTENT")
+ rDeleteProviderResourceGroupRoles.Exception("BAD_REQUEST", "ResourceError", "")
+ rDeleteProviderResourceGroupRoles.Exception("CONFLICT", "ResourceError", "")
+ rDeleteProviderResourceGroupRoles.Exception("FORBIDDEN", "ResourceError", "")
+ rDeleteProviderResourceGroupRoles.Exception("NOT_FOUND", "ResourceError", "")
+ rDeleteProviderResourceGroupRoles.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rDeleteProviderResourceGroupRoles.Build())
+
+ rGetAccess := rdl.NewResourceBuilder("Access", "GET", "/access/{action}/{resource}")
+ rGetAccess.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.")
+ rGetAccess.Input("action", "ActionName", true, "", "", false, nil, "action as specified in the policy assertion, i.e. update or read")
+ rGetAccess.Input("resource", "YRN", true, "", "", false, nil, "the resource to check access against, i.e. \"media.news:articles\"")
+ rGetAccess.Input("domain", "DomainName", false, "domain", "", true, nil, "usually null. If present, it specifies an alternate domain for cross-domain trust relation")
+ rGetAccess.Input("checkPrincipal", "EntityName", false, "principal", "", true, nil, "usually null. If present, carry out the access check for this principal")
+ rGetAccess.Auth("", "", true, "")
+ rGetAccess.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetAccess.Exception("FORBIDDEN", "ResourceError", "")
+ rGetAccess.Exception("NOT_FOUND", "ResourceError", "")
+ rGetAccess.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetAccess.Build())
+
+ rGetAccessExt := rdl.NewResourceBuilder("Access", "GET", "/access/{action}")
+ rGetAccessExt.Name("GetAccessExt")
+ rGetAccessExt.Input("action", "ActionName", true, "", "", false, nil, "action as specified in the policy assertion, i.e. update or read")
+ rGetAccessExt.Input("resource", "String", false, "resource", "", false, nil, "the resource to check access against, i.e. \"media.news:articles\"")
+ rGetAccessExt.Input("domain", "DomainName", false, "domain", "", true, nil, "usually null. If present, it specifies an alternate domain for cross-domain trust relation")
+ rGetAccessExt.Input("checkPrincipal", "EntityName", false, "principal", "", true, nil, "usually null. If present, carry out the access check for this principal")
+ rGetAccessExt.Auth("", "", true, "")
+ rGetAccessExt.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetAccessExt.Exception("FORBIDDEN", "ResourceError", "")
+ rGetAccessExt.Exception("NOT_FOUND", "ResourceError", "")
+ rGetAccessExt.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetAccessExt.Build())
+
+ rGetResourceAccessList := rdl.NewResourceBuilder("ResourceAccessList", "GET", "/resource")
+ rGetResourceAccessList.Comment("Return list of resources that the given principal has access to. Even though the principal is marked as optional, it must be specified unless the caller has authorization from sys.auth domain to check access for all user principals. (action: access, resource: resource-lookup-all)")
+ rGetResourceAccessList.Input("principal", "EntityName", false, "principal", "", true, nil, "specifies principal to query the resource list for")
+ rGetResourceAccessList.Input("action", "ActionName", false, "action", "", true, nil, "action as specified in the policy assertion")
+ rGetResourceAccessList.Auth("", "", true, "")
+ rGetResourceAccessList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetResourceAccessList.Exception("FORBIDDEN", "ResourceError", "")
+ rGetResourceAccessList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetResourceAccessList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetResourceAccessList.Build())
+
+ rGetSignedDomains := rdl.NewResourceBuilder("SignedDomains", "GET", "/sys/modified_domains")
+ rGetSignedDomains.Comment("Retrieve the list of modified domains since the specified timestamp. The server will return the list of all modified domains and the latest modification timestamp as the value of the ETag header. The client will need to use this value during its next call to request the changes since the previous request. When metaonly set to true, dont add roles, policies or services, dont sign")
+ rGetSignedDomains.Input("domain", "DomainName", false, "domain", "", true, nil, "filter the domain list only to the specified name")
+ rGetSignedDomains.Input("metaOnly", "String", false, "metaonly", "", true, nil, "valid values are \"true\" or \"false\"")
+ rGetSignedDomains.Input("matchingTag", "String", false, "", "If-None-Match", false, nil, "Retrieved from the previous request, this timestamp specifies to the server to return any domains modified since this time")
+ rGetSignedDomains.Output("tag", "String", "ETag", false, "")
+ rGetSignedDomains.Auth("", "", true, "")
+ rGetSignedDomains.Exception("FORBIDDEN", "ResourceError", "")
+ rGetSignedDomains.Exception("NOT_FOUND", "ResourceError", "")
+ rGetSignedDomains.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetSignedDomains.Build())
+
+ rGetUserToken := rdl.NewResourceBuilder("UserToken", "GET", "/user/{userName}/token")
+ rGetUserToken.Comment("Return a user/principal token for the specified authenticated user. Typical authenticated users with their native credentials are not allowed to update their domain data. They must first obtain a UserToken and then use that token for authentication and authorization of their update requests.")
+ rGetUserToken.Input("userName", "SimpleName", true, "", "", false, nil, "name of the user")
+ rGetUserToken.Input("serviceNames", "String", false, "services", "", true, nil, "comma separated list of on-behalf-of service names")
+ rGetUserToken.Auth("", "", true, "")
+ rGetUserToken.Exception("FORBIDDEN", "ResourceError", "")
+ rGetUserToken.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetUserToken.Build())
+
+ rOptionsUserToken := rdl.NewResourceBuilder("UserToken", "OPTIONS", "/user/{userName}/token")
+ rOptionsUserToken.Comment("CORS (Cross-Origin Resource Sharing) support to allow Provider Services to obtain AuthorizedService Tokens on behalf of Tenant administrators")
+ rOptionsUserToken.Input("userName", "SimpleName", true, "", "", false, nil, "name of the user")
+ rOptionsUserToken.Input("serviceNames", "String", false, "services", "", true, nil, "comma separated list of on-behalf-of service names")
+ rOptionsUserToken.Exception("BAD_REQUEST", "ResourceError", "")
+ sb.AddResource(rOptionsUserToken.Build())
+
+ rGetServicePrincipal := rdl.NewResourceBuilder("ServicePrincipal", "GET", "/principal")
+ rGetServicePrincipal.Comment("Return a ServicePrincipal object if the serviceToken is valid. This request provides a simple operation that an external application can execute to validate a service token.")
+ rGetServicePrincipal.Auth("", "", true, "")
+ rGetServicePrincipal.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServicePrincipal.Exception("FORBIDDEN", "ResourceError", "")
+ rGetServicePrincipal.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServicePrincipal.Build())
+
+ rGetServerTemplateList := rdl.NewResourceBuilder("ServerTemplateList", "GET", "/template")
+ rGetServerTemplateList.Comment("Get the list of solution templates defined in the server")
+ rGetServerTemplateList.Auth("", "", true, "")
+ rGetServerTemplateList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServerTemplateList.Build())
+
+ rGetTemplate := rdl.NewResourceBuilder("Template", "GET", "/template/{template}")
+ rGetTemplate.Comment("Get solution template details. Includes the roles and policies that will be automatically provisioned when the template is applied to a domain")
+ rGetTemplate.Input("template", "SimpleName", true, "", "", false, nil, "name of the solution template")
+ rGetTemplate.Auth("", "", true, "")
+ rGetTemplate.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetTemplate.Exception("NOT_FOUND", "ResourceError", "")
+ rGetTemplate.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetTemplate.Build())
+
+ schema = sb.Build()
+}
+
+func ZMSSchema() *rdl.Schema {
+ return schema
+}
diff --git a/clients/go/zts/Makefile b/clients/go/zts/Makefile
new file mode 100644
index 00000000000..c3a2e703703
--- /dev/null
+++ b/clients/go/zts/Makefile
@@ -0,0 +1,20 @@
+RDL_FILE=../../../core/zts/src/main/rdl/ZTS.rdl
+RDL_LIB=github.com/ardielle/ardielle-go/rdl
+
+export GOPATH=$(PWD)
+
+all: model.go client.go build
+
+build: src/$(RDL_LIB)
+
+src/$(RDL_LIB):
+ go get $(RDL_LIB)
+
+model.go: $(RDL_FILE)
+ rdl -ps generate -t -o $@ go-model $(RDL_FILE)
+
+client.go: $(RDL_FILE)
+ rdl -ps generate -t -o $@ go-client $(RDL_FILE)
+
+clean::
+ rm -rf model.go client.go zts_schema.go *~ ./src
diff --git a/clients/go/zts/README.md b/clients/go/zts/README.md
new file mode 100644
index 00000000000..d55f6c12f2d
--- /dev/null
+++ b/clients/go/zts/README.md
@@ -0,0 +1,36 @@
+# zts-go-client
+
+A Go client library to talk to Athenz ZTS.
+
+The model.go and client.go files are generated from zts_core, and checked in so users of this library need not know that.
+
+Release Notes:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Version 1.0 (2016-09-06)
+ - Initial opensource release
+
+## Usage
+
+To get it into your workspace:
+
+ go get github.com/yahoo/athenz/clients/go/zts
+
+Then in your Go code:
+
+ import (
+ zts "github.com/yahoo/athenz/clients/go/zts"
+ )
+ func main() {
+ var principal rdl.Principal /* NToken */
+ ...
+ client := zts.NewClient()
+ client.AddCredentials(principal.GetHTTPHeaderName(), principal.GetCredentials())
+ svc, err := client.GetServiceIdentity("athenz", "storage")
+ ...
+ }
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
diff --git a/clients/go/zts/client.go b/clients/go/zts/client.go
new file mode 100644
index 00000000000..c00142a6a68
--- /dev/null
+++ b/clients/go/zts/client.go
@@ -0,0 +1,755 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zts
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ rdl "github.com/ardielle/ardielle-go/rdl"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var _ = json.Marshal
+var _ = fmt.Printf
+var _ = rdl.BaseTypeAny
+var _ = ioutil.NopCloser
+
+type ZTSClient struct {
+ URL string
+ Transport http.RoundTripper
+ CredsHeader *string
+ CredsToken *string
+ Timeout time.Duration
+}
+
+// NewClient creates and returns a new HTTP client object for the ZTS service
+func NewClient(url string, transport http.RoundTripper) ZTSClient {
+ return ZTSClient{url, transport, nil, nil, 0}
+}
+
+// AddCredentials adds the credentials to the client for subsequent requests.
+func (client *ZTSClient) AddCredentials(header string, token string) {
+ client.CredsHeader = &header
+ client.CredsToken = &token
+}
+
+func (client ZTSClient) getClient() *http.Client {
+ var c *http.Client
+ if client.Transport != nil {
+ c = &http.Client{Transport: client.Transport}
+ } else {
+ c = &http.Client{}
+ }
+ if client.Timeout > 0 {
+ c.Timeout = client.Timeout
+ }
+ return c
+}
+
+func (client ZTSClient) addAuthHeader(req *http.Request) {
+ if client.CredsHeader != nil && client.CredsToken != nil {
+ if strings.HasPrefix(*client.CredsHeader, "Cookie.") {
+ req.Header.Add("Cookie", (*client.CredsHeader)[7:]+"="+*client.CredsToken)
+ } else {
+ req.Header.Add(*client.CredsHeader, *client.CredsToken)
+ }
+ }
+}
+
+func (client ZTSClient) httpGet(url string, headers map[string]string) (*http.Response, error) {
+ hclient := client.getClient()
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZTSClient) httpDelete(url string, headers map[string]string) (*http.Response, error) {
+ hclient := client.getClient()
+ req, err := http.NewRequest("DELETE", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZTSClient) httpPut(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("PUT", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZTSClient) httpPost(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("POST", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZTSClient) httpPatch(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ contentReader := bytes.NewReader(body)
+ hclient := client.getClient()
+ req, err := http.NewRequest("PATCH", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Content-type", "application/json")
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func (client ZTSClient) httpOptions(url string, headers map[string]string, body []byte) (*http.Response, error) {
+ var contentReader io.Reader = nil
+ if body != nil {
+ contentReader = bytes.NewReader(body)
+ }
+ hclient := client.getClient()
+ req, err := http.NewRequest("OPTIONS", url, contentReader)
+ if err != nil {
+ return nil, err
+ }
+ if contentReader != nil {
+ req.Header.Add("Content-type", "application/json")
+ }
+ client.addAuthHeader(req)
+ if headers != nil {
+ for k, v := range headers {
+ req.Header.Add(k, v)
+ }
+ }
+ return hclient.Do(req)
+}
+
+func encodeStringParam(name string, val string, def string) string {
+ if val == def {
+ return ""
+ }
+ return "&" + name + "=" + url.QueryEscape(val)
+}
+func encodeBoolParam(name string, b bool, def bool) string {
+ if b == def {
+ return ""
+ }
+ return fmt.Sprintf("&%s=%v", name, b)
+}
+func encodeInt8Param(name string, i int8, def int8) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt16Param(name string, i int16, def int16) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt32Param(name string, i int32, def int32) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(i))
+}
+func encodeInt64Param(name string, i int64, def int64) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatInt(i, 10)
+}
+func encodeFloat32Param(name string, i float32, def float32) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatFloat(float64(i), 'g', -1, 32)
+}
+func encodeFloat64Param(name string, i float64, def float64) string {
+ if i == def {
+ return ""
+ }
+ return "&" + name + "=" + strconv.FormatFloat(i, 'g', -1, 64)
+}
+func encodeOptionalEnumParam(name string, e interface{}) string {
+ if e == nil {
+ return "\"\""
+ }
+ return fmt.Sprintf("&%s=%v", name, e)
+}
+func encodeOptionalBoolParam(name string, b *bool) string {
+ if b == nil {
+ return ""
+ }
+ return fmt.Sprintf("&%s=%v", name, *b)
+}
+func encodeOptionalInt32Param(name string, i *int32) string {
+ if i == nil {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(*i))
+}
+func encodeOptionalInt64Param(name string, i *int64) string {
+ if i == nil {
+ return ""
+ }
+ return "&" + name + "=" + strconv.Itoa(int(*i))
+}
+func encodeParams(objs ...string) string {
+ s := strings.Join(objs, "")
+ if s == "" {
+ return s
+ }
+ return "?" + s[1:]
+}
+
+func (client ZTSClient) GetServiceIdentity(domainName DomainName, serviceName ServiceName) (*ServiceIdentity, error) {
+ var data *ServiceIdentity
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetServiceIdentityList(domainName DomainName) (*ServiceIdentityList, error) {
+ var data *ServiceIdentityList
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetPublicKeyEntry(domainName DomainName, serviceName SimpleName, keyId string) (*PublicKeyEntry, error) {
+ var data *PublicKeyEntry
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/publickey/" + keyId
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetHostServices(host string) (*HostServices, error) {
+ var data *HostServices
+ url := client.URL + "/host/" + host + "/services"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetDomainSignedPolicyData(domainName DomainName, matchingTag string) (*DomainSignedPolicyData, string, error) {
+ var data *DomainSignedPolicyData
+ headers := map[string]string{
+ "If-None-Match": matchingTag,
+ }
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/signed_policy_data"
+ resp, err := client.httpGet(url, headers)
+ if err != nil {
+ return nil, "", err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return nil, "", err
+ }
+ switch resp.StatusCode {
+ case 200, 304:
+ if 304 != resp.StatusCode {
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return nil, "", err
+ }
+ }
+ tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
+ return data, tag, nil
+ default:
+ var errobj rdl.ResourceError
+ json.Unmarshal(contentBytes, &errobj)
+ if errobj.Code == 0 {
+ errobj.Code = resp.StatusCode
+ }
+ if errobj.Message == "" {
+ errobj.Message = string(contentBytes)
+ }
+ return nil, "", errobj
+ }
+}
+
+func (client ZTSClient) GetRoleToken(domainName DomainName, role EntityName, minExpiryTime *int32, maxExpiryTime *int32, proxyForPrincipal EntityName) (*RoleToken, error) {
+ var data *RoleToken
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/token" + encodeParams(encodeStringParam("role", string(role), ""), encodeOptionalInt32Param("minExpiryTime", minExpiryTime), encodeOptionalInt32Param("maxExpiryTime", maxExpiryTime), encodeStringParam("proxyForPrincipal", string(proxyForPrincipal), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetAccess(domainName DomainName, roleName EntityName, principal EntityName) (*Access, error) {
+ var data *Access
+ url := client.URL + "/access/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(roleName) + "/principal/" + fmt.Sprint(principal)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetRoleAccess(domainName DomainName, principal EntityName) (*RoleAccess, error) {
+ var data *RoleAccess
+ url := client.URL + "/access/domain/" + fmt.Sprint(domainName) + "/principal/" + fmt.Sprint(principal)
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetTenantDomains(providerDomainName DomainName, userName EntityName, roleName EntityName, serviceName ServiceName) (*TenantDomains, error) {
+ var data *TenantDomains
+ url := client.URL + "/providerdomain/" + fmt.Sprint(providerDomainName) + "/user/" + fmt.Sprint(userName) + encodeParams(encodeStringParam("roleName", string(roleName), ""), encodeStringParam("serviceName", string(serviceName), ""))
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) PostInstanceInformation(info *InstanceInformation) (*Identity, error) {
+ var data *Identity
+ url := client.URL + "/instance"
+ contentBytes, err := json.Marshal(info)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, nil, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) PostInstanceRefreshRequest(domain CompoundName, service SimpleName, req *InstanceRefreshRequest) (*Identity, error) {
+ var data *Identity
+ url := client.URL + "/instance/" + fmt.Sprint(domain) + "/" + fmt.Sprint(service) + "/refresh"
+ contentBytes, err := json.Marshal(req)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, nil, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) PostAWSInstanceInformation(info *AWSInstanceInformation) (*Identity, error) {
+ var data *Identity
+ url := client.URL + "/aws/instance"
+ contentBytes, err := json.Marshal(info)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, nil, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) PostAWSCertificateRequest(domain CompoundName, service SimpleName, req *AWSCertificateRequest) (*Identity, error) {
+ var data *Identity
+ url := client.URL + "/aws/instance/" + fmt.Sprint(domain) + "/" + fmt.Sprint(service) + "/refresh"
+ contentBytes, err := json.Marshal(req)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, nil, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) GetAWSTemporaryCredentials(domainName DomainName, role CompoundName) (*AWSTemporaryCredentials, error) {
+ var data *AWSTemporaryCredentials
+ url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/role/" + fmt.Sprint(role) + "/creds"
+ resp, err := client.httpGet(url, nil)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err := ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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) PostDomainMetrics(domainName DomainName, req *DomainMetrics) (*DomainMetrics, error) {
+ var data *DomainMetrics
+ url := client.URL + "/metrics/" + fmt.Sprint(domainName)
+ contentBytes, err := json.Marshal(req)
+ if err != nil {
+ return data, err
+ }
+ resp, err := client.httpPost(url, nil, contentBytes)
+ if err != nil {
+ return data, err
+ }
+ contentBytes, err = ioutil.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return data, err
+ }
+ switch resp.StatusCode {
+ case 200:
+ err = json.Unmarshal(contentBytes, &data)
+ if err != nil {
+ return data, err
+ }
+ return data, nil
+ default:
+ var errobj rdl.ResourceError
+ 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
new file mode 100644
index 00000000000..efd20bca288
--- /dev/null
+++ b/clients/go/zts/model.go
@@ -0,0 +1,1966 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zts
+
+import (
+ "encoding/json"
+ "fmt"
+ rdl "github.com/ardielle/ardielle-go/rdl"
+)
+
+var _ = rdl.Version
+var _ = json.Marshal
+var _ = fmt.Printf
+
+//
+// SimpleName - Copyright 2016 Yahoo Inc. Licensed under the terms of the
+// Apache version 2.0 license. See LICENSE file for terms. Common name types
+// used by several API definitions A simple identifier, an element of compound
+// name.
+//
+type SimpleName string
+
+//
+// CompoundName - A compound name. Most names in this API are compound names.
+//
+type CompoundName string
+
+//
+// DomainName - A domain name is the general qualifier prefix, as its
+// uniqueness is managed.
+//
+type DomainName string
+
+//
+// EntityName - An entity name is a short form of a resource name, including
+// only the domain and entity.
+//
+type EntityName string
+
+//
+// ServiceName - A service name will generally be a unique subdomain.
+//
+type ServiceName string
+
+//
+// LocationName - A location name is not yet defined, but will be a dotted name
+// like everything else.
+//
+type LocationName string
+
+//
+// ActionName - An action (operation) name.
+//
+type ActionName string
+
+//
+// ResourceName - A shorthand for a YRN with no service or location. The 'tail'
+// of a YRN, just the domain:entity. Note that the EntityName part is optional,
+// that is, a domain name followed by a colon is valid resource name.
+//
+type ResourceName string
+
+//
+// YRN - A full Yahoo Resource name (YRN).
+//
+type YRN string
+
+//
+// YBase64 - The Y-specific URL-safe Base64 variant.
+//
+type YBase64 string
+
+//
+// YEncoded - YEncoded includes ybase64 chars, as well as = and %. This can
+// represent a user cookie and URL-encoded values.
+//
+type YEncoded string
+
+//
+// AuthorityName - Used as the prefix in a signed assertion. This uniquely
+// identifies a signing authority.
+//
+type AuthorityName string
+
+//
+// SignedToken - A signed assertion if identity. i.e. the user cookie value.
+// This token will only make sense to the authority that generated it, so it is
+// beneficial to have something in the value that is cheaply recognized to
+// quickly reject if it belongs to another authority. In addition to the
+// YEncoded set our token includes ; to separate components and , to separate
+// roles
+//
+type SignedToken string
+
+//
+// PublicKeyEntry - The representation of the public key in a service identity
+// object.
+//
+type PublicKeyEntry struct {
+
+ //
+ // the public key for the service
+ //
+ Key string `json:"key"`
+
+ //
+ // the key identifier (version or zone name)
+ //
+ Id string `json:"id"`
+}
+
+//
+// NewPublicKeyEntry - creates an initialized PublicKeyEntry instance, returns a pointer to it
+//
+func NewPublicKeyEntry(init ...*PublicKeyEntry) *PublicKeyEntry {
+ var o *PublicKeyEntry
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(PublicKeyEntry)
+ }
+ return o
+}
+
+type rawPublicKeyEntry PublicKeyEntry
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a PublicKeyEntry
+//
+func (pTypeDef *PublicKeyEntry) UnmarshalJSON(b []byte) error {
+ var r rawPublicKeyEntry
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := PublicKeyEntry(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *PublicKeyEntry) Validate() error {
+ if pTypeDef.Key == "" {
+ return fmt.Errorf("PublicKeyEntry.key is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Key)
+ if !val.Valid {
+ return fmt.Errorf("PublicKeyEntry.key does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Id == "" {
+ return fmt.Errorf("PublicKeyEntry.id is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Id)
+ if !val.Valid {
+ return fmt.Errorf("PublicKeyEntry.id does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ServiceIdentity - The representation of the service identity object.
+//
+type ServiceIdentity struct {
+
+ //
+ // the full name of the service, i.e. "sports.storage"
+ //
+ Name ServiceName `json:"name"`
+
+ //
+ // array of public keys for key rotation
+ //
+ PublicKeys []*PublicKeyEntry `json:"publicKeys,omitempty" rdl:"optional"`
+
+ //
+ // if present, then this service can provision tenants via this endpoint.
+ //
+ ProviderEndpoint string `json:"providerEndpoint,omitempty" rdl:"optional"`
+
+ //
+ // the timestamp when this entry was last modified
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // the path of the executable that runs the service
+ //
+ Executable string `json:"executable,omitempty" rdl:"optional"`
+
+ //
+ // list of host names that this service can run on
+ //
+ Hosts []string `json:"hosts,omitempty" rdl:"optional"`
+
+ //
+ // local (unix) user name this service can run as
+ //
+ User string `json:"user,omitempty" rdl:"optional"`
+
+ //
+ // local (unix) group name this service can run as
+ //
+ Group string `json:"group,omitempty" rdl:"optional"`
+}
+
+//
+// NewServiceIdentity - creates an initialized ServiceIdentity instance, returns a pointer to it
+//
+func NewServiceIdentity(init ...*ServiceIdentity) *ServiceIdentity {
+ var o *ServiceIdentity
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServiceIdentity)
+ }
+ return o
+}
+
+type rawServiceIdentity ServiceIdentity
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServiceIdentity
+//
+func (pTypeDef *ServiceIdentity) UnmarshalJSON(b []byte) error {
+ var r rawServiceIdentity
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServiceIdentity(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServiceIdentity) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("ServiceIdentity.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "ServiceName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("ServiceIdentity.name does not contain a valid ServiceName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// ServiceIdentityList - The representation for an enumeration of services in
+// the namespace.
+//
+type ServiceIdentityList struct {
+
+ //
+ // list of service names
+ //
+ Names []EntityName `json:"names"`
+}
+
+//
+// NewServiceIdentityList - creates an initialized ServiceIdentityList instance, returns a pointer to it
+//
+func NewServiceIdentityList(init ...*ServiceIdentityList) *ServiceIdentityList {
+ var o *ServiceIdentityList
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(ServiceIdentityList)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *ServiceIdentityList) Init() *ServiceIdentityList {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawServiceIdentityList ServiceIdentityList
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a ServiceIdentityList
+//
+func (pTypeDef *ServiceIdentityList) UnmarshalJSON(b []byte) error {
+ var r rawServiceIdentityList
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := ServiceIdentityList(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *ServiceIdentityList) Validate() error {
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("ServiceIdentityList: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// HostServices - The representation for an enumeration of services authorized
+// to run on a specific host.
+//
+type HostServices struct {
+
+ //
+ // name of the host
+ //
+ Host string `json:"host"`
+
+ //
+ // list of service names authorized to run on this host
+ //
+ Names []EntityName `json:"names"`
+}
+
+//
+// NewHostServices - creates an initialized HostServices instance, returns a pointer to it
+//
+func NewHostServices(init ...*HostServices) *HostServices {
+ var o *HostServices
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(HostServices)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *HostServices) Init() *HostServices {
+ if pTypeDef.Names == nil {
+ pTypeDef.Names = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawHostServices HostServices
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a HostServices
+//
+func (pTypeDef *HostServices) UnmarshalJSON(b []byte) error {
+ var r rawHostServices
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := HostServices(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *HostServices) Validate() error {
+ if pTypeDef.Host == "" {
+ return fmt.Errorf("HostServices.host is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Host)
+ if !val.Valid {
+ return fmt.Errorf("HostServices.host does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Names == nil {
+ return fmt.Errorf("HostServices: Missing required field: names")
+ }
+ return nil
+}
+
+//
+// AssertionEffect - Every assertion can have the effect of ALLOW or DENY.
+//
+type AssertionEffect int
+
+//
+// AssertionEffect constants
+//
+const (
+ _ AssertionEffect = iota
+ ALLOW
+ DENY
+)
+
+var namesAssertionEffect = []string{
+ ALLOW: "ALLOW",
+ DENY: "DENY",
+}
+
+//
+// NewAssertionEffect - return a string representation of the enum
+//
+func NewAssertionEffect(init ...interface{}) AssertionEffect {
+ if len(init) == 1 {
+ switch v := init[0].(type) {
+ case AssertionEffect:
+ return v
+ case int:
+ return AssertionEffect(v)
+ case int32:
+ return AssertionEffect(v)
+ case string:
+ for i, s := range namesAssertionEffect {
+ if s == v {
+ return AssertionEffect(i)
+ }
+ }
+ default:
+ panic("Bad init value for AssertionEffect enum")
+ }
+ }
+ return AssertionEffect(0) //default to the first enum value
+}
+
+//
+// String - return a string representation of the enum
+//
+func (e AssertionEffect) String() string {
+ return namesAssertionEffect[e]
+}
+
+//
+// SymbolSet - return an array of all valid string representations (symbols) of the enum
+//
+func (e AssertionEffect) SymbolSet() []string {
+ return namesAssertionEffect
+}
+
+//
+// MarshalJSON is defined for proper JSON encoding of a AssertionEffect
+//
+func (e AssertionEffect) MarshalJSON() ([]byte, error) {
+ return json.Marshal(e.String())
+}
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a AssertionEffect
+//
+func (e *AssertionEffect) UnmarshalJSON(b []byte) error {
+ var j string
+ err := json.Unmarshal(b, &j)
+ if err == nil {
+ s := string(j)
+ for v, s2 := range namesAssertionEffect {
+ if s == s2 {
+ *e = AssertionEffect(v)
+ return nil
+ }
+ }
+ err = fmt.Errorf("Bad enum symbol for type AssertionEffect: %s", s)
+ }
+ return err
+}
+
+//
+// Assertion - A representation for the encapsulation of an action to be
+// performed on a resource by a principal.
+//
+type Assertion struct {
+
+ //
+ // the subject of the assertion, a role
+ //
+ Role string `json:"role"`
+
+ //
+ // the object of the assertion. Must be in the local namespace. Can contain
+ // wildcards
+ //
+ Resource string `json:"resource"`
+
+ //
+ // the predicate of the assertion. Can contain wildcards
+ //
+ Action string `json:"action"`
+
+ //
+ // the effect of the assertion in the policy language
+ //
+ Effect *AssertionEffect `json:"effect,omitempty" rdl:"optional"`
+
+ //
+ // assertion id - auto generated by server
+ //
+ Id *int64 `json:"id,omitempty" rdl:"optional"`
+}
+
+//
+// NewAssertion - creates an initialized Assertion instance, returns a pointer to it
+//
+func NewAssertion(init ...*Assertion) *Assertion {
+ var o *Assertion
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Assertion)
+ }
+ return o
+}
+
+type rawAssertion Assertion
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Assertion
+//
+func (pTypeDef *Assertion) UnmarshalJSON(b []byte) error {
+ var r rawAssertion
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Assertion(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Assertion) Validate() error {
+ if pTypeDef.Role == "" {
+ return fmt.Errorf("Assertion.role is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Role)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.role does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Resource == "" {
+ return fmt.Errorf("Assertion.resource is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Resource)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.resource does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Action == "" {
+ return fmt.Errorf("Assertion.action is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Action)
+ if !val.Valid {
+ return fmt.Errorf("Assertion.action does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Policy - The representation for a Policy with set of assertions.
+//
+type Policy struct {
+
+ //
+ // name of the policy
+ //
+ Name ResourceName `json:"name"`
+
+ //
+ // last modification timestamp of this policy
+ //
+ Modified *rdl.Timestamp `json:"modified,omitempty" rdl:"optional"`
+
+ //
+ // list of defined assertions for this policy
+ //
+ Assertions []*Assertion `json:"assertions"`
+}
+
+//
+// NewPolicy - creates an initialized Policy instance, returns a pointer to it
+//
+func NewPolicy(init ...*Policy) *Policy {
+ var o *Policy
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Policy)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *Policy) Init() *Policy {
+ if pTypeDef.Assertions == nil {
+ pTypeDef.Assertions = make([]*Assertion, 0)
+ }
+ return pTypeDef
+}
+
+type rawPolicy Policy
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Policy
+//
+func (pTypeDef *Policy) UnmarshalJSON(b []byte) error {
+ var r rawPolicy
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Policy(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Policy) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Policy.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "ResourceName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Policy.name does not contain a valid ResourceName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Assertions == nil {
+ return fmt.Errorf("Policy: Missing required field: assertions")
+ }
+ return nil
+}
+
+//
+// PolicyData -
+//
+type PolicyData struct {
+
+ //
+ // name of the domain
+ //
+ Domain DomainName `json:"domain"`
+
+ //
+ // list of policies defined in this server
+ //
+ Policies []*Policy `json:"policies"`
+}
+
+//
+// NewPolicyData - creates an initialized PolicyData instance, returns a pointer to it
+//
+func NewPolicyData(init ...*PolicyData) *PolicyData {
+ var o *PolicyData
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(PolicyData)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *PolicyData) Init() *PolicyData {
+ if pTypeDef.Policies == nil {
+ pTypeDef.Policies = make([]*Policy, 0)
+ }
+ return pTypeDef
+}
+
+type rawPolicyData PolicyData
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a PolicyData
+//
+func (pTypeDef *PolicyData) UnmarshalJSON(b []byte) error {
+ var r rawPolicyData
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := PolicyData(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *PolicyData) Validate() error {
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("PolicyData.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "DomainName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("PolicyData.domain does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Policies == nil {
+ return fmt.Errorf("PolicyData: Missing required field: policies")
+ }
+ return nil
+}
+
+//
+// SignedPolicyData - A representation of policies object defined in a given
+// server.
+//
+type SignedPolicyData struct {
+
+ //
+ // list of policies defined in a domain
+ //
+ PolicyData *PolicyData `json:"policyData"`
+
+ //
+ // zms signature generated based on the domain policies object
+ //
+ ZmsSignature string `json:"zmsSignature"`
+
+ //
+ // the identifier of the zms key used to generate the signature
+ //
+ ZmsKeyId string `json:"zmsKeyId"`
+
+ //
+ // when the domain itself was last modified
+ //
+ Modified rdl.Timestamp `json:"modified"`
+
+ //
+ // timestamp specifying the expiration time for using this set of policies
+ //
+ Expires rdl.Timestamp `json:"expires"`
+}
+
+//
+// NewSignedPolicyData - creates an initialized SignedPolicyData instance, returns a pointer to it
+//
+func NewSignedPolicyData(init ...*SignedPolicyData) *SignedPolicyData {
+ var o *SignedPolicyData
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(SignedPolicyData)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *SignedPolicyData) Init() *SignedPolicyData {
+ if pTypeDef.PolicyData == nil {
+ pTypeDef.PolicyData = NewPolicyData()
+ }
+ return pTypeDef
+}
+
+type rawSignedPolicyData SignedPolicyData
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a SignedPolicyData
+//
+func (pTypeDef *SignedPolicyData) UnmarshalJSON(b []byte) error {
+ var r rawSignedPolicyData
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := SignedPolicyData(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *SignedPolicyData) Validate() error {
+ if pTypeDef.PolicyData == nil {
+ return fmt.Errorf("SignedPolicyData: Missing required field: policyData")
+ }
+ if pTypeDef.ZmsSignature == "" {
+ return fmt.Errorf("SignedPolicyData.zmsSignature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.ZmsSignature)
+ if !val.Valid {
+ return fmt.Errorf("SignedPolicyData.zmsSignature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.ZmsKeyId == "" {
+ return fmt.Errorf("SignedPolicyData.zmsKeyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.ZmsKeyId)
+ if !val.Valid {
+ return fmt.Errorf("SignedPolicyData.zmsKeyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Modified.IsZero() {
+ return fmt.Errorf("SignedPolicyData: Missing required field: modified")
+ }
+ if pTypeDef.Expires.IsZero() {
+ return fmt.Errorf("SignedPolicyData: Missing required field: expires")
+ }
+ return nil
+}
+
+//
+// DomainSignedPolicyData - A signed bulk transfer of policies. The data is
+// signed with server's private key.
+//
+type DomainSignedPolicyData struct {
+
+ //
+ // policy data signed by ZMS
+ //
+ SignedPolicyData *SignedPolicyData `json:"signedPolicyData"`
+
+ //
+ // signature generated based on the domain policies object
+ //
+ Signature string `json:"signature"`
+
+ //
+ // the identifier of the key used to generate the signature
+ //
+ KeyId string `json:"keyId"`
+}
+
+//
+// NewDomainSignedPolicyData - creates an initialized DomainSignedPolicyData instance, returns a pointer to it
+//
+func NewDomainSignedPolicyData(init ...*DomainSignedPolicyData) *DomainSignedPolicyData {
+ var o *DomainSignedPolicyData
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainSignedPolicyData)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainSignedPolicyData) Init() *DomainSignedPolicyData {
+ if pTypeDef.SignedPolicyData == nil {
+ pTypeDef.SignedPolicyData = NewSignedPolicyData()
+ }
+ return pTypeDef
+}
+
+type rawDomainSignedPolicyData DomainSignedPolicyData
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainSignedPolicyData
+//
+func (pTypeDef *DomainSignedPolicyData) UnmarshalJSON(b []byte) error {
+ var r rawDomainSignedPolicyData
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainSignedPolicyData(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainSignedPolicyData) Validate() error {
+ if pTypeDef.SignedPolicyData == nil {
+ return fmt.Errorf("DomainSignedPolicyData: Missing required field: signedPolicyData")
+ }
+ if pTypeDef.Signature == "" {
+ return fmt.Errorf("DomainSignedPolicyData.signature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Signature)
+ if !val.Valid {
+ return fmt.Errorf("DomainSignedPolicyData.signature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.KeyId == "" {
+ return fmt.Errorf("DomainSignedPolicyData.keyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.KeyId)
+ if !val.Valid {
+ return fmt.Errorf("DomainSignedPolicyData.keyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// RoleToken - A representation of a signed RoleToken
+//
+type RoleToken struct {
+ Token string `json:"token"`
+ ExpiryTime int64 `json:"expiryTime"`
+}
+
+//
+// NewRoleToken - creates an initialized RoleToken instance, returns a pointer to it
+//
+func NewRoleToken(init ...*RoleToken) *RoleToken {
+ var o *RoleToken
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(RoleToken)
+ }
+ return o
+}
+
+type rawRoleToken RoleToken
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a RoleToken
+//
+func (pTypeDef *RoleToken) UnmarshalJSON(b []byte) error {
+ var r rawRoleToken
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := RoleToken(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *RoleToken) Validate() error {
+ if pTypeDef.Token == "" {
+ return fmt.Errorf("RoleToken.token is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Token)
+ if !val.Valid {
+ return fmt.Errorf("RoleToken.token does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// Access - Access can be checked and returned as this resource.
+//
+type Access struct {
+
+ //
+ // true (allowed) or false (denied)
+ //
+ Granted bool `json:"granted"`
+}
+
+//
+// NewAccess - creates an initialized Access instance, returns a pointer to it
+//
+func NewAccess(init ...*Access) *Access {
+ var o *Access
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Access)
+ }
+ return o
+}
+
+type rawAccess Access
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Access
+//
+func (pTypeDef *Access) UnmarshalJSON(b []byte) error {
+ var r rawAccess
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Access(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Access) Validate() error {
+ return nil
+}
+
+//
+// RoleAccess -
+//
+type RoleAccess struct {
+ Roles []EntityName `json:"roles"`
+}
+
+//
+// NewRoleAccess - creates an initialized RoleAccess instance, returns a pointer to it
+//
+func NewRoleAccess(init ...*RoleAccess) *RoleAccess {
+ var o *RoleAccess
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(RoleAccess)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *RoleAccess) Init() *RoleAccess {
+ if pTypeDef.Roles == nil {
+ pTypeDef.Roles = make([]EntityName, 0)
+ }
+ return pTypeDef
+}
+
+type rawRoleAccess RoleAccess
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a RoleAccess
+//
+func (pTypeDef *RoleAccess) UnmarshalJSON(b []byte) error {
+ var r rawRoleAccess
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := RoleAccess(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *RoleAccess) Validate() error {
+ if pTypeDef.Roles == nil {
+ return fmt.Errorf("RoleAccess: Missing required field: roles")
+ }
+ return nil
+}
+
+//
+// TenantDomains -
+//
+type TenantDomains struct {
+ TenantDomainNames []DomainName `json:"tenantDomainNames"`
+}
+
+//
+// NewTenantDomains - creates an initialized TenantDomains instance, returns a pointer to it
+//
+func NewTenantDomains(init ...*TenantDomains) *TenantDomains {
+ var o *TenantDomains
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(TenantDomains)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *TenantDomains) Init() *TenantDomains {
+ if pTypeDef.TenantDomainNames == nil {
+ pTypeDef.TenantDomainNames = make([]DomainName, 0)
+ }
+ return pTypeDef
+}
+
+type rawTenantDomains TenantDomains
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a TenantDomains
+//
+func (pTypeDef *TenantDomains) UnmarshalJSON(b []byte) error {
+ var r rawTenantDomains
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := TenantDomains(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *TenantDomains) Validate() error {
+ if pTypeDef.TenantDomainNames == nil {
+ return fmt.Errorf("TenantDomains: Missing required field: tenantDomainNames")
+ }
+ return nil
+}
+
+//
+// Identity - Identity - a signed assertion of service or human identity, the
+// response could be either a client certificate or just a regular NToken
+// (depending if the request contained a csr or not).
+//
+type Identity struct {
+
+ //
+ // name of the identity, fully qualified, i.e. my.domain.service1, or
+ // aws.1232321321312.myusername
+ //
+ Name CompoundName `json:"name"`
+
+ //
+ // a certificate usable for both client and server in TLS connections
+ //
+ Certificate string `json:"certificate,omitempty" rdl:"optional"`
+
+ //
+ // the CA certificate chain to use with all IMS-generated certs
+ //
+ CaCertBundle string `json:"caCertBundle,omitempty" rdl:"optional"`
+
+ //
+ // the SSH server cert, signed by the CA
+ //
+ SshServerCert string `json:"sshServerCert,omitempty" rdl:"optional"`
+
+ //
+ // service token instead of TLS certificate
+ //
+ ServiceToken SignedToken `json:"serviceToken,omitempty" rdl:"optional"`
+
+ //
+ // other config-like attributes determined at boot time
+ //
+ Attributes map[string]string `json:"attributes,omitempty" rdl:"optional"`
+}
+
+//
+// NewIdentity - creates an initialized Identity instance, returns a pointer to it
+//
+func NewIdentity(init ...*Identity) *Identity {
+ var o *Identity
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(Identity)
+ }
+ return o
+}
+
+type rawIdentity Identity
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a Identity
+//
+func (pTypeDef *Identity) UnmarshalJSON(b []byte) error {
+ var r rawIdentity
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := Identity(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *Identity) Validate() error {
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("Identity.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "CompoundName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("Identity.name does not contain a valid CompoundName (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// InstanceInformation - Instance object that includes requested service
+// details plus host document that is signed by provider as part of the host
+// bootstrap process
+//
+type InstanceInformation struct {
+
+ //
+ // signed document containing attributes like IP address, instance-id,
+ // account#, etc.
+ //
+ Document string `json:"document"`
+
+ //
+ // the signature for the document
+ //
+ Signature string `json:"signature"`
+
+ //
+ // the keyid used to sign the document
+ //
+ KeyId string `json:"keyId"`
+
+ //
+ // the domain of the instance
+ //
+ Domain CompoundName `json:"domain"`
+
+ //
+ // the service this instance is supposed to run
+ //
+ Service SimpleName `json:"service"`
+
+ //
+ // return a certificate in the response
+ //
+ Csr string `json:"csr"`
+}
+
+//
+// NewInstanceInformation - creates an initialized InstanceInformation instance, returns a pointer to it
+//
+func NewInstanceInformation(init ...*InstanceInformation) *InstanceInformation {
+ var o *InstanceInformation
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(InstanceInformation)
+ }
+ return o
+}
+
+type rawInstanceInformation InstanceInformation
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a InstanceInformation
+//
+func (pTypeDef *InstanceInformation) UnmarshalJSON(b []byte) error {
+ var r rawInstanceInformation
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := InstanceInformation(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *InstanceInformation) Validate() error {
+ if pTypeDef.Document == "" {
+ return fmt.Errorf("InstanceInformation.document is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Document)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.document does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Signature == "" {
+ return fmt.Errorf("InstanceInformation.signature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Signature)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.signature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.KeyId == "" {
+ return fmt.Errorf("InstanceInformation.keyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.KeyId)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.keyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("InstanceInformation.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "CompoundName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.domain does not contain a valid CompoundName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("InstanceInformation.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "SimpleName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.service does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Csr == "" {
+ return fmt.Errorf("InstanceInformation.csr is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Csr)
+ if !val.Valid {
+ return fmt.Errorf("InstanceInformation.csr does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// InstanceRefreshRequest - InstanceRefreshRequest - a certificate refresh
+// request
+//
+type InstanceRefreshRequest struct {
+
+ //
+ // Cert CSR if requesting TLS certificate
+ //
+ Csr string `json:"csr"`
+
+ //
+ // in seconds how long token should be valid for
+ //
+ ExpiryTime *int32 `json:"expiryTime,omitempty" rdl:"optional"`
+}
+
+//
+// NewInstanceRefreshRequest - creates an initialized InstanceRefreshRequest instance, returns a pointer to it
+//
+func NewInstanceRefreshRequest(init ...*InstanceRefreshRequest) *InstanceRefreshRequest {
+ var o *InstanceRefreshRequest
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(InstanceRefreshRequest)
+ }
+ return o
+}
+
+type rawInstanceRefreshRequest InstanceRefreshRequest
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a InstanceRefreshRequest
+//
+func (pTypeDef *InstanceRefreshRequest) UnmarshalJSON(b []byte) error {
+ var r rawInstanceRefreshRequest
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := InstanceRefreshRequest(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *InstanceRefreshRequest) Validate() error {
+ if pTypeDef.Csr == "" {
+ return fmt.Errorf("InstanceRefreshRequest.csr is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Csr)
+ if !val.Valid {
+ return fmt.Errorf("InstanceRefreshRequest.csr does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// AWSInstanceInformation - AWSInstanceInformation - the information a booting
+// EC2 instance must provide to ZTS to authenticate.
+//
+type AWSInstanceInformation struct {
+
+ //
+ // signed document containing attributes like IP address, instance-id,
+ // account#, etc.
+ //
+ Document string `json:"document"`
+
+ //
+ // the signature for the document
+ //
+ Signature string `json:"signature"`
+
+ //
+ // the domain of the instance
+ //
+ Domain CompoundName `json:"domain"`
+
+ //
+ // the service this instance is supposed to run
+ //
+ Service SimpleName `json:"service"`
+
+ //
+ // return a certificate in the response
+ //
+ Csr string `json:"csr"`
+
+ //
+ // the full service identity name (same as the EC2 instance profile name)
+ //
+ Name CompoundName `json:"name"`
+
+ //
+ // the account id (as a string) for the instance. parsed from the instance
+ // profile ARN
+ //
+ Account SimpleName `json:"account"`
+
+ //
+ // the name of the cloud (namespace) within the account, parsed from the name
+ //
+ Cloud SimpleName `json:"cloud,omitempty" rdl:"optional"`
+
+ //
+ // the name of the subnet this instance is expected to be running in, parsed
+ // from the name
+ //
+ Subnet SimpleName `json:"subnet"`
+
+ //
+ // the AWS Access Key Id for the role
+ //
+ Access string `json:"access"`
+
+ //
+ // the AWS Secret Access Key for the role
+ //
+ Secret string `json:"secret"`
+
+ //
+ // the AWS STS Token for the role
+ //
+ Token string `json:"token"`
+
+ //
+ // the expiration time of the access keys
+ //
+ Expires rdl.Timestamp `json:"expires"`
+
+ //
+ // the modified time of the access keys
+ //
+ Modified rdl.Timestamp `json:"modified"`
+
+ //
+ // the 'flavor' of the access keys, i.e. "AWS-HMAC"
+ //
+ Flavor string `json:"flavor"`
+}
+
+//
+// NewAWSInstanceInformation - creates an initialized AWSInstanceInformation instance, returns a pointer to it
+//
+func NewAWSInstanceInformation(init ...*AWSInstanceInformation) *AWSInstanceInformation {
+ var o *AWSInstanceInformation
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(AWSInstanceInformation)
+ }
+ return o
+}
+
+type rawAWSInstanceInformation AWSInstanceInformation
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a AWSInstanceInformation
+//
+func (pTypeDef *AWSInstanceInformation) UnmarshalJSON(b []byte) error {
+ var r rawAWSInstanceInformation
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := AWSInstanceInformation(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *AWSInstanceInformation) Validate() error {
+ if pTypeDef.Document == "" {
+ return fmt.Errorf("AWSInstanceInformation.document is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Document)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.document does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Signature == "" {
+ return fmt.Errorf("AWSInstanceInformation.signature is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Signature)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.signature does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Domain == "" {
+ return fmt.Errorf("AWSInstanceInformation.domain is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "CompoundName", pTypeDef.Domain)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.domain does not contain a valid CompoundName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Service == "" {
+ return fmt.Errorf("AWSInstanceInformation.service is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "SimpleName", pTypeDef.Service)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.service does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Csr == "" {
+ return fmt.Errorf("AWSInstanceInformation.csr is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Csr)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.csr does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Name == "" {
+ return fmt.Errorf("AWSInstanceInformation.name is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "CompoundName", pTypeDef.Name)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.name does not contain a valid CompoundName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Account == "" {
+ return fmt.Errorf("AWSInstanceInformation.account is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "SimpleName", pTypeDef.Account)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.account does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Subnet == "" {
+ return fmt.Errorf("AWSInstanceInformation.subnet is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "SimpleName", pTypeDef.Subnet)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.subnet does not contain a valid SimpleName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Access == "" {
+ return fmt.Errorf("AWSInstanceInformation.access is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Access)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.access does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Secret == "" {
+ return fmt.Errorf("AWSInstanceInformation.secret is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Secret)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.secret does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Token == "" {
+ return fmt.Errorf("AWSInstanceInformation.token is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Token)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.token does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Expires.IsZero() {
+ return fmt.Errorf("AWSInstanceInformation: Missing required field: expires")
+ }
+ if pTypeDef.Modified.IsZero() {
+ return fmt.Errorf("AWSInstanceInformation: Missing required field: modified")
+ }
+ if pTypeDef.Flavor == "" {
+ return fmt.Errorf("AWSInstanceInformation.flavor is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Flavor)
+ if !val.Valid {
+ return fmt.Errorf("AWSInstanceInformation.flavor does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// AWSCertificateRequest - AWSCertificateRequest - a certificate signing
+// request
+//
+type AWSCertificateRequest struct {
+ Csr string `json:"csr"`
+}
+
+//
+// NewAWSCertificateRequest - creates an initialized AWSCertificateRequest instance, returns a pointer to it
+//
+func NewAWSCertificateRequest(init ...*AWSCertificateRequest) *AWSCertificateRequest {
+ var o *AWSCertificateRequest
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(AWSCertificateRequest)
+ }
+ return o
+}
+
+type rawAWSCertificateRequest AWSCertificateRequest
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a AWSCertificateRequest
+//
+func (pTypeDef *AWSCertificateRequest) UnmarshalJSON(b []byte) error {
+ var r rawAWSCertificateRequest
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := AWSCertificateRequest(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *AWSCertificateRequest) Validate() error {
+ if pTypeDef.Csr == "" {
+ return fmt.Errorf("AWSCertificateRequest.csr is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.Csr)
+ if !val.Valid {
+ return fmt.Errorf("AWSCertificateRequest.csr does not contain a valid String (%v)", val.Error)
+ }
+ }
+ return nil
+}
+
+//
+// AWSTemporaryCredentials -
+//
+type AWSTemporaryCredentials struct {
+ AccessKeyId string `json:"accessKeyId"`
+ SecretAccessKey string `json:"secretAccessKey"`
+ SessionToken string `json:"sessionToken"`
+ Expiration rdl.Timestamp `json:"expiration"`
+}
+
+//
+// NewAWSTemporaryCredentials - creates an initialized AWSTemporaryCredentials instance, returns a pointer to it
+//
+func NewAWSTemporaryCredentials(init ...*AWSTemporaryCredentials) *AWSTemporaryCredentials {
+ var o *AWSTemporaryCredentials
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(AWSTemporaryCredentials)
+ }
+ return o
+}
+
+type rawAWSTemporaryCredentials AWSTemporaryCredentials
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a AWSTemporaryCredentials
+//
+func (pTypeDef *AWSTemporaryCredentials) UnmarshalJSON(b []byte) error {
+ var r rawAWSTemporaryCredentials
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := AWSTemporaryCredentials(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *AWSTemporaryCredentials) Validate() error {
+ if pTypeDef.AccessKeyId == "" {
+ return fmt.Errorf("AWSTemporaryCredentials.accessKeyId is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.AccessKeyId)
+ if !val.Valid {
+ return fmt.Errorf("AWSTemporaryCredentials.accessKeyId does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.SecretAccessKey == "" {
+ return fmt.Errorf("AWSTemporaryCredentials.secretAccessKey is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.SecretAccessKey)
+ if !val.Valid {
+ return fmt.Errorf("AWSTemporaryCredentials.secretAccessKey does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.SessionToken == "" {
+ return fmt.Errorf("AWSTemporaryCredentials.sessionToken is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "String", pTypeDef.SessionToken)
+ if !val.Valid {
+ return fmt.Errorf("AWSTemporaryCredentials.sessionToken does not contain a valid String (%v)", val.Error)
+ }
+ }
+ if pTypeDef.Expiration.IsZero() {
+ return fmt.Errorf("AWSTemporaryCredentials: Missing required field: expiration")
+ }
+ return nil
+}
+
+//
+// DomainMetricType - zpe metric attributes
+//
+type DomainMetricType int
+
+//
+// DomainMetricType constants
+//
+const (
+ _ DomainMetricType = iota
+ ACCESS_ALLOWED
+ ACCESS_ALLOWED_DENY
+ ACCESS_ALLOWED_DENY_NO_MATCH
+ ACCESS_ALLOWED_ALLOW
+ ACCESS_ALLOWED_ERROR
+ ACCESS_ALLOWED_TOKEN_INVALID
+ ACCESS_Allowed_TOKEN_EXPIRED
+ ACCESS_ALLOWED_DOMAIN_NOT_FOUND
+ ACCESS_ALLOWED_DOMAIN_MISMATCH
+ ACCESS_ALLOWED_DOMAIN_EXPIRED
+ ACCESS_ALLOWED_DOMAIN_EMPTY
+ ACCESS_ALLOWED_TOKEN_CACHE_FAILURE
+ ACCESS_ALLOWED_TOKEN_CACHE_NOT_FOUND
+ ACCESS_ALLOWED_TOKEN_CACHE_SUCCESS
+ ACCESS_ALLOWED_TOKEN_VALIDATE
+ LOAD_FILE_FAIL
+ LOAD_FILE_GOOD
+ LOAD_DOMAIN_GOOD
+)
+
+var namesDomainMetricType = []string{
+ ACCESS_ALLOWED: "ACCESS_ALLOWED",
+ ACCESS_ALLOWED_DENY: "ACCESS_ALLOWED_DENY",
+ ACCESS_ALLOWED_DENY_NO_MATCH: "ACCESS_ALLOWED_DENY_NO_MATCH",
+ ACCESS_ALLOWED_ALLOW: "ACCESS_ALLOWED_ALLOW",
+ ACCESS_ALLOWED_ERROR: "ACCESS_ALLOWED_ERROR",
+ ACCESS_ALLOWED_TOKEN_INVALID: "ACCESS_ALLOWED_TOKEN_INVALID",
+ ACCESS_Allowed_TOKEN_EXPIRED: "ACCESS_Allowed_TOKEN_EXPIRED",
+ ACCESS_ALLOWED_DOMAIN_NOT_FOUND: "ACCESS_ALLOWED_DOMAIN_NOT_FOUND",
+ ACCESS_ALLOWED_DOMAIN_MISMATCH: "ACCESS_ALLOWED_DOMAIN_MISMATCH",
+ ACCESS_ALLOWED_DOMAIN_EXPIRED: "ACCESS_ALLOWED_DOMAIN_EXPIRED",
+ ACCESS_ALLOWED_DOMAIN_EMPTY: "ACCESS_ALLOWED_DOMAIN_EMPTY",
+ ACCESS_ALLOWED_TOKEN_CACHE_FAILURE: "ACCESS_ALLOWED_TOKEN_CACHE_FAILURE",
+ ACCESS_ALLOWED_TOKEN_CACHE_NOT_FOUND: "ACCESS_ALLOWED_TOKEN_CACHE_NOT_FOUND",
+ ACCESS_ALLOWED_TOKEN_CACHE_SUCCESS: "ACCESS_ALLOWED_TOKEN_CACHE_SUCCESS",
+ ACCESS_ALLOWED_TOKEN_VALIDATE: "ACCESS_ALLOWED_TOKEN_VALIDATE",
+ LOAD_FILE_FAIL: "LOAD_FILE_FAIL",
+ LOAD_FILE_GOOD: "LOAD_FILE_GOOD",
+ LOAD_DOMAIN_GOOD: "LOAD_DOMAIN_GOOD",
+}
+
+//
+// NewDomainMetricType - return a string representation of the enum
+//
+func NewDomainMetricType(init ...interface{}) DomainMetricType {
+ if len(init) == 1 {
+ switch v := init[0].(type) {
+ case DomainMetricType:
+ return v
+ case int:
+ return DomainMetricType(v)
+ case int32:
+ return DomainMetricType(v)
+ case string:
+ for i, s := range namesDomainMetricType {
+ if s == v {
+ return DomainMetricType(i)
+ }
+ }
+ default:
+ panic("Bad init value for DomainMetricType enum")
+ }
+ }
+ return DomainMetricType(0) //default to the first enum value
+}
+
+//
+// String - return a string representation of the enum
+//
+func (e DomainMetricType) String() string {
+ return namesDomainMetricType[e]
+}
+
+//
+// SymbolSet - return an array of all valid string representations (symbols) of the enum
+//
+func (e DomainMetricType) SymbolSet() []string {
+ return namesDomainMetricType
+}
+
+//
+// MarshalJSON is defined for proper JSON encoding of a DomainMetricType
+//
+func (e DomainMetricType) MarshalJSON() ([]byte, error) {
+ return json.Marshal(e.String())
+}
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainMetricType
+//
+func (e *DomainMetricType) UnmarshalJSON(b []byte) error {
+ var j string
+ err := json.Unmarshal(b, &j)
+ if err == nil {
+ s := string(j)
+ for v, s2 := range namesDomainMetricType {
+ if s == s2 {
+ *e = DomainMetricType(v)
+ return nil
+ }
+ }
+ err = fmt.Errorf("Bad enum symbol for type DomainMetricType: %s", s)
+ }
+ return err
+}
+
+//
+// DomainMetric -
+//
+type DomainMetric struct {
+ MetricType DomainMetricType `json:"metricType"`
+ MetricVal int32 `json:"metricVal"`
+}
+
+//
+// NewDomainMetric - creates an initialized DomainMetric instance, returns a pointer to it
+//
+func NewDomainMetric(init ...*DomainMetric) *DomainMetric {
+ var o *DomainMetric
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainMetric)
+ }
+ return o
+}
+
+type rawDomainMetric DomainMetric
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainMetric
+//
+func (pTypeDef *DomainMetric) UnmarshalJSON(b []byte) error {
+ var r rawDomainMetric
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainMetric(r)
+ *pTypeDef = o
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainMetric) Validate() error {
+ return nil
+}
+
+//
+// DomainMetrics -
+//
+type DomainMetrics struct {
+
+ //
+ // name of the domain the metrics pertain to
+ //
+ DomainName DomainName `json:"domainName"`
+
+ //
+ // list of the domains metrics
+ //
+ MetricList []*DomainMetric `json:"metricList"`
+}
+
+//
+// NewDomainMetrics - creates an initialized DomainMetrics instance, returns a pointer to it
+//
+func NewDomainMetrics(init ...*DomainMetrics) *DomainMetrics {
+ var o *DomainMetrics
+ if len(init) == 1 {
+ o = init[0]
+ } else {
+ o = new(DomainMetrics)
+ }
+ return o.Init()
+}
+
+//
+// Init - sets up the instance according to its default field values, if any
+//
+func (pTypeDef *DomainMetrics) Init() *DomainMetrics {
+ if pTypeDef.MetricList == nil {
+ pTypeDef.MetricList = make([]*DomainMetric, 0)
+ }
+ return pTypeDef
+}
+
+type rawDomainMetrics DomainMetrics
+
+//
+// UnmarshalJSON is defined for proper JSON decoding of a DomainMetrics
+//
+func (pTypeDef *DomainMetrics) UnmarshalJSON(b []byte) error {
+ var r rawDomainMetrics
+ err := json.Unmarshal(b, &r)
+ if err == nil {
+ o := DomainMetrics(r)
+ *pTypeDef = *((&o).Init())
+ err = pTypeDef.Validate()
+ }
+ return err
+}
+
+//
+// Validate - checks for missing required fields, etc
+//
+func (pTypeDef *DomainMetrics) Validate() error {
+ if pTypeDef.DomainName == "" {
+ return fmt.Errorf("DomainMetrics.domainName is missing but is a required field")
+ } else {
+ val := rdl.Validate(ZTSSchema(), "DomainName", pTypeDef.DomainName)
+ if !val.Valid {
+ return fmt.Errorf("DomainMetrics.domainName does not contain a valid DomainName (%v)", val.Error)
+ }
+ }
+ if pTypeDef.MetricList == nil {
+ return fmt.Errorf("DomainMetrics: Missing required field: metricList")
+ }
+ return nil
+}
diff --git a/clients/go/zts/zts_schema.go b/clients/go/zts/zts_schema.go
new file mode 100644
index 00000000000..8d1648ba866
--- /dev/null
+++ b/clients/go/zts/zts_schema.go
@@ -0,0 +1,418 @@
+//
+// This file generated by rdl 1.4.8
+//
+
+package zts
+
+import (
+ rdl "github.com/ardielle/ardielle-go/rdl"
+)
+
+var schema *rdl.Schema
+
+func init() {
+ sb := rdl.NewSchemaBuilder("ZTS")
+ sb.Version(1)
+ sb.Namespace("com.yahoo.athenz.zts")
+ sb.Comment("Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. The Authorization Management Service (ZTS) API")
+
+ tSimpleName := rdl.NewStringTypeBuilder("SimpleName")
+ tSimpleName.Comment("Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms. Common name types used by several API definitions A simple identifier, an element of compound name.")
+ tSimpleName.Pattern("[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tSimpleName.Build())
+
+ tCompoundName := rdl.NewStringTypeBuilder("CompoundName")
+ tCompoundName.Comment("A compound name. Most names in this API are compound names.")
+ tCompoundName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tCompoundName.Build())
+
+ tDomainName := rdl.NewStringTypeBuilder("DomainName")
+ tDomainName.Comment("A domain name is the general qualifier prefix, as its uniqueness is managed.")
+ tDomainName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tDomainName.Build())
+
+ tEntityName := rdl.NewStringTypeBuilder("EntityName")
+ tEntityName.Comment("An entity name is a short form of a resource name, including only the domain and entity.")
+ tEntityName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tEntityName.Build())
+
+ tServiceName := rdl.NewStringTypeBuilder("ServiceName")
+ tServiceName.Comment("A service name will generally be a unique subdomain.")
+ tServiceName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tServiceName.Build())
+
+ tLocationName := rdl.NewStringTypeBuilder("LocationName")
+ tLocationName.Comment("A location name is not yet defined, but will be a dotted name like everything else.")
+ tLocationName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tLocationName.Build())
+
+ tActionName := rdl.NewStringTypeBuilder("ActionName")
+ tActionName.Comment("An action (operation) name.")
+ tActionName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tActionName.Build())
+
+ tResourceName := rdl.NewStringTypeBuilder("ResourceName")
+ tResourceName.Comment("A shorthand for a YRN with no service or location. The 'tail' of a YRN, just the domain:entity. Note that the EntityName part is optional, that is, a domain name followed by a colon is valid resource name.")
+ tResourceName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*(:([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?")
+ sb.AddType(tResourceName.Build())
+
+ tYRN := rdl.NewStringTypeBuilder("YRN")
+ tYRN.Comment("A full Yahoo Resource name (YRN).")
+ tYRN.Pattern("(yrn:(([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?:(([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?:)?([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*(:([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*)?")
+ sb.AddType(tYRN.Build())
+
+ tYBase64 := rdl.NewStringTypeBuilder("YBase64")
+ tYBase64.Comment("The Y-specific URL-safe Base64 variant.")
+ tYBase64.Pattern("[a-zA-Z0-9\\._-]+")
+ sb.AddType(tYBase64.Build())
+
+ tYEncoded := rdl.NewStringTypeBuilder("YEncoded")
+ tYEncoded.Comment("YEncoded includes ybase64 chars, as well as = and %. This can represent a user cookie and URL-encoded values.")
+ tYEncoded.Pattern("[a-zA-Z0-9\\._%=-]*")
+ sb.AddType(tYEncoded.Build())
+
+ tAuthorityName := rdl.NewStringTypeBuilder("AuthorityName")
+ tAuthorityName.Comment("Used as the prefix in a signed assertion. This uniquely identifies a signing authority.")
+ tAuthorityName.Pattern("([a-zA-Z0-9_][a-zA-Z0-9_-]*\\.)*[a-zA-Z0-9_][a-zA-Z0-9_-]*")
+ sb.AddType(tAuthorityName.Build())
+
+ tSignedToken := rdl.NewStringTypeBuilder("SignedToken")
+ tSignedToken.Comment("A signed assertion if identity. i.e. the user cookie value. This token will only make sense to the authority that generated it, so it is beneficial to have something in the value that is cheaply recognized to quickly reject if it belongs to another authority. In addition to the YEncoded set our token includes ; to separate components and , to separate roles")
+ tSignedToken.Pattern("[a-zA-Z0-9\\._%=;,-]*")
+ sb.AddType(tSignedToken.Build())
+
+ tPublicKeyEntry := rdl.NewStructTypeBuilder("Struct", "PublicKeyEntry")
+ tPublicKeyEntry.Comment("The representation of the public key in a service identity object.")
+ tPublicKeyEntry.Field("key", "String", false, nil, "the public key for the service")
+ tPublicKeyEntry.Field("id", "String", false, nil, "the key identifier (version or zone name)")
+ sb.AddType(tPublicKeyEntry.Build())
+
+ tServiceIdentity := rdl.NewStructTypeBuilder("Struct", "ServiceIdentity")
+ tServiceIdentity.Comment("The representation of the service identity object.")
+ tServiceIdentity.Field("name", "ServiceName", false, nil, "the full name of the service, i.e. \"sports.storage\"")
+ tServiceIdentity.ArrayField("publicKeys", "PublicKeyEntry", true, "array of public keys for key rotation")
+ tServiceIdentity.Field("providerEndpoint", "String", true, nil, "if present, then this service can provision tenants via this endpoint.")
+ tServiceIdentity.Field("modified", "Timestamp", true, nil, "the timestamp when this entry was last modified")
+ tServiceIdentity.Field("executable", "String", true, nil, "the path of the executable that runs the service")
+ tServiceIdentity.ArrayField("hosts", "String", true, "list of host names that this service can run on")
+ tServiceIdentity.Field("user", "String", true, nil, "local (unix) user name this service can run as")
+ tServiceIdentity.Field("group", "String", true, nil, "local (unix) group name this service can run as")
+ sb.AddType(tServiceIdentity.Build())
+
+ tServiceIdentityList := rdl.NewStructTypeBuilder("Struct", "ServiceIdentityList")
+ tServiceIdentityList.Comment("The representation for an enumeration of services in the namespace.")
+ tServiceIdentityList.ArrayField("names", "EntityName", false, "list of service names")
+ sb.AddType(tServiceIdentityList.Build())
+
+ tHostServices := rdl.NewStructTypeBuilder("Struct", "HostServices")
+ tHostServices.Comment("The representation for an enumeration of services authorized to run on a specific host.")
+ tHostServices.Field("host", "String", false, nil, "name of the host")
+ tHostServices.ArrayField("names", "EntityName", false, "list of service names authorized to run on this host")
+ sb.AddType(tHostServices.Build())
+
+ tAssertionEffect := rdl.NewEnumTypeBuilder("Enum", "AssertionEffect")
+ tAssertionEffect.Comment("Every assertion can have the effect of ALLOW or DENY.")
+ tAssertionEffect.Element("ALLOW", "Every assertion can have the effect of ALLOW or DENY.")
+ tAssertionEffect.Element("DENY", "")
+ sb.AddType(tAssertionEffect.Build())
+
+ tAssertion := rdl.NewStructTypeBuilder("Struct", "Assertion")
+ tAssertion.Comment("A representation for the encapsulation of an action to be performed on a resource by a principal.")
+ tAssertion.Field("role", "String", false, nil, "the subject of the assertion, a role")
+ tAssertion.Field("resource", "String", false, nil, "the object of the assertion. Must be in the local namespace. Can contain wildcards")
+ tAssertion.Field("action", "String", false, nil, "the predicate of the assertion. Can contain wildcards")
+ tAssertion.Field("effect", "AssertionEffect", true, ALLOW, "the effect of the assertion in the policy language")
+ tAssertion.Field("id", "Int64", true, nil, "assertion id - auto generated by server")
+ sb.AddType(tAssertion.Build())
+
+ tPolicy := rdl.NewStructTypeBuilder("Struct", "Policy")
+ tPolicy.Comment("The representation for a Policy with set of assertions.")
+ tPolicy.Field("name", "ResourceName", false, nil, "name of the policy")
+ tPolicy.Field("modified", "Timestamp", true, nil, "last modification timestamp of this policy")
+ tPolicy.ArrayField("assertions", "Assertion", false, "list of defined assertions for this policy")
+ sb.AddType(tPolicy.Build())
+
+ tPolicyData := rdl.NewStructTypeBuilder("Struct", "PolicyData")
+ tPolicyData.Field("domain", "DomainName", false, nil, "name of the domain")
+ tPolicyData.ArrayField("policies", "Policy", false, "list of policies defined in this server")
+ sb.AddType(tPolicyData.Build())
+
+ tSignedPolicyData := rdl.NewStructTypeBuilder("Struct", "SignedPolicyData")
+ tSignedPolicyData.Comment("A representation of policies object defined in a given server.")
+ tSignedPolicyData.Field("policyData", "PolicyData", false, nil, "list of policies defined in a domain")
+ tSignedPolicyData.Field("zmsSignature", "String", false, nil, "zms signature generated based on the domain policies object")
+ tSignedPolicyData.Field("zmsKeyId", "String", false, nil, "the identifier of the zms key used to generate the signature")
+ tSignedPolicyData.Field("modified", "Timestamp", false, nil, "when the domain itself was last modified")
+ tSignedPolicyData.Field("expires", "Timestamp", false, nil, "timestamp specifying the expiration time for using this set of policies")
+ sb.AddType(tSignedPolicyData.Build())
+
+ tDomainSignedPolicyData := rdl.NewStructTypeBuilder("Struct", "DomainSignedPolicyData")
+ tDomainSignedPolicyData.Comment("A signed bulk transfer of policies. The data is signed with server's private key.")
+ tDomainSignedPolicyData.Field("signedPolicyData", "SignedPolicyData", false, nil, "policy data signed by ZMS")
+ tDomainSignedPolicyData.Field("signature", "String", false, nil, "signature generated based on the domain policies object")
+ tDomainSignedPolicyData.Field("keyId", "String", false, nil, "the identifier of the key used to generate the signature")
+ sb.AddType(tDomainSignedPolicyData.Build())
+
+ tRoleToken := rdl.NewStructTypeBuilder("Struct", "RoleToken")
+ tRoleToken.Comment("A representation of a signed RoleToken")
+ tRoleToken.Field("token", "String", false, nil, "")
+ tRoleToken.Field("expiryTime", "Int64", false, nil, "")
+ sb.AddType(tRoleToken.Build())
+
+ tAccess := rdl.NewStructTypeBuilder("Struct", "Access")
+ tAccess.Comment("Access can be checked and returned as this resource.")
+ tAccess.Field("granted", "Bool", false, nil, "true (allowed) or false (denied)")
+ sb.AddType(tAccess.Build())
+
+ tRoleAccess := rdl.NewStructTypeBuilder("Struct", "RoleAccess")
+ tRoleAccess.ArrayField("roles", "EntityName", false, "")
+ sb.AddType(tRoleAccess.Build())
+
+ tTenantDomains := rdl.NewStructTypeBuilder("Struct", "TenantDomains")
+ tTenantDomains.ArrayField("tenantDomainNames", "DomainName", false, "")
+ sb.AddType(tTenantDomains.Build())
+
+ tIdentity := rdl.NewStructTypeBuilder("Struct", "Identity")
+ tIdentity.Comment("Identity - a signed assertion of service or human identity, the response could be either a client certificate or just a regular NToken (depending if the request contained a csr or not).")
+ tIdentity.Field("name", "CompoundName", false, nil, "name of the identity, fully qualified, i.e. my.domain.service1, or aws.1232321321312.myusername")
+ tIdentity.Field("certificate", "String", true, nil, "a certificate usable for both client and server in TLS connections")
+ tIdentity.Field("caCertBundle", "String", true, nil, "the CA certificate chain to use with all IMS-generated certs")
+ tIdentity.Field("sshServerCert", "String", true, nil, "the SSH server cert, signed by the CA")
+ tIdentity.Field("serviceToken", "SignedToken", true, nil, "service token instead of TLS certificate")
+ tIdentity.MapField("attributes", "String", "String", true, "other config-like attributes determined at boot time")
+ sb.AddType(tIdentity.Build())
+
+ tInstanceInformation := rdl.NewStructTypeBuilder("Struct", "InstanceInformation")
+ tInstanceInformation.Comment("Instance object that includes requested service details plus host document that is signed by provider as part of the host bootstrap process")
+ tInstanceInformation.Field("document", "String", false, nil, "signed document containing attributes like IP address, instance-id, account#, etc.")
+ tInstanceInformation.Field("signature", "String", false, nil, "the signature for the document")
+ tInstanceInformation.Field("keyId", "String", false, nil, "the keyid used to sign the document")
+ tInstanceInformation.Field("domain", "CompoundName", false, nil, "the domain of the instance")
+ tInstanceInformation.Field("service", "SimpleName", false, nil, "the service this instance is supposed to run")
+ tInstanceInformation.Field("csr", "String", false, nil, "return a certificate in the response")
+ sb.AddType(tInstanceInformation.Build())
+
+ tInstanceRefreshRequest := rdl.NewStructTypeBuilder("Struct", "InstanceRefreshRequest")
+ tInstanceRefreshRequest.Comment("InstanceRefreshRequest - a certificate refresh request")
+ tInstanceRefreshRequest.Field("csr", "String", false, nil, "Cert CSR if requesting TLS certificate")
+ tInstanceRefreshRequest.Field("expiryTime", "Int32", true, nil, "in seconds how long token should be valid for")
+ sb.AddType(tInstanceRefreshRequest.Build())
+
+ tAWSInstanceInformation := rdl.NewStructTypeBuilder("Struct", "AWSInstanceInformation")
+ tAWSInstanceInformation.Comment("AWSInstanceInformation - the information a booting EC2 instance must provide to ZTS to authenticate.")
+ tAWSInstanceInformation.Field("document", "String", false, nil, "signed document containing attributes like IP address, instance-id, account#, etc.")
+ tAWSInstanceInformation.Field("signature", "String", false, nil, "the signature for the document")
+ tAWSInstanceInformation.Field("domain", "CompoundName", false, nil, "the domain of the instance")
+ tAWSInstanceInformation.Field("service", "SimpleName", false, nil, "the service this instance is supposed to run")
+ tAWSInstanceInformation.Field("csr", "String", false, nil, "return a certificate in the response")
+ tAWSInstanceInformation.Field("name", "CompoundName", false, nil, "the full service identity name (same as the EC2 instance profile name)")
+ tAWSInstanceInformation.Field("account", "SimpleName", false, nil, "the account id (as a string) for the instance. parsed from the instance profile ARN")
+ tAWSInstanceInformation.Field("cloud", "SimpleName", true, nil, "the name of the cloud (namespace) within the account, parsed from the name")
+ tAWSInstanceInformation.Field("subnet", "SimpleName", false, nil, "the name of the subnet this instance is expected to be running in, parsed from the name")
+ tAWSInstanceInformation.Field("access", "String", false, nil, "the AWS Access Key Id for the role")
+ tAWSInstanceInformation.Field("secret", "String", false, nil, "the AWS Secret Access Key for the role")
+ tAWSInstanceInformation.Field("token", "String", false, nil, "the AWS STS Token for the role")
+ tAWSInstanceInformation.Field("expires", "Timestamp", false, nil, "the expiration time of the access keys")
+ tAWSInstanceInformation.Field("modified", "Timestamp", false, nil, "the modified time of the access keys")
+ tAWSInstanceInformation.Field("flavor", "String", false, nil, "the 'flavor' of the access keys, i.e. \"AWS-HMAC\"")
+ sb.AddType(tAWSInstanceInformation.Build())
+
+ tAWSCertificateRequest := rdl.NewStructTypeBuilder("Struct", "AWSCertificateRequest")
+ tAWSCertificateRequest.Comment("AWSCertificateRequest - a certificate signing request")
+ tAWSCertificateRequest.Field("csr", "String", false, nil, "")
+ sb.AddType(tAWSCertificateRequest.Build())
+
+ tAWSTemporaryCredentials := rdl.NewStructTypeBuilder("Struct", "AWSTemporaryCredentials")
+ tAWSTemporaryCredentials.Field("accessKeyId", "String", false, nil, "")
+ tAWSTemporaryCredentials.Field("secretAccessKey", "String", false, nil, "")
+ tAWSTemporaryCredentials.Field("sessionToken", "String", false, nil, "")
+ tAWSTemporaryCredentials.Field("expiration", "Timestamp", false, nil, "")
+ sb.AddType(tAWSTemporaryCredentials.Build())
+
+ tDomainMetricType := rdl.NewEnumTypeBuilder("Enum", "DomainMetricType")
+ tDomainMetricType.Comment("zpe metric attributes")
+ tDomainMetricType.Element("ACCESS_ALLOWED", "zpe metric attributes")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DENY", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DENY_NO_MATCH", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_ALLOW", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_ERROR", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_TOKEN_INVALID", "")
+ tDomainMetricType.Element("ACCESS_Allowed_TOKEN_EXPIRED", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DOMAIN_NOT_FOUND", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DOMAIN_MISMATCH", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DOMAIN_EXPIRED", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_DOMAIN_EMPTY", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_TOKEN_CACHE_FAILURE", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_TOKEN_CACHE_NOT_FOUND", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_TOKEN_CACHE_SUCCESS", "")
+ tDomainMetricType.Element("ACCESS_ALLOWED_TOKEN_VALIDATE", "")
+ tDomainMetricType.Element("LOAD_FILE_FAIL", "")
+ tDomainMetricType.Element("LOAD_FILE_GOOD", "")
+ tDomainMetricType.Element("LOAD_DOMAIN_GOOD", "")
+ sb.AddType(tDomainMetricType.Build())
+
+ tDomainMetric := rdl.NewStructTypeBuilder("Struct", "DomainMetric")
+ tDomainMetric.Field("metricType", "DomainMetricType", false, nil, "")
+ tDomainMetric.Field("metricVal", "Int32", false, nil, "")
+ sb.AddType(tDomainMetric.Build())
+
+ tDomainMetrics := rdl.NewStructTypeBuilder("Struct", "DomainMetrics")
+ tDomainMetrics.Field("domainName", "DomainName", false, nil, "name of the domain the metrics pertain to")
+ tDomainMetrics.ArrayField("metricList", "DomainMetric", false, "list of the domains metrics")
+ sb.AddType(tDomainMetrics.Build())
+
+ rGetServiceIdentity := rdl.NewResourceBuilder("ServiceIdentity", "GET", "/domain/{domainName}/service/{serviceName}")
+ rGetServiceIdentity.Comment("Get info for the specified ServiceIdentity.")
+ rGetServiceIdentity.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetServiceIdentity.Input("serviceName", "ServiceName", true, "", "", false, nil, "name of the service to be retrieved")
+ rGetServiceIdentity.Auth("", "", true, "")
+ rGetServiceIdentity.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServiceIdentity.Exception("NOT_FOUND", "ResourceError", "")
+ rGetServiceIdentity.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServiceIdentity.Build())
+
+ rGetServiceIdentityList := rdl.NewResourceBuilder("ServiceIdentityList", "GET", "/domain/{domainName}/service")
+ rGetServiceIdentityList.Comment("Enumerate services provisioned in this domain.")
+ rGetServiceIdentityList.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetServiceIdentityList.Auth("", "", true, "")
+ rGetServiceIdentityList.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetServiceIdentityList.Exception("NOT_FOUND", "ResourceError", "")
+ rGetServiceIdentityList.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetServiceIdentityList.Build())
+
+ rGetPublicKeyEntry := rdl.NewResourceBuilder("PublicKeyEntry", "GET", "/domain/{domainName}/service/{serviceName}/publickey/{keyId}")
+ rGetPublicKeyEntry.Comment("Retrieve the specified public key from the service.")
+ rGetPublicKeyEntry.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetPublicKeyEntry.Input("serviceName", "SimpleName", true, "", "", false, nil, "name of the service")
+ rGetPublicKeyEntry.Input("keyId", "String", true, "", "", false, nil, "the identifier of the public key to be retrieved")
+ rGetPublicKeyEntry.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetPublicKeyEntry.Exception("NOT_FOUND", "ResourceError", "")
+ sb.AddResource(rGetPublicKeyEntry.Build())
+
+ rGetHostServices := rdl.NewResourceBuilder("HostServices", "GET", "/host/{host}/services")
+ rGetHostServices.Comment("Enumerate services provisioned on a specific host")
+ rGetHostServices.Input("host", "String", true, "", "", false, nil, "name of the host")
+ rGetHostServices.Exception("BAD_REQUEST", "ResourceError", "")
+ sb.AddResource(rGetHostServices.Build())
+
+ rGetDomainSignedPolicyData := rdl.NewResourceBuilder("DomainSignedPolicyData", "GET", "/domain/{domainName}/signed_policy_data")
+ rGetDomainSignedPolicyData.Comment("Get a signed policy enumeration from the service, to transfer to a local store. An ETag is generated for the PolicyList that changes when any item in the list changes. If the If-None-Match header is provided, and it matches the ETag that would be returned, then a NOT_MODIFIED response is returned instead of the list.")
+ rGetDomainSignedPolicyData.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetDomainSignedPolicyData.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")
+ rGetDomainSignedPolicyData.Output("tag", "String", "ETag", false, "")
+ rGetDomainSignedPolicyData.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetDomainSignedPolicyData.Exception("NOT_FOUND", "ResourceError", "")
+ sb.AddResource(rGetDomainSignedPolicyData.Build())
+
+ rGetRoleToken := rdl.NewResourceBuilder("RoleToken", "GET", "/domain/{domainName}/token")
+ rGetRoleToken.Comment("Return a security token for the specific role in the namespace that the user can assume. If the role is omitted, then all roles in the namespace that the authenticated user can assume are returned. the caller can specify how long the RoleToken should be valid for by specifying the minExpiryTime and maxExpiryTime parameters. The minExpiryTime specifies that the returned RoleToken must be at least valid (min/lower bound) for specified number of seconds, while maxExpiryTime specifies that the RoleToken must be at most valid (max/upper bound) for specified number of seconds. If both values are the same, the server must return a RoleToken for that many seconds. If no values are specified, the server's default RoleToken Timeout value is used.")
+ rGetRoleToken.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetRoleToken.Input("role", "EntityName", false, "role", "", true, nil, "only interested for a token for this role")
+ rGetRoleToken.Input("minExpiryTime", "Int32", false, "minExpiryTime", "", true, nil, "in seconds min expiry time")
+ rGetRoleToken.Input("maxExpiryTime", "Int32", false, "maxExpiryTime", "", true, nil, "in seconds max expiry time")
+ rGetRoleToken.Input("proxyForPrincipal", "EntityName", false, "proxyForPrincipal", "", true, nil, "optional this request is proxy for this principal")
+ rGetRoleToken.Auth("", "", true, "")
+ rGetRoleToken.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetRoleToken.Exception("FORBIDDEN", "ResourceError", "")
+ rGetRoleToken.Exception("NOT_FOUND", "ResourceError", "")
+ rGetRoleToken.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetRoleToken.Build())
+
+ rGetAccess := rdl.NewResourceBuilder("Access", "GET", "/access/domain/{domainName}/role/{roleName}/principal/{principal}")
+ rGetAccess.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetAccess.Input("roleName", "EntityName", true, "", "", false, nil, "name of the role to check access for")
+ rGetAccess.Input("principal", "EntityName", true, "", "", false, nil, "carry out the access check for this principal")
+ rGetAccess.Auth("", "", true, "")
+ rGetAccess.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetAccess.Exception("FORBIDDEN", "ResourceError", "")
+ rGetAccess.Exception("NOT_FOUND", "ResourceError", "")
+ rGetAccess.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetAccess.Build())
+
+ rGetRoleAccess := rdl.NewResourceBuilder("RoleAccess", "GET", "/access/domain/{domainName}/principal/{principal}")
+ rGetRoleAccess.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain")
+ rGetRoleAccess.Input("principal", "EntityName", true, "", "", false, nil, "carry out the role access lookup for this principal")
+ rGetRoleAccess.Auth("", "", true, "")
+ rGetRoleAccess.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetRoleAccess.Exception("NOT_FOUND", "ResourceError", "")
+ rGetRoleAccess.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetRoleAccess.Build())
+
+ rGetTenantDomains := rdl.NewResourceBuilder("TenantDomains", "GET", "/providerdomain/{providerDomainName}/user/{userName}")
+ rGetTenantDomains.Comment("Get list of tenant domains user has access to for specified provider domain and service")
+ rGetTenantDomains.Input("providerDomainName", "DomainName", true, "", "", false, nil, "name of the provider domain")
+ rGetTenantDomains.Input("userName", "EntityName", true, "", "", false, nil, "name of the user to retrieve tenant domain access for")
+ rGetTenantDomains.Input("roleName", "EntityName", false, "roleName", "", true, nil, "role name to filter on when looking for the tenants in provider")
+ rGetTenantDomains.Input("serviceName", "ServiceName", false, "serviceName", "", true, nil, "service name to filter on when looking for the tenants in provider")
+ rGetTenantDomains.Auth("", "", true, "")
+ rGetTenantDomains.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetTenantDomains.Exception("NOT_FOUND", "ResourceError", "")
+ rGetTenantDomains.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetTenantDomains.Build())
+
+ rPostInstanceInformation := rdl.NewResourceBuilder("Identity", "POST", "/instance")
+ rPostInstanceInformation.Comment("Get a cert for service being bootstrapped by supported service")
+ rPostInstanceInformation.Input("info", "InstanceInformation", false, "", "", false, nil, "")
+ rPostInstanceInformation.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostInstanceInformation.Exception("FORBIDDEN", "ResourceError", "")
+ rPostInstanceInformation.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostInstanceInformation.Build())
+
+ rPostInstanceRefreshRequest := rdl.NewResourceBuilder("Identity", "POST", "/instance/{domain}/{service}/refresh")
+ rPostInstanceRefreshRequest.Comment("Refresh self identity if the original identity was issued by ZTS")
+ rPostInstanceRefreshRequest.Input("domain", "CompoundName", true, "", "", false, nil, "name of the domain requesting the refresh")
+ rPostInstanceRefreshRequest.Input("service", "SimpleName", true, "", "", false, nil, "name of the service requesting the refresh")
+ rPostInstanceRefreshRequest.Input("req", "InstanceRefreshRequest", false, "", "", false, nil, "the refresh request")
+ rPostInstanceRefreshRequest.Auth("", "", true, "")
+ rPostInstanceRefreshRequest.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostInstanceRefreshRequest.Exception("FORBIDDEN", "ResourceError", "")
+ rPostInstanceRefreshRequest.Exception("NOT_FOUND", "ResourceError", "")
+ rPostInstanceRefreshRequest.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostInstanceRefreshRequest.Build())
+
+ rPostAWSInstanceInformation := rdl.NewResourceBuilder("Identity", "POST", "/aws/instance")
+ rPostAWSInstanceInformation.Comment("Register an instance in AWS ZTS. Whether this succeeds or not depends on the contents of the request (the request itself is not authenticated or authorized in the normal way). If successful, the Identity is returned as a x.509 client certificate (to be used in TLS operations)")
+ rPostAWSInstanceInformation.Input("info", "AWSInstanceInformation", false, "", "", false, nil, "")
+ rPostAWSInstanceInformation.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostAWSInstanceInformation.Exception("FORBIDDEN", "ResourceError", "")
+ rPostAWSInstanceInformation.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostAWSInstanceInformation.Build())
+
+ rPostAWSCertificateRequest := rdl.NewResourceBuilder("Identity", "POST", "/aws/instance/{domain}/{service}/refresh")
+ rPostAWSCertificateRequest.Comment("Rotate certs. Make this request with previous cert, the result is new cert for the same identity.")
+ rPostAWSCertificateRequest.Input("domain", "CompoundName", true, "", "", false, nil, "name of the domain requesting the refresh")
+ rPostAWSCertificateRequest.Input("service", "SimpleName", true, "", "", false, nil, "name of the service requesting the refresh")
+ rPostAWSCertificateRequest.Input("req", "AWSCertificateRequest", false, "", "", false, nil, "the refresh request")
+ rPostAWSCertificateRequest.Auth("", "", true, "")
+ rPostAWSCertificateRequest.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostAWSCertificateRequest.Exception("FORBIDDEN", "ResourceError", "")
+ rPostAWSCertificateRequest.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostAWSCertificateRequest.Build())
+
+ rGetAWSTemporaryCredentials := rdl.NewResourceBuilder("AWSTemporaryCredentials", "GET", "/domain/{domainName}/role/{role}/creds")
+ rGetAWSTemporaryCredentials.Comment("perform an AWS AssumeRole of the target role and return the credentials. ZTS must have been granted the ability to assume the role in IAM, and granted the ability to ASSUME_AWS_ROLE in Athenz for this to succeed.")
+ rGetAWSTemporaryCredentials.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain containing the role, which implies the target account")
+ rGetAWSTemporaryCredentials.Input("role", "CompoundName", true, "", "", false, nil, "the target AWS role name in the domain account, in Athenz terms, i.e. \"the.role\"")
+ rGetAWSTemporaryCredentials.Auth("", "", true, "")
+ rGetAWSTemporaryCredentials.Exception("BAD_REQUEST", "ResourceError", "")
+ rGetAWSTemporaryCredentials.Exception("FORBIDDEN", "ResourceError", "")
+ rGetAWSTemporaryCredentials.Exception("NOT_FOUND", "ResourceError", "")
+ rGetAWSTemporaryCredentials.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rGetAWSTemporaryCredentials.Build())
+
+ rPostDomainMetrics := rdl.NewResourceBuilder("DomainMetrics", "POST", "/metrics/{domainName}")
+ rPostDomainMetrics.Comment("called to post multiple zpe related metric attributes")
+ rPostDomainMetrics.Input("domainName", "DomainName", true, "", "", false, nil, "name of the domain the metrics pertain to")
+ rPostDomainMetrics.Input("req", "DomainMetrics", false, "", "", false, nil, "")
+ rPostDomainMetrics.Exception("BAD_REQUEST", "ResourceError", "")
+ rPostDomainMetrics.Exception("FORBIDDEN", "ResourceError", "")
+ rPostDomainMetrics.Exception("NOT_FOUND", "ResourceError", "")
+ rPostDomainMetrics.Exception("UNAUTHORIZED", "ResourceError", "")
+ sb.AddResource(rPostDomainMetrics.Build())
+
+ schema = sb.Build()
+}
+
+func ZTSSchema() *rdl.Schema {
+ return schema
+}
diff --git a/clients/java/sia/README.md b/clients/java/sia/README.md
new file mode 100644
index 00000000000..89bb17098d2
--- /dev/null
+++ b/clients/java/sia/README.md
@@ -0,0 +1,27 @@
+Service Identity Agent Client Java Library
+
+System properties:
+
+ athenz.sia.client.ntoken_path
+ When used in athenz enabled environment, this setting specifies
+ the path of the file that contains the ntoken generated by the framework.
+ This setting requires that ntoken_domain and ntoken_service settings
+ to be configured as well.
+
+ athenz.sia.client.ntoken_domain
+ This setting specifies the domain name of the service that is identified
+ by the ntoken generated by the framework(see ntoken_path above).
+ This setting requires that ntoken_path and ntoken_service settings
+ to be configured as well.
+
+ athenz.sia.client.ntoken_service
+ This setting specifies the service name that is identified
+ by the ntoken generated by the framework(see ntoken_path above).
+ This setting requires that ntoken_path and ntoken_domain settings
+ to be configured as well.
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
diff --git a/clients/java/sia/pom.xml b/clients/java/sia/pom.xml
new file mode 100644
index 00000000000..c379b49c3a9
--- /dev/null
+++ b/clients/java/sia/pom.xml
@@ -0,0 +1,62 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+ sia_java_client
+ jar
+ sia_java_client
+ SIA Java Client Library
+
+
+
+ ${project.groupId}
+ auth_core
+ ${project.parent.version}
+
+
+ com.kohlschutter.junixsocket
+ junixsocket-common
+ 2.0.4
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+
+ prepare-package
+
+ jar
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/sia/src/main/java/com/yahoo/athenz/sia/SIA.java b/clients/java/sia/src/main/java/com/yahoo/athenz/sia/SIA.java
new file mode 100644
index 00000000000..d6279277d26
--- /dev/null
+++ b/clients/java/sia/src/main/java/com/yahoo/athenz/sia/SIA.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.sia;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.yahoo.athenz.auth.Principal;
+
+public interface SIA {
+
+ /**
+ * For the specified domain/service return the corresponding Service Principal that
+ * includes the SIA generated PrincipalToken (NToken)
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param minExpiryTime (optional) specifies that the returned PrincipalToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned PrincipalToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @param ignoreCache ignore the cache and retrieve the token from SIA Server
+ * @return SIA generated Principal object with PrincipalToken
+ * @throws IOException for any IO errors
+ */
+ public Principal getServicePrincipal(String domainName, String serviceName,
+ Integer minExpiryTime, Integer maxExpiryTime, boolean ignoreCache) throws IOException;
+
+ /**
+ * Returns the list of domains that have private keys registered on this host
+ * @return List of domain names
+ * @throws IOException for any IO errors
+ */
+ public ArrayList getDomainList() throws IOException;
+}
diff --git a/clients/java/sia/src/main/java/com/yahoo/athenz/sia/impl/SIAClient.java b/clients/java/sia/src/main/java/com/yahoo/athenz/sia/impl/SIAClient.java
new file mode 100644
index 00000000000..598bd5f646c
--- /dev/null
+++ b/clients/java/sia/src/main/java/com/yahoo/athenz/sia/impl/SIAClient.java
@@ -0,0 +1,526 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.sia.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.newsclub.net.unix.AFUNIXSocket;
+import org.newsclub.net.unix.AFUNIXSocketAddress;
+import org.newsclub.net.unix.AFUNIXSocketException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.Authority;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.PrincipalAuthority;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+import com.yahoo.athenz.auth.token.PrincipalToken;
+import com.yahoo.athenz.sia.SIA;
+import com.yahoo.rdl.JSON;
+import com.yahoo.rdl.Struct;
+
+/**
+ * SIA Client Library to retrieve Service Principal and the list of ZMS Domains
+ * provisioned to run on this host.
+ */
+public class SIAClient implements SIA {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SIAClient.class);
+
+ public static final int OP_GET_NTOKEN = 1;
+ public static final int OP_LIST_DOMAINS = 2;
+
+ private static int tokenMinExpiryTime = 1800;
+ private static final String UNIX_SOCKET_FNAME = "/var/run/sia/sia.ds";
+ private static final String ROOT_DIR = "/home/athenz";
+ private static final Authority PRINCIPAL_AUTHORITY = new PrincipalAuthority();
+
+ // Used for testing: if set, should point to the config file containing vars specifying
+ // the ntoken is in a file.
+ static final String SIA_PROP_CFG_FILE = "athenz.sia.client.config_path";
+
+ // vars used to set the config file
+ static final String SIACLT_NTOKEN_PATH = "ntoken_path";
+ static final String SIACLT_NTOKEN_DOMAIN = "ntoken_domain";
+ static final String SIACLT_NTOKEN_SERVICE = "ntoken_service";
+
+ // system property vars
+ static final String SIA_PROP_NTOKEN_PATH = "athenz.sia.client.ntoken_path";
+ static final String SIA_PROP_NTOKEN_DOMAIN = "athenz.sia.client.ntoken_domain";
+ static final String SIA_PROP_NTOKEN_SERVICE = "athenz.sia.client.ntoken_service";
+
+ static ConcurrentHashMap principalTokenCache = new ConcurrentHashMap<>();
+
+ // values obtained from the system properties and config file
+ //
+ static String cfgNtokenPath = null;
+ static String cfgNtokenDomain = null;
+ static String cfgNtokenService = null;
+
+ final static String CONF_PATH = "/conf/sia_java_client/sia_client.conf";
+
+ static {
+ initConfigVars();
+ }
+
+ static void initConfigVars() {
+ String ntokenPath = null;
+ String ntokenDomain = null;
+ String ntokenSvc = null;
+
+ // load the config vars. in case of any exceptions
+ // we'll just set our config variables to null and default to using
+ // SIA Server for principal tokens
+
+ Struct configVars = null;
+ try {
+ String confFile = System.getProperty(SIA_PROP_CFG_FILE);
+ if (confFile == null) {
+ String rootDir = System.getenv("ROOT");
+ if (null == rootDir) {
+ rootDir = File.separator + "home" + File.separator + "athenz";
+ }
+ confFile = rootDir + CONF_PATH;
+ }
+
+ Path path = Paths.get(confFile);
+ configVars = JSON.fromBytes(Files.readAllBytes(path), Struct.class);
+
+ setupConfigVars(configVars.getString(SIACLT_NTOKEN_PATH),
+ configVars.getString(SIACLT_NTOKEN_DOMAIN),
+ configVars.getString(SIACLT_NTOKEN_SERVICE));
+ } catch (Exception exc) {
+ LOG.error("SIACLT: config variable initialization failure. Will use SIA Server for Principal Tokens", exc);
+ cfgNtokenPath = null;
+ cfgNtokenDomain = null;
+ cfgNtokenService = null;
+ return;
+ }
+
+ // load the System properties
+ // if set, they over-ride the config variables. in case of any exceptions
+ // we'll just set our config variables to null and default to using
+ // SIA Server for principal tokens
+
+ try {
+ ntokenPath = System.getProperty(SIA_PROP_NTOKEN_PATH);
+ ntokenDomain = System.getProperty(SIA_PROP_NTOKEN_DOMAIN);
+ ntokenSvc = System.getProperty(SIA_PROP_NTOKEN_SERVICE);
+ } catch (Exception exc) {
+ LOG.error("SIACLT: system property initialization failure. Will use SIA Server for Principal Tokens", exc);
+ cfgNtokenPath = null;
+ cfgNtokenDomain = null;
+ cfgNtokenService = null;
+ return;
+ }
+
+ if (ntokenPath == null || ntokenPath.isEmpty()) {
+ ntokenPath = cfgNtokenPath;
+ }
+ if (ntokenDomain == null || ntokenDomain.isEmpty()) {
+ ntokenDomain = cfgNtokenDomain;
+ }
+ if (ntokenSvc == null || ntokenSvc.isEmpty()) {
+ ntokenSvc = cfgNtokenService;
+ }
+ setupConfigVars(ntokenPath, ntokenDomain, ntokenSvc);
+ }
+
+ static void setupConfigVars(String ntokenPath, String ntokenDomain, String ntokenSvc) throws IllegalArgumentException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("SIACLT:setupConfigVars: ntoken path=" + ntokenPath +
+ " domain=" + ntokenDomain + " service=" + ntokenSvc);
+ }
+
+ // make sure no empty strings(ie. "") were specified
+ //
+ if (ntokenPath != null && ntokenPath.isEmpty()) {
+ cfgNtokenPath = null;
+ } else {
+ cfgNtokenPath = ntokenPath;
+ }
+
+ if (ntokenDomain != null) {
+ if (ntokenDomain.isEmpty()) {
+ cfgNtokenDomain = null;
+ } else {
+ cfgNtokenDomain = ntokenDomain.toLowerCase();
+ }
+ }
+
+ if (ntokenSvc != null) {
+ if (ntokenSvc.isEmpty()) {
+ cfgNtokenService = null;
+ } else {
+ cfgNtokenService = ntokenSvc.toLowerCase();
+ }
+ }
+
+ if (!((cfgNtokenPath == null && cfgNtokenDomain == null && cfgNtokenService == null) ||
+ (cfgNtokenPath != null && cfgNtokenDomain != null && cfgNtokenService != null))) {
+ String errMsg = "SIACLT: invalid ntoken configuration settings: " +
+ "ntoken_path, ntoken_domain, ntoken_service must all be set " +
+ "to use the client in a managed Athenz enabled environment";
+ LOG.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ // build the service only if we have configured valid values
+
+ if (cfgNtokenDomain != null) {
+ StringBuilder sb = new StringBuilder(512);
+ sb.append(cfgNtokenDomain).append(".").append(cfgNtokenService);
+ cfgNtokenService = sb.toString();
+ }
+ }
+
+ public SIAClient() {
+ }
+
+ String siaSocketFile() {
+
+ String root = System.getenv("ROOT");
+ if (root == null) {
+ root = ROOT_DIR;
+ }
+
+ return root + UNIX_SOCKET_FNAME;
+ }
+
+ String getPrincipalTokenCacheKey(String domainName, String serviceName) {
+
+ StringBuilder cacheKey = new StringBuilder(512);
+ cacheKey.append(domainName);
+ cacheKey.append(".");
+ cacheKey.append(serviceName);
+ return cacheKey.toString();
+ }
+
+ boolean isExpiredToken(long expiryTime, Integer minExpiryTime, Integer maxExpiryTime) {
+
+ // we'll first make sure if we're given both min and max expiry
+ // times then both conditions are satisfied
+
+ if (minExpiryTime != null && expiryTime < minExpiryTime) {
+ return true;
+ }
+
+ if (maxExpiryTime != null && expiryTime > maxExpiryTime) {
+ return true;
+ }
+
+ // if both limits were null then we need to make sure
+ // that our token is valid for our min configured value
+
+ if (minExpiryTime == null && maxExpiryTime == null && expiryTime < tokenMinExpiryTime) {
+ return true;
+ }
+
+ return false;
+ }
+
+ PrincipalToken lookupPrincipalTokenInCache(String cacheKey, Integer minExpiryTime, Integer maxExpiryTime) {
+
+ PrincipalToken principalToken = principalTokenCache.get(cacheKey);
+ if (principalToken == null) {
+ return null;
+ }
+
+ // before returning our cache hit we need to make sure it
+ // satisfies the time requirements as specified by the client
+
+ long expiryTime = principalToken.getExpiryTime() - (System.currentTimeMillis() / 1000);
+
+ if (isExpiredToken(expiryTime, minExpiryTime, maxExpiryTime)) {
+ principalTokenCache.remove(cacheKey);
+ return null;
+ }
+
+ return principalToken;
+ }
+
+ int readResponseData(InputStream is, byte[] data) throws IOException {
+
+ int read;
+ int offset = 0;
+ int length = data.length;
+
+ while (true) {
+ read = is.read(data, offset, length);
+ if (read == -1) {
+ break;
+ }
+
+ offset += read;
+ length -= read;
+
+ if (length == 0) {
+ break;
+ }
+ }
+
+ return offset;
+ }
+
+ Socket getSIADomainSocket() throws IOException {
+ File socketFile = new File(siaSocketFile());
+ AFUNIXSocket sock = AFUNIXSocket.newInstance();
+ try {
+ sock.connect(new AFUNIXSocketAddress(socketFile));
+ } catch (AFUNIXSocketException e) {
+ throw e;
+ }
+ return sock;
+ }
+
+ String processRequest(Socket sock, int sia_op, byte[] data) throws IOException {
+
+ String response = null;
+ try (InputStream is = sock.getInputStream();
+ OutputStream os = sock.getOutputStream()) {
+
+ // first we are going to write our magic number
+
+ ByteBuffer dsBytes = ByteBuffer.allocate(4);
+ dsBytes.order(ByteOrder.LITTLE_ENDIAN);
+ dsBytes.putInt(0x534941);
+ os.write(dsBytes.array());
+
+ // next we are going to write our operation code
+
+ dsBytes.clear();
+ dsBytes.putInt(sia_op);
+ os.write(dsBytes.array());
+
+ // next write the length of our data which should be 4 bytes
+
+ dsBytes.clear();
+ dsBytes.putInt(data != null ? data.length : 0);
+ os.write(dsBytes.array());
+
+ // now write our data
+
+ if (data != null) {
+ os.write(data);
+ }
+
+ os.flush();
+
+ // first read the response status
+
+ byte[] retCodeBytes = new byte[4];
+ int read = readResponseData(is, retCodeBytes);
+ if (read != 4) {
+ throw new IOException("Unable to read response return code");
+ }
+
+ ByteBuffer retBytes = ByteBuffer.wrap(retCodeBytes);
+ retBytes.order(ByteOrder.LITTLE_ENDIAN);
+ int retCode = retBytes.getInt();
+
+ if (retCode != 0) {
+ throw new IOException("Server failed to process request - error: " + retCode);
+ }
+
+ // next read the response length
+
+ byte[] dataSize = new byte[4];
+ read = readResponseData(is, dataSize);
+ if (read != 4) {
+ throw new IOException("Unable to read response length");
+ }
+
+ ByteBuffer dataBytes = ByteBuffer.wrap(dataSize);
+ dataBytes.order(ByteOrder.LITTLE_ENDIAN);
+ int dataLen = dataBytes.getInt();
+
+ // now read the rest of the data
+
+ byte[] buf = new byte[dataLen];
+ read = readResponseData(is, buf);
+ if (read != dataLen) {
+ throw new IOException("Read partial data: " + read + " vs. " + dataLen);
+ }
+
+ response = new String(buf, "UTF-8");
+ }
+
+ return response;
+ }
+
+ byte[] tokenRequestBuilder(String domainName, String serviceName, Integer maxExpiryTime) {
+
+ StringBuilder reqBuilder = new StringBuilder(512);
+ reqBuilder.append("d=");
+ reqBuilder.append(domainName);
+ reqBuilder.append(",s=");
+ reqBuilder.append(serviceName);
+ if (maxExpiryTime != null) {
+ reqBuilder.append(",e=");
+ reqBuilder.append(maxExpiryTime);
+ }
+ return reqBuilder.toString().getBytes(StandardCharsets.UTF_8);
+ }
+
+ String getSIAPrincipalToken(String domainName, String serviceName, Integer maxExpiryTime) throws IOException {
+
+ byte[] req = tokenRequestBuilder(domainName, serviceName, maxExpiryTime);
+
+ String token = null;
+ Socket sock = null;
+ try {
+ sock = getSIADomainSocket();
+ token = processRequest(sock, OP_GET_NTOKEN, req);
+ } finally {
+ if (sock != null) {
+ sock.close();
+ }
+ }
+
+ return token;
+ }
+
+ /**
+ * For the specified domain/service return the corresponding Service Principal that
+ * includes the SIA generated PrincipalToken (NToken)
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param minExpiryTime (optional) specifies that the returned PrincipalToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned PrincipalToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @param ignoreCache ignore the cache and retrieve the token from SIA Server
+ * @return SIA generated Principal object with PrincipalToken
+ * @throws IOException for IO errors
+ */
+ public Principal getServicePrincipal(String domainName, String serviceName,
+ Integer minExpiryTime, Integer maxExpiryTime, boolean ignoreCache)
+ throws IOException {
+
+ if (domainName == null || domainName.isEmpty() ||
+ serviceName == null || serviceName.isEmpty()) {
+
+ String errMsg = "get service principal: both domain and service names are required";
+ LOG.error("SIACLT: " + errMsg);
+ throw new IOException(errMsg);
+ }
+
+ // normalize our domain and service names to lower case
+
+ domainName = domainName.toLowerCase();
+ serviceName = serviceName.toLowerCase();
+
+ // first lookup in our cache to see if it can be satisfied
+ // only if we're not asked to ignore the cache
+
+ String nToken = null;
+ String cacheKey = getPrincipalTokenCacheKey(domainName, serviceName);
+ if (!ignoreCache) {
+ PrincipalToken principalToken = lookupPrincipalTokenInCache(cacheKey, minExpiryTime, maxExpiryTime);
+ if (principalToken != null) {
+ nToken = principalToken.getSignedToken();
+ }
+ }
+
+ if (nToken == null) {
+
+ // get ntoken from file path if configured, else retrieve from SIA server
+ //
+ if (cfgNtokenPath != null) {
+ nToken = getFilePrincipalToken(domainName, serviceName);
+ } else {
+
+ // retrieve a new PrincipalToken from SIA Server if we didn't
+ // satisfy the request from our cache
+ //
+ nToken = getSIAPrincipalToken(domainName, serviceName, maxExpiryTime);
+
+ // create and put a new PrincipalToken object in the cache and
+ // return a newly created principal object
+
+ PrincipalToken principalToken = new PrincipalToken(nToken);
+ principalTokenCache.put(cacheKey, principalToken);
+ }
+ }
+
+ return SimplePrincipal.create(domainName, serviceName, nToken, PRINCIPAL_AUTHORITY);
+ }
+
+ String getFilePrincipalToken(String domainName, String serviceName) throws IOException {
+ StringBuilder sb = new StringBuilder(512);
+ sb.append(domainName).append("."). append(serviceName);
+ String svc = sb.toString().toLowerCase();
+ if (!svc.equals(cfgNtokenService)) {
+ String errMsg = "SIACLT: get ntoken from file: Unknown service=" +
+ svc + " Configured service=" + cfgNtokenService;
+ LOG.error(errMsg);
+ throw new IOException(errMsg);
+ }
+
+ Path path = Paths.get(cfgNtokenPath);
+ String token = new String(Files.readAllBytes(path));
+ if (token != null && !token.isEmpty()) {
+ token = token.trim();
+ int index = token.indexOf('\n');
+ if (index != -1) {
+ token = token.substring(0, index);
+ }
+ }
+ return token;
+ }
+
+ /**
+ * Returns the list of domains that have private keys registered on this host
+ * @return List of domain names
+ * @throws IOException for any IO errors
+ */
+ public ArrayList getDomainList() throws IOException {
+
+ String domains = null;
+ Socket sock = null;
+ try {
+ sock = getSIADomainSocket();
+ domains = processRequest(sock, OP_LIST_DOMAINS, null);
+ } finally {
+ if (sock != null) {
+ sock.close();
+ }
+ }
+
+ StringTokenizer st = new StringTokenizer(domains, ";");
+ ArrayList domainList = new ArrayList();
+ while (st.hasMoreTokens()) {
+ domainList.add(st.nextToken());
+ }
+
+ return domainList;
+ }
+}
diff --git a/clients/java/sia/src/test/java/com/yahoo/athenz/sia/impl/SIAClientTest.java b/clients/java/sia/src/test/java/com/yahoo/athenz/sia/impl/SIAClientTest.java
new file mode 100644
index 00000000000..8eebf8c2caf
--- /dev/null
+++ b/clients/java/sia/src/test/java/com/yahoo/athenz/sia/impl/SIAClientTest.java
@@ -0,0 +1,528 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.sia.impl;
+
+import java.io.File;
+import java.io.Writer;
+import java.io.OutputStreamWriter;
+import java.io.FileOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.token.PrincipalToken;
+import com.yahoo.athenz.sia.impl.SIAClient;
+
+public class SIAClientTest {
+
+ @Mock Socket mockSocket;
+
+ @BeforeClass
+ public void setUp() throws Exception {
+ System.setProperty(SIAClient.SIA_PROP_NTOKEN_PATH, "src/test/resources/svc.ntoken");
+ System.setProperty(SIAClient.SIA_PROP_NTOKEN_SERVICE, "storage");
+ System.setProperty(SIAClient.SIA_PROP_CFG_FILE, "src/test/resources/testcfg.conf");
+
+ MockitoAnnotations.initMocks(this);
+ prepareNtokenFile("_test");
+ }
+
+ // writes an ntoken to the configured ntoken path
+ void prepareNtokenFile(String pathSuffix) throws Exception {
+
+ // prepare the ntoken file
+ // ex: ntoken = "v=S1;d=athenz;n=storage;t=55555;e=57955;s=fake";
+ String ntoken_path = System.getProperty(SIAClient.SIA_PROP_NTOKEN_PATH);
+ ntoken_path = ntoken_path + pathSuffix;
+ Path path = Paths.get(ntoken_path);
+ String token = new String(Files.readAllBytes(path));
+ long curTimeSecs = System.currentTimeMillis() / 1000;
+ String curTime = Long.toString(curTimeSecs);
+ token = token.replaceFirst("55555", curTime);
+ curTimeSecs += 2400;
+ curTime = Long.toString(curTimeSecs);
+ token = token.replaceFirst("55555", curTime);
+
+ // write it to the configured ntoken file
+ ntoken_path = System.getProperty(SIAClient.SIA_PROP_NTOKEN_PATH);
+ File file = new File(ntoken_path);
+ file.createNewFile();
+ Writer fw = new OutputStreamWriter(new FileOutputStream(file));
+ fw.write(token + "\n");
+ fw.close();
+ }
+
+ @AfterMethod
+ public void cleanup() {
+ }
+
+ @Test
+ public void testIsExpiredTokenSmallerThanMin() {
+ SIAClient client = new SIAClient();
+ assertTrue(client.isExpiredToken(100, 200, null));
+ }
+
+ @Test
+ public void testIsExpiredTokenBiggerThanMax() {
+ SIAClient client = new SIAClient();
+ assertTrue(client.isExpiredToken(500, null, 300));
+ assertTrue(client.isExpiredToken(500, 200, 300));
+ }
+
+ @Test
+ public void testIsExpiredTokenAtLeastOneLimitIsNotNull() {
+ SIAClient client = new SIAClient();
+ assertFalse(client.isExpiredToken(500, null, 600));
+ assertFalse(client.isExpiredToken(500, 200, null));
+ assertFalse(client.isExpiredToken(500, 200, 501));
+ }
+
+ @Test
+ public void testIsExpiredTokenAtLeastBothLimitsNullSmallerThanMin() {
+ // the min is 1800
+ SIAClient client = new SIAClient();
+ assertTrue(client.isExpiredToken(1700, null, null));
+ }
+
+ @Test
+ public void testIsExpiredTokenAtLeastBothLimitsNullBiggerThanMin() {
+ // the min is 1800
+ SIAClient client = new SIAClient();
+ assertFalse(client.isExpiredToken(2100, null, null));
+ }
+
+ @Test
+ public void testGetPrincipalTokenCacheKey() {
+ SIAClient client = new SIAClient();
+ assertEquals(client.getPrincipalTokenCacheKey("coretech", "service"), "coretech.service");
+ assertEquals(client.getPrincipalTokenCacheKey(null, "service"), "null.service");
+ assertEquals(client.getPrincipalTokenCacheKey("coretech", null), "coretech.null");
+ }
+
+ @Test
+ public void testSiaSocketFile() {
+ SIAClient client = new SIAClient();
+ assertEquals(client.siaSocketFile(), "/home/athenz/var/run/sia/sia.ds");
+ }
+
+ @Test
+ public void testLookupPrincipalTokenInCacheNotPresent() {
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.notpresent";
+ assertNull(client.lookupPrincipalTokenInCache(cacheKey, null, null));
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testLookupPrincipalTokenInCacheExpired() {
+
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.storage";
+ PrincipalToken token = new PrincipalToken.Builder("S1", "coretech", "storage")
+ .issueTime((System.currentTimeMillis() / 1000)).expirationWindow(1000).build();
+ client.principalTokenCache.put(cacheKey, token);
+
+ assertNull(client.lookupPrincipalTokenInCache(cacheKey, 3000, 4000));
+ assertNull(client.lookupPrincipalTokenInCache(cacheKey, 500, 800));
+
+ client.principalTokenCache.clear();
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testLookupPrincipalTokenInCache() {
+
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.storage";
+ PrincipalToken token = new PrincipalToken.Builder("S1", "coretech", "storage")
+ .issueTime((System.currentTimeMillis() / 1000)).expirationWindow(3500).build();
+ client.principalTokenCache.put(cacheKey, token);
+
+ assertNotNull(client.lookupPrincipalTokenInCache(cacheKey, 3000, 4000));
+
+ client.principalTokenCache.clear();
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testLookupPrincipalTokenInCacheSecondClient() {
+
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.storage";
+ PrincipalToken token = new PrincipalToken.Builder("S1", "coretech", "storage")
+ .issueTime((System.currentTimeMillis() / 1000)).expirationWindow(3500).build();
+ client.principalTokenCache.put(cacheKey, token);
+
+ assertNotNull(client.lookupPrincipalTokenInCache(cacheKey, 3000, 4000));
+
+ // now let's get another client
+
+ SIAClient client1 = new SIAClient();
+ assertNotNull(client1.lookupPrincipalTokenInCache(cacheKey, 3000, 4000));
+
+ client.principalTokenCache.clear();
+ }
+
+ @Test
+ public void testProcessRequestDomainList() throws IOException {
+
+ ByteBuffer statusBuf = ByteBuffer.allocate(4);
+ statusBuf.order(ByteOrder.LITTLE_ENDIAN);
+ statusBuf.putInt(0);
+ byte[] status = statusBuf.array();
+
+ ByteBuffer sizeBuf = ByteBuffer.allocate(4);
+ sizeBuf.order(ByteOrder.LITTLE_ENDIAN);
+ sizeBuf.putInt(15);
+ byte[] size = sizeBuf.array();
+
+ byte[] list = "domain1,domain2".getBytes();
+
+ byte[] data = new byte[status.length + size.length + list.length];
+
+ System.arraycopy(status, 0, data, 0, status.length);
+ System.arraycopy(size, 0, data, status.length, size.length);
+ System.arraycopy(list, 0, data, status.length + size.length, list.length);
+
+ InputStream inputStream = new ByteArrayInputStream(data);
+ OutputStream outputStream = new ByteArrayOutputStream();
+
+ SIAClient mockSIAClient = Mockito.mock(SIAClient.class);
+ Mockito.when(mockSIAClient.getSIADomainSocket()).thenReturn(mockSocket);
+ Mockito.when(mockSocket.getInputStream()).thenReturn(inputStream);
+ Mockito.when(mockSocket.getOutputStream()).thenReturn(outputStream);
+
+ SIAClient siaClient = new SIAClient();
+ String domains = null;
+ try {
+ domains = siaClient.processRequest(mockSocket, SIAClient.OP_LIST_DOMAINS, null);
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail();
+ }
+ assertEquals(domains, "domain1,domain2");
+ }
+
+ @Test
+ public void testProcessRequestPrincipalToken() throws IOException {
+
+ ByteBuffer statusBuf = ByteBuffer.allocate(4);
+ statusBuf.order(ByteOrder.LITTLE_ENDIAN);
+ statusBuf.putInt(0);
+ byte[] status = statusBuf.array();
+
+ ByteBuffer sizeBuf = ByteBuffer.allocate(4);
+ sizeBuf.order(ByteOrder.LITTLE_ENDIAN);
+ sizeBuf.putInt(36);
+ byte[] size = sizeBuf.array();
+
+ byte[] token = "v=S1;d=coretech;n=storage;k=0;s=fake".getBytes();
+
+ byte[] data = new byte[status.length + size.length + token.length];
+
+ System.arraycopy(status, 0, data, 0, status.length);
+ System.arraycopy(size, 0, data, status.length, size.length);
+ System.arraycopy(token, 0, data, status.length + size.length, token.length);
+
+ InputStream inputStream = new ByteArrayInputStream(data);
+ OutputStream outputStream = new ByteArrayOutputStream();
+
+ SIAClient mockSIAClient = Mockito.mock(SIAClient.class);
+ Mockito.when(mockSIAClient.getSIADomainSocket()).thenReturn(mockSocket);
+ Mockito.when(mockSocket.getInputStream()).thenReturn(inputStream);
+ Mockito.when(mockSocket.getOutputStream()).thenReturn(outputStream);
+
+ SIAClient siaClient = new SIAClient();
+ String ntoken = null;
+ try {
+ ntoken = siaClient.processRequest(mockSocket, SIAClient.OP_GET_NTOKEN, "d=coretech,n=storage,e=1800".getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail();
+ }
+ assertEquals(ntoken, "v=S1;d=coretech;n=storage;k=0;s=fake");
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testGetServicePrincipal() throws IOException {
+
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.storage";
+ String nToken = "v=S1;d=coretech;n=storage;t=" + (System.currentTimeMillis() / 1000)
+ + ";e=" + ((System.currentTimeMillis() / 1000) + 3500) + ";k=0;s=fake";
+ PrincipalToken token = new PrincipalToken(nToken);
+ client.principalTokenCache.put(cacheKey, token);
+
+ Principal principal = client.getServicePrincipal("coretech", "storage", null, null, false);
+ assertNotNull(principal);
+ assertEquals(principal.getDomain(), "coretech");
+ assertEquals(principal.getName(), "storage");
+
+ client.principalTokenCache.clear();
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testGetServicePrincipalMixedCase() throws IOException {
+
+ SIAClient client = new SIAClient();
+
+ String cacheKey = "coretech.storage";
+ String nToken = "v=S1;d=coretech;n=storage;t=" + (System.currentTimeMillis() / 1000)
+ + ";e=" + ((System.currentTimeMillis() / 1000) + 3500) + ";k=0;s=fake";
+ PrincipalToken token = new PrincipalToken(nToken);
+ client.principalTokenCache.put(cacheKey, token);
+
+ Principal principal = client.getServicePrincipal("CoreTech", "Storage", null, null, false);
+ assertNotNull(principal);
+ assertEquals(principal.getDomain(), "coretech");
+ assertEquals(principal.getName(), "storage");
+
+ client.principalTokenCache.clear();
+ }
+
+ @Test (groups = "tokenfileA")
+ public void testGetServicePrincipalTokenFile() {
+ SIAClient client = new SIAClient();
+ String domain = "athenz";
+ String service = "storage";
+ // Configured service=athenz.storage
+ try {
+ client.getServicePrincipal(domain, service, 500, 3600, false);
+ } catch (java.io.IOException exc) {
+ fail("getServicePrincipal");
+ }
+ }
+
+ @Test (groups = "tokenfileA")
+ public void testGetServicePrincipalTokenFileWrongDomain() {
+ SIAClient client = new SIAClient();
+ String domain = "test.aaa";
+ String service = "storage";
+ String fullSvc = domain + "." + service;
+ // Configured service=athenz.storage
+ try {
+ client.getServicePrincipal(domain, service, 500, 3600, false);
+ fail("getServicePrincipal");
+ } catch (java.io.IOException exc) {
+ assertTrue(exc.getMessage().contains("get ntoken from file: Unknown service=" + fullSvc), exc.getMessage());
+ }
+ }
+
+ @Test (groups = "tokenfileA")
+ public void testGetServicePrincipalTokenFileWrongService() {
+ SIAClient client = new SIAClient();
+ String domain = "athenz";
+ String service = "destroyage";
+ String fullSvc = domain + "." + service;
+ // Configured service=athenz.storage
+ try {
+ client.getServicePrincipal(domain, service, 500, 3600, false);
+ fail("getServicePrincipal");
+ } catch (java.io.IOException exc) {
+ assertTrue(exc.getMessage().contains("get ntoken from file: Unknown service=" + fullSvc), exc.getMessage());
+ }
+ }
+
+ @Test (dependsOnGroups = "tokenfileA")
+ public void testGetServicePrincipalTokenFileEmptyConfigMissingDomainProperty() throws java.io.IOException {
+ System.setProperty(SIAClient.SIA_PROP_CFG_FILE, "src/test/resources/testcfg_empty.conf");
+ try {
+ SIAClient.initConfigVars();
+ SIAClient client = new SIAClient();
+ String domain = "athenz";
+ String service = "storage";
+ // Configured service=athenz.storage
+ client.getServicePrincipal(domain, service, 500, 3600, false);
+ fail("getServicePrincipal");
+ } catch (java.lang.IllegalArgumentException exc) {
+ assertTrue(exc.getMessage().contains("SIACLT: invalid ntoken configuration settings"), exc.getMessage());
+ }
+ }
+
+ @Test (dependsOnMethods={"testGetServicePrincipalTokenFileEmptyConfigMissingDomainProperty"})
+ public void testGetServicePrincipalTokenFileEmptyConfig() {
+ System.setProperty(SIAClient.SIA_PROP_NTOKEN_DOMAIN, "athenz");
+ System.setProperty(SIAClient.SIA_PROP_CFG_FILE, "src/test/resources/testcfg_empty.conf");
+ SIAClient.initConfigVars();
+ SIAClient client = new SIAClient();
+ String domain = "athenz";
+ String service = "storage";
+ // Configured service=athenz.storage
+ try {
+ client.getServicePrincipal(domain, service, 500, 3600, false);
+ } catch (java.io.IOException exc) {
+ fail("getServicePrincipal");
+ }
+ }
+
+ @Test
+ public void testTokenRequestBuilder() {
+ SIAClient client = new SIAClient();
+ assertEquals("d=test,s=db".getBytes(StandardCharsets.UTF_8), client.tokenRequestBuilder("test", "db", null));
+ assertEquals("d=test,s=db,e=100".getBytes(StandardCharsets.UTF_8), client.tokenRequestBuilder("test", "db", new Integer(100)));
+ assertEquals("d=null,s=db,e=100".getBytes(StandardCharsets.UTF_8), client.tokenRequestBuilder(null, "db", new Integer(100)));
+ assertEquals("d=test,s=null,e=100".getBytes(StandardCharsets.UTF_8), client.tokenRequestBuilder("test", null, new Integer(100)));
+ assertEquals("d=null,s=null,e=100".getBytes(StandardCharsets.UTF_8), client.tokenRequestBuilder(null, null, new Integer(100)));
+ }
+
+ private class SIATestClient extends SIAClient {
+
+ @Override
+ Socket getSIADomainSocket() throws IOException {
+ return null;
+ }
+
+ @Override
+ String processRequest(Socket sock, int sia_op, byte[] data) throws IOException {
+ String result = null;
+ switch (sia_op) {
+ case SIAClient.OP_LIST_DOMAINS:
+ result = "test;hoge;athenz";
+ break;
+ case SIAClient.OP_GET_NTOKEN:
+ result = "v=S1;d=coretech;n=storage;k=0;s=fake";
+ break;
+ }
+ return result;
+ }
+ }
+
+ @Test
+ public void testGetServicePrincipalNullExpiry() throws IOException {
+
+ // we need to make sure not to use our ntoken path which doesn't
+ // call the expected get service principal api. so we're going
+ // to save the value and and then restore it after the test case
+
+ String ntoken_path = SIAClient.cfgNtokenPath;
+ SIAClient.cfgNtokenPath = null;
+
+ SIAClient client = new SIATestClient();
+
+ Principal principal = client.getServicePrincipal("coretech", "storage", 500, null, false);
+ assertNotNull(principal);
+ assertEquals(principal.getDomain(), "coretech");
+ assertEquals(principal.getName(), "storage");
+
+ // restore the property
+
+ SIAClient.cfgNtokenPath = ntoken_path;
+ }
+
+ @Test
+ public void testGetDomainList() throws IOException {
+ SIAClient client = new SIATestClient();
+ ArrayList result = client.getDomainList();
+ assertNotNull(result);
+ assertEquals(result.toString(), "[test, hoge, athenz]");
+ }
+
+ @Test
+ public void testGetServicePrincipalException() throws Exception {
+ SIAClient client = new SIATestClient();
+
+ try {
+ client.getServicePrincipal(null, null, 0, 3600, true);
+ fail();
+ } catch (IOException e) {
+ }
+
+ SIATestClient.cfgNtokenPath = null;
+ Principal p = client.getServicePrincipal("test", "hoge", 0, 3600, true);
+
+ assertNotNull(p);
+ assertEquals(p.getDomain(), "test");
+ assertEquals(p.getName(), "hoge");
+
+ SIATestClient.cfgNtokenPath = "src/test/resources/svc.ntoken";
+ }
+
+ @Test
+ public void testGetFilePrincipalTokenIlligalFile() throws IOException{
+ SIAClient client = new SIATestClient();
+
+ SIATestClient.cfgNtokenPath = "src/test/resources/dummy.ntoken";
+ String s = client.getFilePrincipalToken("athenz", "storage");
+
+ assertEquals(s, "");
+ }
+
+ @Test
+ public void testReadResponseData() throws IOException {
+ SIAClient client = new SIATestClient();
+
+ byte[] dummy = { (byte) 0x47, (byte) 0x4e, (byte) 0x54, (byte) 0x2d, (byte) 0x30, (byte) 0x30, (byte) 0x30,
+ (byte) 0x30 };
+ InputStream is = Mockito.mock(InputStream.class);
+
+ Mockito.when(is.read(dummy, 0, dummy.length)).thenReturn(1);
+ Mockito.when(is.read(dummy, 1, dummy.length - 1)).thenReturn(-1);
+
+ int check = client.readResponseData(is, dummy);
+ assertEquals(check, 1);
+
+ Mockito.when(is.read(dummy, 0, dummy.length)).thenReturn(-1);
+
+ check = client.readResponseData(is, dummy);
+ assertEquals(check, 0);
+ }
+
+ @Test
+ public void testInitConfigVarsIlligalCFGflag() throws Exception {
+
+ System.clearProperty(SIAClient.SIA_PROP_CFG_FILE);
+
+ SIAClient.initConfigVars();
+ assertNull(SIATestClient.cfgNtokenPath);
+ assertNull(SIATestClient.cfgNtokenDomain);
+ assertNull(SIATestClient.cfgNtokenService);
+ }
+
+ @Test
+ public void testSetConfigVarsIlligal() throws Exception {
+
+ SIAClient.setupConfigVars(null, null, null);
+ assertNull(SIATestClient.cfgNtokenDomain);
+ assertNull(SIATestClient.cfgNtokenService);
+ }
+}
diff --git a/clients/java/sia/src/test/resources/dummy.ntoken b/clients/java/sia/src/test/resources/dummy.ntoken
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/clients/java/sia/src/test/resources/logback.xml b/clients/java/sia/src/test/resources/logback.xml
new file mode 100644
index 00000000000..2ce05abfc06
--- /dev/null
+++ b/clients/java/sia/src/test/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ System.out
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %class - %msg%n
+
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/sia/src/test/resources/svc.ntoken_test b/clients/java/sia/src/test/resources/svc.ntoken_test
new file mode 100644
index 00000000000..fae27937dd9
--- /dev/null
+++ b/clients/java/sia/src/test/resources/svc.ntoken_test
@@ -0,0 +1 @@
+v=S1;d=athenz;n=storage;t=55555;e=55555;s=fake
diff --git a/clients/java/sia/src/test/resources/testcfg.conf b/clients/java/sia/src/test/resources/testcfg.conf
new file mode 100644
index 00000000000..e2f1d311202
--- /dev/null
+++ b/clients/java/sia/src/test/resources/testcfg.conf
@@ -0,0 +1,6 @@
+{
+ "ntoken_path": "/map/to/the/stars",
+ "ntoken_domain": "athenz",
+ "ntoken_service": "how_much_to_tip"
+}
+
diff --git a/clients/java/sia/src/test/resources/testcfg_empty.conf b/clients/java/sia/src/test/resources/testcfg_empty.conf
new file mode 100644
index 00000000000..b23ba173dfd
--- /dev/null
+++ b/clients/java/sia/src/test/resources/testcfg_empty.conf
@@ -0,0 +1,6 @@
+{
+ "ntoken_path": "",
+ "ntoken_domain": "",
+ "ntoken_service": ""
+}
+
diff --git a/clients/java/zms/README.md b/clients/java/zms/README.md
new file mode 100644
index 00000000000..7f438730bc9
--- /dev/null
+++ b/clients/java/zms/README.md
@@ -0,0 +1,23 @@
+zms-java-client
+===============
+
+A Java client library to access the ZMS server.
+The client library encapsulates the stub generated from the ZMS RDL.
+It includes zms-core and all other dependencies.
+
+--- Connection Timeouts ---
+
+Default read and connect timeout values for ZMS Client connections
+are 30000ms (30sec). The application can change these values by using
+the following system properties:
+
+ * athenz.zms.client.read_timeout
+ * athenz.zms.client.connect_timeout
+
+The values specified for timeouts must be in milliseconds.
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
diff --git a/clients/java/zms/pom.xml b/clients/java/zms/pom.xml
new file mode 100644
index 00000000000..fe6730a43c2
--- /dev/null
+++ b/clients/java/zms/pom.xml
@@ -0,0 +1,227 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+ zms_java_client
+ jar
+ zms-java-client
+ ZMS Java Client Library
+
+
+
+ ${project.groupId}
+ zms_core
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ client_common
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ auth_core
+ ${project.parent.version}
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-jackson
+ ${jersey.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.1.1
+
+
+
+ exec
+
+ generate-sources
+
+
+
+ bash
+
+ scripts/make_stubs.sh
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+
+ prepare-package
+
+ jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
+
+ package
+
+ shade
+
+
+
+
+
+
+ org.glassfish.hk2
+ org.glassfish.hk2.external
+ org.glassfish.jersey
+ org.glassfish.jersey.ext
+ org.glassfish.jersey.core
+ org.glassfish.jersey.media
+ org.glassfish.jersey.bundles.repackaged
+ com.fasterxml.jackson.core
+ com.fasterxml.jackson.jaxrs
+ com.fasterxml.jackson.module
+ javax.ws.rs
+ javax.annotation
+ javax.inject
+ jersey.repackaged.com.google.common
+ org.aopalliance
+
+
+
+
+ javax.inject
+ athenz.shade.zms.javax.inject
+
+
+ org.aopalliance
+ athenz.shade.zms.org.aopalliance
+
+
+ jersey.repackaged.com.google.common
+ athenz.shade.zms.jersey.repackaged.com.google.common
+
+
+ javax.ws.rs
+ athenz.shade.zms.javax.ws.rs
+
+
+ javax.annotation
+ athenz.shade.zms.javax.annotation
+
+
+ org.glassfish.jersey
+ athenz.shade.zms.org.glassfish.jersey
+
+
+ org.glassfish.hk2
+ athenz.shade.zms.org.glassfish.hk2
+
+
+ org.glassfish.hk2.external
+ athenz.shade.zms.org.glassfish.hk2.external
+
+
+ org.jvnet.hk2
+ athenz.shade.zms.org.jvnet.hk2
+
+
+ org.jvnet.tiger_types
+ athenz.shade.zms.org.jvnet.tiger_types
+
+
+ com.fasterxml.jackson
+ athenz.shade.zms.com.fasterxml.jackson
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+
+
+ coverage
+
+
+
+
+
+ com.atlassian.maven.plugins
+ maven-clover2-plugin
+ 4.0.4
+
+ 1.8
+ ${HOME}/license/clover.license
+
+
+ **/ZMSRDLGeneratedClient.java
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/zms/scripts/make_stubs.sh b/clients/java/zms/scripts/make_stubs.sh
new file mode 100755
index 00000000000..969f6049a07
--- /dev/null
+++ b/clients/java/zms/scripts/make_stubs.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# If the zms_core dependency has been updated, then this script should be run
+# manually to pick up the latest rdl to generate the appropriate client library
+
+# Note this script is dependent on the rdl utility.
+# go get github.com/ardielle/ardielle-tools/...
+
+command -v rdl >/dev/null 2>&1 || {
+ echo >&2 "------------------------------------------------------------------------";
+ echo >&2 "SOURCE WARNING";
+ echo >&2 "------------------------------------------------------------------------";
+ echo >&2 "Please install rdl utility: go get github.com/ardielle/ardielle-tools/...";
+ echo >&2 "Skipping source generation...";
+ exit 0;
+}
+
+RDL_FILE=../../../core/zms/src/main/rdl/ZMS.rdl
+
+echo "Generate the client library..."
+rdl -s generate -o src/main/java -x clientclass=ZMSRDLGenerated java-client $RDL_FILE
+
+# Copyright 2016 Yahoo Inc.
+# Licensed under the terms of the Apache version 2.0 license. See LICENSE file for terms.
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceError.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceError.java
new file mode 100644
index 00000000000..231c7abdf9d
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceError.java
@@ -0,0 +1,24 @@
+//
+// This file generated by rdl 1.4.8. Do not modify!
+//
+package com.yahoo.athenz.zms;
+
+public class ResourceError {
+
+ public int code;
+ public String message;
+
+ public ResourceError code(int code) {
+ this.code = code;
+ return this;
+ }
+ public ResourceError message(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public String toString() {
+ return "{code: " + code + ", message: \"" + message + "\"}";
+ }
+
+}
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceException.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceException.java
new file mode 100644
index 00000000000..a76e476ac22
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ResourceException.java
@@ -0,0 +1,79 @@
+//
+// This file generated by rdl 1.4.8. Do not modify!
+//
+package com.yahoo.athenz.zms;
+
+public class ResourceException extends RuntimeException {
+ public final static int OK = 200;
+ public final static int CREATED = 201;
+ public final static int ACCEPTED = 202;
+ public final static int NO_CONTENT = 204;
+ public final static int MOVED_PERMANENTLY = 301;
+ public final static int FOUND = 302;
+ public final static int SEE_OTHER = 303;
+ public final static int NOT_MODIFIED = 304;
+ public final static int TEMPORARY_REDIRECT = 307;
+ public final static int BAD_REQUEST = 400;
+ public final static int UNAUTHORIZED = 401;
+ public final static int FORBIDDEN = 403;
+ public final static int NOT_FOUND = 404;
+ public final static int CONFLICT = 409;
+ public final static int GONE = 410;
+ public final static int PRECONDITION_FAILED = 412;
+ public final static int UNSUPPORTED_MEDIA_TYPE = 415;
+ public final static int INTERNAL_SERVER_ERROR = 500;
+ public final static int NOT_IMPLEMENTED = 501;
+
+ public final static int SERVICE_UNAVAILABLE = 503;
+
+ public static String codeToString(int code) {
+ switch (code) {
+ case OK: return "OK";
+ case CREATED: return "Created";
+ case ACCEPTED: return "Accepted";
+ case NO_CONTENT: return "No Content";
+ case MOVED_PERMANENTLY: return "Moved Permanently";
+ case FOUND: return "Found";
+ case SEE_OTHER: return "See Other";
+ case NOT_MODIFIED: return "Not Modified";
+ case TEMPORARY_REDIRECT: return "Temporary Redirect";
+ case BAD_REQUEST: return "Bad Request";
+ case UNAUTHORIZED: return "Unauthorized";
+ case FORBIDDEN: return "Forbidden";
+ case NOT_FOUND: return "Not Found";
+ case CONFLICT: return "Conflict";
+ case GONE: return "Gone";
+ case PRECONDITION_FAILED: return "Precondition Failed";
+ case UNSUPPORTED_MEDIA_TYPE: return "Unsupported Media Type";
+ case INTERNAL_SERVER_ERROR: return "Internal Server Error";
+ case NOT_IMPLEMENTED: return "Not Implemented";
+ default: return "" + code;
+ }
+ }
+
+ int code;
+ Object data;
+
+ public ResourceException(int code) {
+ this(code, new ResourceError().code(code).message(codeToString(code)));
+ }
+
+ public ResourceException(int code, Object data) {
+ super("ResourceException (" + code + "): " + data);
+ this.code = code;
+ this.data = data;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public T getData(Class cl) {
+ return cl.cast(data);
+ }
+
+}
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSAuthorizer.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSAuthorizer.java
new file mode 100644
index 00000000000..c503167f969
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSAuthorizer.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import java.io.Closeable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.Authorizer;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.PrincipalAuthority;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+import com.yahoo.athenz.auth.token.PrincipalToken;
+
+public class ZMSAuthorizer implements Authorizer, Closeable {
+
+ String endpoint = null;
+ String serviceDomain = null;
+ protected ZMSClient client = null;
+ private static final Logger LOGGER = LoggerFactory.getLogger(ZMSAuthorizer.class);
+ private static final PrincipalAuthority PRINCIPAL_AUTHORITY = new PrincipalAuthority();
+
+ /**
+ * Constructs a new ZMSAuthorizer object with the given resource service domain
+ * name. The url for ZMS Server is automatically retrieved from the athenz
+ * configuration file (zms_url field).
+ * @param serviceDomain resource service domain name
+ */
+ public ZMSAuthorizer(String serviceDomain) {
+ this(null, serviceDomain);
+ }
+
+ /**
+ * Constructs a new ZMSAuthorizer object with the given ZMS Server endpoint and
+ * given resource service domain name
+ * @param endpoint ZMS Server url (e.g. http://server.athenzcompany.com:4443/zms/v1)
+ * @param serviceDomain resource service domain name
+ */
+ public ZMSAuthorizer(String endpoint, String serviceDomain) {
+ this.endpoint = endpoint;
+ this.serviceDomain = serviceDomain;
+ client = new ZMSClient(this.endpoint);
+ }
+
+ /**
+ * Close the ZMS Client object
+ */
+ public void close() {
+ if (client != null) {
+ client.close();
+ client = null;
+ }
+ }
+
+ /**
+ * Set the authorizer to use the specified zms client object
+ * @param client ZMSClient object to use for authorization checks
+ */
+ public void setZMSClient(ZMSClient client) {
+ // if we already have a client then we need to close it
+ close();
+ this.client = client;
+ }
+
+ /**
+ * Requests the ZMS to indicate whether or not the specific request for the
+ * specified resource with authentication details will be granted or not.
+ * @param action value of the action to be carried out (e.g. "UPDATE", "DELETE")
+ * @param resource resource value
+ * @param principalToken principal token (NToken) that will be authenticated and checked for
+ * requested access
+ * @param trustDomain (optional - usually null) if the access checks involves cross
+ * domain check only check the specified trusted domain and ignore all others
+ * @return boolean indicating whether or not the request will be granted or not
+ */
+ public boolean access(String action, String resource, String principalToken, String trustDomain) {
+ PrincipalToken token = new PrincipalToken(principalToken);
+ Principal principal = SimplePrincipal.create(token.getDomain(), token.getName(),
+ token.getSignedToken(), 0, PRINCIPAL_AUTHORITY);
+ return access(action, resource, principal, trustDomain);
+ }
+
+ /**
+ * Requests the ZMS to indicate whether or not the specific request for the
+ * specified resource with authentication details will be granted or not.
+ * @param action value of the action to be carried out (e.g. "UPDATE", "DELETE")
+ * @param resource resource value
+ * @param principal principal object that will be authenticated and checked for
+ * requested access
+ * @param trustDomain (optional - usually null) if the access checks involves cross
+ * domain check only check the specified trusted domain and ignore all others
+ * @return boolean indicating whether or not the request will be granted or not
+ */
+ public boolean access(String action, String resource, Principal principal, String trustDomain) {
+
+ //the "resource" may be an entity name here, we need a full resource name
+
+ String rn = (resource.contains(":")) ? resource : serviceDomain + ":" + resource;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("ZMSAuthorizer.access(" + action + ", " + rn + ", " + principal.getYRN()
+ + ", " + trustDomain + ")");
+ }
+
+ try {
+ client.addCredentials(principal);
+ return client.getAccess(action, rn, trustDomain).getGranted();
+ } catch (ZMSClientException e) {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("ZMSAuthorizer.access: " + e);
+ }
+
+ switch (e.getCode()) {
+ case ZMSClientException.NOT_FOUND:
+ throw new ZMSClientException(ZMSClientException.FORBIDDEN, "Not found: " + rn);
+ default:
+ throw e;
+ }
+ } catch (Throwable th) {
+ th.printStackTrace();
+ throw new ZMSClientException(ZMSClientException.FORBIDDEN, "Cannot contact ZMS");
+ }
+ }
+}
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClient.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClient.java
new file mode 100644
index 00000000000..18c29015e0c
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClient.java
@@ -0,0 +1,1691 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.io.Closeable;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Map;
+import java.util.List;
+import java.util.Date;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.Authority;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.PrincipalAuthority;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+import com.yahoo.athenz.auth.token.PrincipalToken;
+import com.yahoo.athenz.common.config.AthenzConfig;
+import com.yahoo.rdl.JSON;
+
+public class ZMSClient implements Closeable {
+
+ private String zmsUrl = null;
+ private Principal principal = null;
+ private boolean principalCheckDone = false;
+ protected ZMSRDLGeneratedClient client = null;
+
+ private static final String STR_ENV_ROOT = "ROOT";
+ private static final String STR_DEF_ROOT = "/home/athenz";
+ private static final String HTTP_RFC1123_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss zzz";
+
+ public static final String ZMS_CLIENT_PROP_ATHENZ_CONF = "athenz.athenz_conf";
+ public static final String ZMS_CLIENT_PROP_READ_TIMEOUT = "athenz.zms.client.read_timeout";
+ public static final String ZMS_CLIENT_PROP_CONNECT_TIMEOUT = "athenz.zms.client.connect_timeout";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ZMSClient.class);
+ private static final Authority PRINCIPAL_AUTHORITY = new com.yahoo.athenz.auth.impl.PrincipalAuthority();
+
+ /**
+ * Constructs a new ZMSClient object with media type set to application/json.
+ * The url for ZMS Server is automatically retrieved from the athenz_config
+ * package's configuration file (zms_url field). The client can only be used
+ * to retrieve objects from ZMS that do not require any authentication
+ * otherwise addCredentials method must be used to set the principal identity.
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zms_java_client.read_timeout and
+ * yahoo.zms_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ */
+ public ZMSClient() {
+ initClient(null);
+ }
+
+ /**
+ * Constructs a new ZMSClient object with the given ZMS Server url and
+ * media type set to application/json. The client can only be used
+ * to retrieve objects from ZMS that do not require any authentication
+ * otherwise addCredentials method must be used to set the principal identity.
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zms_java_client.read_timeout and
+ * yahoo.zms_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ * @param url ZMS Server url (e.g. https://server1.athenzcompany.com:4443/zms/v1)
+ */
+ public ZMSClient(String url) {
+ initClient(url);
+ }
+
+ /**
+ * Close the ZMSClient object and release any allocated resources.
+ */
+ public void close() {
+ client.close();
+ }
+
+ public void setZMSRDLGeneratedClient(ZMSRDLGeneratedClient client) {
+ this.client = client;
+ }
+
+ /**
+ * Sets or overrides the current principal identity set in the client.
+ * @param identity Principal identity for authenticating requests
+ * @return self ZMSClient object
+ */
+ public ZMSClient addCredentials(Principal identity) {
+
+ // make sure the principal has proper authority assigned
+
+ if (identity == null || identity.getAuthority() == null) {
+ throw new IllegalArgumentException("Principal must be valid object with authority field");
+ }
+
+ // if we already have a principal set, we're going to
+ // clear our credentials first
+
+ if (principal != null) {
+ client.addCredentials(principal.getAuthority().getHeader(), null);
+ }
+
+ // now we're going to update our principal and set credentials
+
+ principal = identity;
+ principalCheckDone = false;
+
+ final Authority authority = principal.getAuthority();
+ if (authority != null) {
+ client.addCredentials(authority.getHeader(), principal.getCredentials());
+
+ // finally check if we this is a principal token required by ZMS
+
+ principalCheckDone = (authority instanceof PrincipalAuthority);
+ }
+
+ return this;
+ }
+
+ /**
+ * Clear the principal identity set for the client. Unless a new principal is set
+ * using the addCredentials method, the client can only be used to requests data
+ * from the ZMS Server that doesn't require any authentication.
+ * @return self ZMSClient object
+ */
+ public ZMSClient clearCredentials() {
+ if (principal != null) {
+ client.addCredentials(principal.getAuthority().getHeader(), null);
+ principal = null;
+ principalCheckDone = true;
+ }
+ return this;
+ }
+
+ /**
+ * If the current principal is the user principal then request
+ * a UserToken from ZMS and set the UserToken as the principal
+ * identity for authentication.
+ */
+ private void updatePrincipal() {
+
+ /* if the check has already been done then we have nothing to do */
+
+ if (principalCheckDone) {
+ return;
+ }
+
+ /* make sure we have a principal specified */
+
+ if (principal == null) {
+ principalCheckDone = true;
+ return;
+ }
+
+ /* so at this point we have some credentials specified
+ * but it's not the principal authority so we're going
+ * to ask ZMS to return a UserToken for us.
+ */
+
+ String userName = principal.getName();
+ long issueTime = principal.getIssueTime();
+ UserToken userToken = getUserToken(userName);
+
+ PrincipalToken principalToken = new PrincipalToken(userToken.getToken());
+ Principal identity = SimplePrincipal.create(principalToken.getDomain(),
+ principalToken.getName(), userToken.getToken(), issueTime,
+ PRINCIPAL_AUTHORITY);
+ clearCredentials();
+ addCredentials(identity);
+ }
+
+ String lookupZMSUrl() {
+
+ String rootDir = System.getenv(STR_ENV_ROOT);
+ if (rootDir == null) {
+ rootDir = STR_DEF_ROOT;
+ }
+
+ String confFileName = System.getProperty(ZMS_CLIENT_PROP_ATHENZ_CONF,
+ rootDir + "/conf/athenz/athenz.conf");
+ String url = null;
+ try {
+ Path path = Paths.get(confFileName);
+ AthenzConfig conf = JSON.fromBytes(Files.readAllBytes(path), AthenzConfig.class);
+ url = conf.getZmsUrl();
+ } catch (Exception ex) {
+ LOGGER.error("Unable to extract ZMS Url from {} exc: {}",
+ confFileName, ex.getMessage());
+ }
+
+ return url;
+ }
+ /**
+ * Initialize the client for class constructors
+ * @param url ZMS Server url
+ * @param identity Principal identity for authentication
+ * @param mediaType media type for http content type
+ */
+ private void initClient(String url) {
+
+ /* if we have no url specified then we're going to retrieve
+ * the value from our configuration package */
+
+ if (url == null) {
+ zmsUrl = lookupZMSUrl();
+ } else {
+ zmsUrl = url;
+ }
+
+ /* verify if the url is ending with /zms/v1 and if it's
+ * not we'll automatically append it */
+
+ if (zmsUrl != null && !zmsUrl.isEmpty()) {
+ if (!zmsUrl.endsWith("/zms/v1")) {
+ if (zmsUrl.charAt(zmsUrl.length() - 1) != '/') {
+ zmsUrl += '/';
+ }
+ zmsUrl += "zms/v1";
+ }
+ }
+
+ /* determine our read and connect timeouts */
+
+ int readTimeout = Integer.parseInt(System.getProperty(ZMS_CLIENT_PROP_READ_TIMEOUT, "30000"));
+ int connectTimeout = Integer.parseInt(System.getProperty(ZMS_CLIENT_PROP_CONNECT_TIMEOUT, "30000"));
+
+ /* if we are not given a url then use the default value */
+
+ client = new ZMSRDLGeneratedClient(zmsUrl)
+ .setProperty(ClientProperties.CONNECT_TIMEOUT, connectTimeout)
+ .setProperty(ClientProperties.READ_TIMEOUT, readTimeout);
+ }
+
+ public String getZmsUrl() {
+ return zmsUrl;
+ }
+
+ /**
+ * Generate a role name as expected by ZMS Server can be used to
+ * set the role object's name field (e.g. role.setName(name))
+ * @param domain name of the domain
+ * @param role name of the role
+ * @return full role name
+ */
+ public String generateRoleName(String domain, String role) {
+ StringBuilder str = new StringBuilder(256);
+ str.append(domain);
+ str.append(":role.");
+ str.append(role);
+ return str.toString();
+ }
+
+ /**
+ * Generate a policy name as expected by ZMS Server can be used to
+ * set the policy object's name field (e.g. policy.setName(name))
+ * @param domain name of the domain
+ * @param policy name of the policy
+ * @return full policy name
+ */
+ public String generatePolicyName(String domain, String policy) {
+ StringBuilder str = new StringBuilder(256);
+ str.append(domain);
+ str.append(":policy.");
+ str.append(policy);
+ return str.toString();
+ }
+
+ /**
+ * Generate a service name as expected by ZMS Server can be used to
+ * set the service identity object's name field
+ * (e.g. serviceIdentity.setName(name))
+ * @param domain name of the domain
+ * @param service name of the service
+ * @return full service identity name
+ */
+ public String generateServiceIdentityName(String domain, String service) {
+ StringBuilder str = new StringBuilder(256);
+ str.append(domain);
+ str.append(".");
+ str.append(service);
+ return str.toString();
+ }
+
+ /**
+ * Retrieve the specified domain object
+ * @param domain name of the domain to be retrieved
+ * @return Domain object or ZMSClientException will be thrown in case of failure
+ */
+ public Domain getDomain(String domain) {
+ updatePrincipal();
+ try {
+ return client.getDomain(domain);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of domains provisioned on the ZMS Server
+ * @return list of Domains or ZMSClientException will be thrown in case of failure
+ */
+ public DomainList getDomainList() {
+ return getDomainList(null, null, null, null, null, null, null);
+ }
+
+ /**
+ * Retrieve the list of domains provisioned on the ZMS Server
+ * filters based on the specified arguments
+ * @param limit number of domain objects to return
+ * @param skip exclude all the domains including the specified one from the return set
+ * @param prefix return domains starting with this value
+ * @param depth maximum depth of the domain (0 - top level domains only)
+ * @param account return domain that has the specified account name. If account name
+ * is specified all other optional attributes are ignored since there must be
+ * only one domain matching the specified account name.
+ * @param productId return domain that has the specified product id. If product id
+ * is specified all other optional attributes are ignored since there must be
+ * only one domain matching the specified product id.
+ * @param modifiedSince return domains only modified since this date
+ * @return list of domain names or ZMSClientException will be thrown in case of failure
+ */
+ public DomainList getDomainList(Integer limit, String skip, String prefix, Integer depth,
+ String account, Integer productId, Date modifiedSince) {
+ updatePrincipal();
+ String modSinceStr = null;
+ if (modifiedSince != null) {
+ DateFormat df = new SimpleDateFormat(HTTP_RFC1123_DATE_FORMAT);
+ modSinceStr = df.format(modifiedSince);
+ }
+ try {
+ return client.getDomainList(limit, skip, prefix, depth, account, productId, null, null, modSinceStr);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of domains provisioned on the ZMS Server
+ * filters based on the specified arguments
+ * @param roleMember name of the principal
+ * @param roleName name of the role where the principal is a member of
+ * @return list of domain names or ZMSClientException will be thrown in case of failure
+ */
+ public DomainList getDomainList(String roleMember, String roleName) {
+ updatePrincipal();
+ try {
+ return client.getDomainList(null, null, null, null, null, null, roleMember, roleName, null);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/Update Top level domain. If updating a domain the provided
+ * object must contain all attributes as it will replace the full domain
+ * object configured on the server (not just some of the attributes).
+ * @param auditRef string containing audit specification or ticket number
+ * @param detail TopLevelDomain object to be created in ZMS
+ * @return created Domain object or ZMSClientException will be thrown in case of failure
+ */
+ public Domain postTopLevelDomain(String auditRef, TopLevelDomain detail) {
+ updatePrincipal();
+ try {
+ return client.postTopLevelDomain(auditRef, detail);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/Update a sub-domain in the specified domain. If updating a
+ * subdomain the provided object must contain all attributes as it will
+ * replace the full domain object configured on the server (not just some
+ * of the attributes).
+ * @param parent name of the parent domain
+ * @param auditRef string containing audit specification or ticket number
+ * @param detail SubDomain object to be created in ZMS
+ * @return created Domain object or ZMSClientException will be thrown in case of failure
+ */
+ public Domain postSubDomain(String parent, String auditRef, SubDomain detail) {
+ updatePrincipal();
+ try {
+ return client.postSubDomain(parent, auditRef, detail);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create a top-level user-domain - this is user.<userid> domain.
+ * @param name domain to be created, this is the <userid>
+ * @param auditRef string containing audit specification or ticket number
+ * @param detail UserDomain object to be created in ZMS
+ * @return created Domain object or ZMSClientException will be thrown in case of failure
+ */
+ public Domain postUserDomain(String name, String auditRef, UserDomain detail) {
+ updatePrincipal();
+ try {
+ return client.postUserDomain(name, auditRef, detail);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete a top level domain
+ * @param name domain name to be deleted from ZMS
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteTopLevelDomain(String name, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteTopLevelDomain(name, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete a sub-domain
+ * @param parent name of the parent domain
+ * @param name sub-domain to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteSubDomain(String parent, String name, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteSubDomain(parent, name, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete a top-level user-domain (user.<userid>)
+ * @param name domain to be deleted, this is the <userid>
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteUserDomain(String name, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteUserDomain(name, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Set the domain meta parameters
+ * @param name domain name to be modified
+ * @param auditRef string containing audit specification or ticket number
+ * @param detail meta parameters to be set on the domain
+ */
+ public void putDomainMeta(String name, String auditRef, DomainMeta detail) {
+ updatePrincipal();
+ try {
+ client.putDomainMeta(name, auditRef, detail);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of roles defined for the specified domain
+ * @param domainName name of the domain
+ * @return list of role names or ZMSClientException will be thrown in case of failure
+ */
+ public RoleList getRoleList(String domainName) {
+ updatePrincipal();
+ try {
+ return client.getRoleList(domainName, null, null);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of roles defined for the specified domain
+ * filtered based on the parameters specified
+ * @param domainName name of the domain
+ * @param limit number of roles to return
+ * @param skip exclude all the roles including the specified one from the return set
+ * @return list of role names or ZMSClientException will be thrown in case of failure
+ */
+ public RoleList getRoleList(String domainName, Integer limit, String skip) {
+ updatePrincipal();
+ try {
+ return client.getRoleList(domainName, limit, skip);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of roles defined for the specified domain. The roles
+ * will contain their attributes and, if specified, the list of members.
+ * @param domainName name of the domain
+ * @param members include all members for group roles as well
+ * @return list of roles or ZMSClientException will be thrown in case of failure
+ */
+ public Roles getRoles(String domainName, Boolean members) {
+ updatePrincipal();
+ try {
+ return client.getRoles(domainName, members);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified role
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @return role object or ZMSClientException will be thrown in case of failure
+ */
+ public Role getRole(String domainName, String roleName) {
+ return getRole(domainName, roleName, false, false);
+ }
+
+ /**
+ * Retrieve the specified role
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param auditLog include audit log for the role changes in the response
+ * @return role object or ZMSClientException will be thrown in case of failure
+ */
+ public Role getRole(String domainName, String roleName, boolean auditLog) {
+ return getRole(domainName, roleName, auditLog, false);
+ }
+
+
+ /**
+ * Retrieve the specified role
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param auditLog include audit log for the role changes in the response
+ * @param expand if the requested role is a delegated/trust role, this flag
+ * will instruct the ZMS server to automatically retrieve the members of the
+ * role from the delegated domain and return as part of the role object
+ * @return role object or ZMSClientException will be thrown in case of failure
+ */
+ public Role getRole(String domainName, String roleName, boolean auditLog, boolean expand) {
+ updatePrincipal();
+ try {
+ return client.getRole(domainName, roleName, auditLog, expand);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/Update a new role in the specified domain. If updating a role
+ * the provided object must contain all attributes as it will replace
+ * the full role object configured on the server (not just some of the attributes).
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param auditRef string containing audit specification or ticket number
+ * @param role role object to be added to the domain
+ */
+ public void putRole(String domainName, String roleName, String auditRef, Role role) {
+ updatePrincipal();
+ try {
+ client.putRole(domainName, roleName, auditRef, role);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified role from domain
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteRole(String domainName, String roleName, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteRole(domainName, roleName, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Get membership details for the specified member in the given role
+ * in a specified domain
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param memberName name of the member
+ * @return Membership object or ZMSClientException will be thrown in case of failure
+ */
+ public Membership getMembership(String domainName, String roleName, String memberName) {
+ updatePrincipal();
+ try {
+ return client.getMembership(domainName, roleName, memberName);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Add a new member in the specified role.
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param memberName name of the member to be added
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void putMembership(String domainName, String roleName, String memberName, String auditRef) {
+ updatePrincipal();
+ Membership mbr = new Membership();
+ mbr.setRoleName(roleName);
+ mbr.setMemberName(memberName);
+ mbr.setIsMember(true);
+ try {
+ client.putMembership(domainName, roleName, memberName, auditRef, mbr);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Remove the specified member from the role
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param memberName name of the member to be removed
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteMembership(String domainName, String roleName, String memberName, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteMembership(domainName, roleName, memberName, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of policies defined for the specified domain. The policies
+ * will contain their attributes and, if specified, the list of assertions.
+ * @param domainName name of the domain
+ * @param assertions include all assertion for policies as well
+ * @return list of policies or ZMSClientException will be thrown in case of failure
+ */
+ public Policies getPolicies(String domainName, Boolean assertions) {
+ updatePrincipal();
+ try {
+ return client.getPolicies(domainName, assertions);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Get list of policies defined in the specified domain
+ * @param domainName name of the domain
+ * @return list of policy names or ZMSClientException will be thrown in case of failure
+ */
+ public PolicyList getPolicyList(String domainName) {
+ updatePrincipal();
+ try {
+ return client.getPolicyList(domainName, null, null);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Get list of policies defined in the specified domain filtered
+ * based on the specified arguments
+ * @param domainName name of the domain
+ * @param limit number of policies to return
+ * @param skip exclude all the policies including the specified one from the return set
+ * @return list of policy names or ZMSClientException will be thrown in case of failure
+ */
+ public PolicyList getPolicyList(String domainName, Integer limit, String skip) {
+ updatePrincipal();
+ try {
+ return client.getPolicyList(domainName, limit, skip);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Return the specified policy object assertion
+ * @param domainName name of the domain
+ * @param policyName name of the policy
+ * @param assertionId the id of the assertion to be retrieved
+ * @return Assertion object or ZMSClientException will be thrown in case of failure
+ */
+ public Assertion getAssertion(String domainName, String policyName, Long assertionId) {
+ updatePrincipal();
+ try {
+ return client.getAssertion(domainName, policyName, assertionId);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Add the specified assertion to the specified policy
+ * @param domainName name of the domain
+ * @param policyName name of the policy
+ * @param auditRef string containing audit specification or ticket number
+ * @param assertion Assertion object to be added to the policy
+ * @return updated assertion object that includes the server assigned id
+ */
+ public Assertion putAssertion(String domainName, String policyName, String auditRef, Assertion assertion) {
+ updatePrincipal();
+ try {
+ return client.putAssertion(domainName, policyName, auditRef, assertion);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete specified assertion from the given policy
+ * @param domainName name of the domain
+ * @param policyName name of the policy
+ * @param assertionId the id of the assertion to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteAssertion(String domainName, String policyName, Long assertionId, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteAssertion(domainName, policyName, assertionId, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Return the specified policy object
+ * @param domainName name of the domain
+ * @param policyName name of the policy to be retrieved
+ * @return Policy object or ZMSClientException will be thrown in case of failure
+ */
+ public Policy getPolicy(String domainName, String policyName) {
+ updatePrincipal();
+ try {
+ return client.getPolicy(domainName, policyName);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/Update a new policy in the specified domain. If updating a policy
+ * the provided object must contain all attributes as it will replace the
+ * full policy object configured on the server (not just some of the attributes).
+ * @param domainName name of the domain
+ * @param policyName name of the policy
+ * @param auditRef string containing audit specification or ticket number
+ * @param policy Policy object with details
+ */
+ public void putPolicy(String domainName, String policyName, String auditRef, Policy policy) {
+ updatePrincipal();
+ try {
+ client.putPolicy(domainName, policyName, auditRef, policy);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete specified policy from a domain
+ * @param domainName name of the domain
+ * @param policyName name of the policy to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deletePolicy(String domainName, String policyName, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deletePolicy(domainName, policyName, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/Update a new service in the specified domain. If updating a service
+ * the provided object must contain all attributes as it will replace the
+ * full service object configured on the server (not just some of the attributes).
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param auditRef string containing audit specification or ticket number
+ * @param service ServiceIdentity object with all service details
+ */
+ public void putServiceIdentity(String domainName, String serviceName,
+ String auditRef, ServiceIdentity service) {
+ updatePrincipal();
+ try {
+ client.putServiceIdentity(domainName, serviceName, auditRef, service);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified service object from a domain
+ * @param domainName name of the domain
+ * @param serviceName name of the service to be retrieved
+ * @return ServiceIdentity object or ZMSClientException will be thrown in case of failure
+ */
+ public ServiceIdentity getServiceIdentity(String domainName, String serviceName) {
+ updatePrincipal();
+ try {
+ return client.getServiceIdentity(domainName, serviceName);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified service from a domain
+ * @param domainName name of the domain
+ * @param serviceName name of the service to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteServiceIdentity(String domainName, String serviceName, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteServiceIdentity(domainName, serviceName, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of services defined for the specified domain. The services
+ * will contain their attributes and, if specified, the list of publickeys and hosts.
+ * @param domainName name of the domain
+ * @param publicKeys include all public keys for services as well
+ * @param hosts include all configured hosts for services as well
+ * @return list of services or ZMSClientException will be thrown in case of failure
+ */
+ public ServiceIdentities getServiceIdentities(String domainName, Boolean publicKeys, Boolean hosts) {
+ updatePrincipal();
+ try {
+ return client.getServiceIdentities(domainName, publicKeys, hosts);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the full list of services defined in a domain
+ * @param domainName name of the domain
+ * @return list of all service names or ZMSClientException will be thrown in case of failure
+ */
+ public ServiceIdentityList getServiceIdentityList(String domainName) {
+ updatePrincipal();
+ try {
+ return client.getServiceIdentityList(domainName, null, null);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of services defined in a domain filtered
+ * based on the specified arguments
+ * @param domainName name of the domain
+ * @param limit number of services to return
+ * @param skip exclude all the services including the specified one from the return set
+ * @return list of service names or ZMSClientException will be thrown in case of failure
+ */
+ public ServiceIdentityList getServiceIdentityList(String domainName, Integer limit, String skip) {
+ updatePrincipal();
+ try {
+ return client.getServiceIdentityList(domainName, limit, skip);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified public key from the given service object
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param keyId the identifier of the public key to be retrieved
+ * @return PublicKeyEntry object or ZMSClientException will be thrown in case of failure
+ */
+ public PublicKeyEntry getPublicKeyEntry(String domainName, String serviceName, String keyId) {
+ updatePrincipal();
+ try {
+ return client.getPublicKeyEntry(domainName, serviceName, keyId);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Update or add (if doesn't already exist) the specified public key in the service object
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param keyId the identifier of the public key to be updated
+ * @param auditRef string containing audit specification or ticket number
+ * @param publicKeyEntry that contains the public key details
+ */
+ public void putPublicKeyEntry(String domainName, String serviceName, String keyId, String auditRef,
+ PublicKeyEntry publicKeyEntry) {
+ updatePrincipal();
+ try {
+ client.putPublicKeyEntry(domainName, serviceName, keyId, auditRef, publicKeyEntry);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified public key from the service object. If the key doesn't exist then
+ * it is treated as a successful operation and no exception will be thrown.
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param keyId the identifier of the public key to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deletePublicKeyEntry(String domainName, String serviceName, String keyId, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deletePublicKeyEntry(domainName, serviceName, keyId, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create/update an entity object in ZMS
+ * @param domainName name of the domain
+ * @param entityName name of the entity
+ * @param auditRef string containing audit specification or ticket number
+ * @param entity entity object with details
+ */
+ public void putEntity(String domainName, String entityName, String auditRef, Entity entity) {
+ updatePrincipal();
+ try {
+ client.putEntity(domainName, entityName, auditRef, entity);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified entity from the ZMS Server
+ * @param domainName name of the domain
+ * @param entityName name of the entity
+ * @return Entity object with details or ZMSClientException will be thrown in case of failure
+ */
+ public Entity getEntity(String domainName, String entityName) {
+ updatePrincipal();
+ try {
+ return client.getEntity(domainName, entityName);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified entity from the ZMS Server
+ * @param domainName name of the domain
+ * @param entityName name of the entity
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteEntity(String domainName, String entityName, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteEntity(domainName, entityName, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of entities defined for the specified domain
+ * @param domainName name of the domain
+ * @return list of entity names or ZMSClientException will be thrown in case of failure
+ */
+ public EntityList getEntityList(String domainName) {
+ updatePrincipal();
+ try {
+ return client.getEntityList(domainName);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create a new tenant for the specified domain. The service specifies the
+ * provider.
+ * @param tenantDomain name of the tenant domain
+ * @param providerService name of the provider service
+ * format: provider-domain-name.provider-service-name, ex: "sports.storage"
+ * @param auditRef string containing audit specification or ticket number
+ * @param tenant Tenancy object with tenant details
+ */
+ public void putTenancy(String tenantDomain, String providerService, String auditRef, Tenancy tenant) {
+ updatePrincipal();
+ try {
+ client.putTenancy(tenantDomain, providerService, auditRef, tenant);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified tenant from a domain
+ * @param tenantDomain name of the tenant domain
+ * @param providerService name of the provider service,
+ * format: provider-domain-name.provider-service-name, ex: "sports.storage"
+ * @return Tenancy object or ZMSClientException will be thrown in case of failure
+ */
+ public Tenancy getTenancy(String tenantDomain, String providerService) {
+ updatePrincipal();
+ try {
+ return client.getTenancy(tenantDomain, providerService);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified tenant from a domain
+ * @param tenantDomain name of the tenant domain
+ * @param providerService name of the provider service,
+ * format: provider-domain-name.provider-service-name, ex: "sports.storage"
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteTenancy(String tenantDomain, String providerService, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteTenancy(tenantDomain, providerService, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create a new resource group for the specified tenant. The service specifies the
+ * provider. The tenant must have on-boarded already using the putTenancy call.
+ * @param tenantDomain name of the tenant domain
+ * @param providerService name of the provider service,
+ * format: provider-domain-name.provider-service-name, ex: "sports.storage"
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ * @param resourceGroupData TenancyResourceGroup object with tenant's resource group details
+ */
+ public void putTenancyResourceGroup(String tenantDomain, String providerService,
+ String resourceGroup, String auditRef, TenancyResourceGroup resourceGroupData) {
+ updatePrincipal();
+ try {
+ client.putTenancyResourceGroup(tenantDomain, providerService, resourceGroup, auditRef, resourceGroupData);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified resource group for the tenant.
+ * @param tenantDomain name of the tenant domain
+ * @param providerService name of the provider service, format:
+ * provider-domain-name.provider-service-name, ex: "sports.storage"
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteTenancyResourceGroup(String tenantDomain, String providerService,
+ String resourceGroup, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteTenancyResourceGroup(tenantDomain, providerService, resourceGroup, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create tenant roles for the specified tenant
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of the tenant's domain
+ * @param auditRef string containing audit specification or ticket number
+ * @param tenantRoles Tenant roles
+ */
+ public void putTenantRoles(String providerDomain, String providerServiceName,
+ String tenantDomain, String auditRef, TenantRoles tenantRoles) {
+ updatePrincipal();
+ try {
+ client.putTenantRoles(providerDomain, providerServiceName, tenantDomain, auditRef, tenantRoles);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Create tenant roles for the specified tenant resource group.
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of the tenant's domain
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ * @param tenantRoles Tenant roles
+ */
+ public void putTenantResourceGroupRoles(String providerDomain, String providerServiceName, String tenantDomain,
+ String resourceGroup, String auditRef, TenantResourceGroupRoles tenantRoles) {
+ updatePrincipal();
+ try {
+ client.putTenantResourceGroupRoles(providerDomain, providerServiceName, tenantDomain,
+ resourceGroup, auditRef, tenantRoles);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of tenant roles defined for a tenant in a domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of the tenant's domain
+ * @return list of tenant roles or ZMSClientException will be thrown in case of failure
+ */
+ public TenantRoles getTenantRoles(String providerDomain, String providerServiceName, String tenantDomain) {
+ updatePrincipal();
+ try {
+ return client.getTenantRoles(providerDomain, providerServiceName, tenantDomain);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of tenant roles defined for a tenant resource group in a domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of the tenant's domain
+ * @param resourceGroup name of the resource group
+ * @return list of tenant roles or ZMSClientException will be thrown in case of failure
+ */
+ public TenantResourceGroupRoles getTenantResourceGroupRoles(String providerDomain, String providerServiceName,
+ String tenantDomain, String resourceGroup) {
+ updatePrincipal();
+ try {
+ return client.getTenantResourceGroupRoles(providerDomain, providerServiceName,
+ tenantDomain, resourceGroup);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete tenant roles for the specified tenant in a domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of tenant's domain
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteTenantRoles(String providerDomain, String providerServiceName, String tenantDomain,
+ String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteTenantRoles(providerDomain, providerServiceName, tenantDomain, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete tenant roles for the specified tenant resource group in a domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param tenantDomain name of tenant's domain
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteTenantResourceGroupRoles(String providerDomain, String providerServiceName, String tenantDomain,
+ String resourceGroup, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteTenantResourceGroupRoles(providerDomain, providerServiceName, tenantDomain,
+ resourceGroup, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Requests the ZMS to indicate whether or not the specific request for the
+ * specified resource with authentication details will be granted or not.
+ * @param action value of the action to be carried out (e.g. "UPDATE", "DELETE")
+ * @param resource resource YRN. YRN is defined as {ServiceName})?:({LocationName})?:)?{ResourceName}"
+ * @param trustDomain (optional) if the access checks involves cross domain check only
+ * check the specified trusted domain and ignore all others
+ * @return Access object indicating whether or not the request will be granted or not
+ */
+ public Access getAccess(String action, String resource, String trustDomain) {
+ return getAccess(action, resource, trustDomain, null);
+ }
+
+ /**
+ * Requests the ZMS to indicate whether or not the specific request for the
+ * specified resource with authentication details will be granted or not.
+ * @param action value of the action to be carried out (e.g. "UPDATE", "DELETE")
+ * @param resource resource YRN. YRN is defined as {ServiceName})?:({LocationName})?:)?{ResourceName}"
+ * @param trustDomain (optional) if the access checks involves cross domain check only
+ * check the specified trusted domain and ignore all others
+ * @param principal (optional) carry out the access check for specified principal
+ * @return Access object indicating whether or not the request will be granted or not
+ */
+ public Access getAccess(String action, String resource, String trustDomain, String principal) {
+ try {
+ return client.getAccess(action, resource, trustDomain, principal);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+
+ /**
+ * Requests the ZMS to indicate whether or not the specific request for the
+ * specified resource with authentication details will be granted or not.
+ * @param action value of the action to be carried out (e.g. "UPDATE", "DELETE")
+ * @param resource resource string.
+ * @param trustDomain (optional) if the access checks involves cross domain check only
+ * check the specified trusted domain and ignore all others
+ * @param principal (optional) carry out the access check for specified principal
+ * @return Access object indicating whether or not the request will be granted or not
+ */
+ public Access getAccessExt(String action, String resource, String trustDomain, String principal) {
+ try {
+ return client.getAccessExt(action, resource, trustDomain, principal);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of all domain data from the ZMS Server that
+ * is signed with ZMS's private key. It will pass an optional matchingTag
+ * so that ZMS can skip returning domains if no changes have taken
+ * place since that tag was issued.
+ * @param domainName name of the domain. if specified, the server will
+ * only return this domain in the result set
+ * @param metaOnly (can be null) must have value of true or false (default).
+ * if set to true, zms server will only return meta information
+ * about each domain (description, last modified timestamp, etc) and
+ * no role/policy/service details will be returned.
+ * @param matchingTag (can be null) contains modified timestamp received
+ * with last request. If null, then return all domains.
+ * @param responseHeaders contains the "tag" returned for modification
+ * time of the domains, map key = "tag", List should
+ * contain a single value timestamp String to be used
+ * with subsequent call as matchingTag to this API
+ * @return list of domains signed by ZMS Server
+ */
+ public SignedDomains getSignedDomains(String domainName, String metaOnly, String matchingTag,
+ Map> responseHeaders) {
+ updatePrincipal();
+ try {
+ SignedDomains sd = client.getSignedDomains(domainName, metaOnly, matchingTag, responseHeaders);
+ return sd;
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * For the specified user credentials return the corresponding User Token that
+ * can be used for authenticating other ZMS operations. The client internally
+ * automatically calls this method and uses the UserToken if the ZMSClient
+ * object was initialized with a user principal.
+ * @param userName name of the user. This is only used to verify that it matches
+ * the user name from the credentials and is optional. The caller can just pass
+ * the string "_self_" as the userName to bypass this optional check.
+ * @return ZMS generated User Token
+ */
+ public UserToken getUserToken(String userName) {
+ return getUserToken(userName, null);
+ }
+
+ /**
+ * For the specified user credentials return the corresponding User Token that
+ * can be used for authenticating other ZMS operations by any of the specified
+ * authorized services.
+ * @param userName name of the user
+ * @param serviceNames comma separated list of authorized service names
+ * @return ZMS generated User Token
+ */
+ public UserToken getUserToken(String userName, String serviceNames) {
+ try {
+ return client.getUserToken(userName, serviceNames);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * For the specified domain in domainName, a list of default administrators
+ * can be passed to this method and will be added to the domain's admin role
+ * In addition this method will ensure that the admin role and policy exist and
+ * are properly set up
+ * @param domainName - name of the domain to add default administrators to
+ * @param auditRef - string containing audit specification or ticket number
+ * @param defaultAdmins - list of names to be added as default administrators
+ */
+ public void putDefaultAdmins(String domainName, String auditRef, DefaultAdmins defaultAdmins) {
+ updatePrincipal();
+ try {
+ client.putDefaultAdmins(domainName, auditRef, defaultAdmins);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * The client will validate the given serviceToken against the ZMS Server
+ * and if the token is valid, it will return a Principal object.
+ * @param serviceToken token to be validated.
+ * @return Principal object if the token is successfully validated or
+ * ZMSClientException will be thrown in case of failure
+ */
+ public Principal getPrincipal(String serviceToken) {
+
+ if (serviceToken == null) {
+ throw new ZMSClientException(401, "Null service token provided");
+ }
+
+ PrincipalToken token = null;
+ try {
+ token = new PrincipalToken(serviceToken);
+ } catch (IllegalArgumentException ex) {
+ throw new ZMSClientException(ZMSClientException.UNAUTHORIZED, "Invalid service token provided: " + ex.getMessage());
+ }
+
+ Principal servicePrincipal = null;
+ try {
+ servicePrincipal = SimplePrincipal.create(token.getDomain(), token.getName(),
+ serviceToken, 0, PRINCIPAL_AUTHORITY);
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.UNAUTHORIZED, "Invalid service token provided");
+ }
+
+ addCredentials(servicePrincipal);
+
+ ServicePrincipal validatedPrincipal = null;
+ try {
+ validatedPrincipal = client.getServicePrincipal();
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+
+ if (validatedPrincipal == null) {
+ throw new ZMSClientException(ZMSClientException.UNAUTHORIZED, "Invalid service token provided");
+ }
+
+ // before returning let's validate that domain, name and
+ // credentials match to what was passed to
+
+ if (!servicePrincipal.getDomain().equalsIgnoreCase(validatedPrincipal.getDomain())) {
+ throw new ZMSClientException(ZMSClientException.UNAUTHORIZED, "Validated principal domain name mismatch");
+ }
+
+ if (!servicePrincipal.getName().equalsIgnoreCase(validatedPrincipal.getService())) {
+ throw new ZMSClientException(ZMSClientException.UNAUTHORIZED, "Validated principal service name mismatch");
+ }
+
+ return servicePrincipal;
+ }
+
+ /**
+ * Create provider roles for the specified tenant resource group in the tenant domain.
+ * If the principal requesting this operation has been authorized by the provider
+ * service itself, then the corresponding tenant roles will be created in the provider
+ * domain as well thus completing the tenancy on-boarding process in one call.
+ * @param tenantDomain name of the tenant's domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ * @param providerRoles Provider roles
+ */
+ public void putProviderResourceGroupRoles(String tenantDomain, String providerDomain,
+ String providerServiceName, String resourceGroup, String auditRef,
+ ProviderResourceGroupRoles providerRoles) {
+ updatePrincipal();
+ try {
+ client.putProviderResourceGroupRoles(tenantDomain, providerDomain, providerServiceName,
+ resourceGroup, auditRef, providerRoles);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the provider roles for the specified tenant resource group from the tenant domain.
+ * If the principal requesting this operation has been authorized by the provider
+ * service itself, then the corresponding tenant roles will be deleted from the provider
+ * domain as well thus completing the process in one call.
+ * @param tenantDomain name of tenant's domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param resourceGroup name of the resource group
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteProviderResourceGroupRoles(String tenantDomain, String providerDomain,
+ String providerServiceName, String resourceGroup, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteProviderResourceGroupRoles(tenantDomain, providerDomain, providerServiceName,
+ resourceGroup, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of provider roles defined for a tenant resource group in a domain
+ * @param tenantDomain name of the tenant's domain
+ * @param providerDomain name of the provider domain
+ * @param providerServiceName name of the provider service
+ * @param resourceGroup name of the resource group
+ * @return list of provider roles or ZMSClientException will be thrown in case of failure
+ */
+ public ProviderResourceGroupRoles getProviderResourceGroupRoles(String tenantDomain,
+ String providerDomain, String providerServiceName, String resourceGroup) {
+ updatePrincipal();
+ try {
+ return client.getProviderResourceGroupRoles(tenantDomain, providerDomain, providerServiceName,
+ resourceGroup);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Check the data for the specified domain object
+ * @param domain name of the domain to be checked
+ * @return DomainDataCheck object or ZMSClientException will be thrown in case of failure
+ */
+ public DomainDataCheck getDomainDataCheck(String domain) {
+ updatePrincipal();
+ try {
+ return client.getDomainDataCheck(domain);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the the specified solution template provisioned on the ZMS Server.
+ * The template object will include the list of roles and policies that will
+ * be provisioned in the domain when the template is applied.
+ * @param template name of the solution template to be retrieved
+ * @return template object or ZMSClientException will be thrown in case of failure
+ */
+ public Template getTemplate(String template) {
+ updatePrincipal();
+ try {
+ return client.getTemplate(template);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of solution templates provisioned on the ZMS Server
+ * @return list of template names or ZMSClientException will be thrown in case of failure
+ */
+ public ServerTemplateList getServerTemplateList() {
+ updatePrincipal();
+ try {
+ return client.getServerTemplateList();
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Provision the specified solution template roles and policies in the domain
+ * @param domain name of the domain to be updated
+ * @param auditRef string containing audit specification or ticket number
+ * @param templates contains list of template names to be provisioned in the domain
+ */
+ public void putDomainTemplate(String domain, String auditRef, DomainTemplate templates) {
+ updatePrincipal();
+ try {
+ client.putDomainTemplate(domain, auditRef, templates);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Delete the specified solution template roles and policies from the domain
+ * @param domain name of the domain to be updated
+ * @param template is the name of the provisioned template to be deleted
+ * @param auditRef string containing audit specification or ticket number
+ */
+ public void deleteDomainTemplate(String domain, String template, String auditRef) {
+ updatePrincipal();
+ try {
+ client.deleteDomainTemplate(domain, template, auditRef);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of solution template provisioned for a domain
+ * @param domain name of the domain
+ * @return TemplateList object that includes the list of provisioned solution template names
+ */
+ public DomainTemplateList getDomainTemplateList(String domain) {
+ updatePrincipal();
+ try {
+ return client.getDomainTemplateList(domain);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the list of resources as defined in their respective assertions
+ * that the given principal has access to through their role membership
+ * @param principal the principal name (e.g. user.joe). Must have special
+ * privileges to execute this query without specifying the principal.
+ * Check with Athenz Service Administrators if you have a use case to
+ * request all principals from Athenz Service
+ * @param action optional field specifying what action to filter assertions on
+ * @return ResourceAccessList object that lists the set of assertions per principal
+ */
+ public ResourceAccessList getResourceAccessList(String principal, String action) {
+ updatePrincipal();
+ try {
+ return client.getResourceAccessList(principal, action);
+ } catch (ResourceException ex) {
+ throw new ZMSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZMSClientException(ZMSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+}
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClientException.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClientException.java
new file mode 100644
index 00000000000..331acf66a58
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSClientException.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+public class ZMSClientException extends ResourceException {
+
+ private static final long serialVersionUID = -8084410672948347342L;
+
+ public ZMSClientException(int code, Object data) {
+ super(code, data);
+ }
+}
diff --git a/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSRDLGeneratedClient.java b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSRDLGeneratedClient.java
new file mode 100644
index 00000000000..39d13d70a64
--- /dev/null
+++ b/clients/java/zms/src/main/java/com/yahoo/athenz/zms/ZMSRDLGeneratedClient.java
@@ -0,0 +1,1478 @@
+//
+// This file generated by rdl 1.4.8. Do not modify!
+//
+package com.yahoo.athenz.zms;
+
+import com.yahoo.rdl.*;
+import javax.ws.rs.client.*;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.net.ssl.HostnameVerifier;
+
+public class ZMSRDLGeneratedClient {
+ Client client;
+ WebTarget base;
+ String credsHeader;
+ String credsToken;
+
+ public ZMSRDLGeneratedClient(String url) {
+ client = ClientBuilder.newClient();
+ base = client.target(url);
+ }
+
+ public ZMSRDLGeneratedClient(String url, HostnameVerifier hostnameVerifier) {
+ client = ClientBuilder.newBuilder()
+ .hostnameVerifier(hostnameVerifier)
+ .build();
+ base = client.target(url);
+ }
+
+ public void close() {
+ client.close();
+ }
+
+ public ZMSRDLGeneratedClient setProperty(String name, Object value) {
+ client = client.property(name, value);
+ return this;
+ }
+
+ public ZMSRDLGeneratedClient addCredentials(String header, String token) {
+ credsHeader = header;
+ credsToken = token;
+ return this;
+ }
+
+ public Domain getDomain(String domain) {
+ WebTarget target = base.path("/domain/{domain}")
+ .resolveTemplate("domain", domain);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Domain.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DomainList getDomainList(Integer limit, String skip, String prefix, Integer depth, String account, Integer productId, String roleMember, String roleName, String modifiedSince) {
+ WebTarget target = base.path("/domain");
+ if (limit != null) {
+ target = target.queryParam("limit", limit);
+ }
+ if (skip != null) {
+ target = target.queryParam("skip", skip);
+ }
+ if (prefix != null) {
+ target = target.queryParam("prefix", prefix);
+ }
+ if (depth != null) {
+ target = target.queryParam("depth", depth);
+ }
+ if (account != null) {
+ target = target.queryParam("account", account);
+ }
+ if (productId != null) {
+ target = target.queryParam("ypmid", productId);
+ }
+ if (roleMember != null) {
+ target = target.queryParam("member", roleMember);
+ }
+ if (roleName != null) {
+ target = target.queryParam("role", roleName);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (modifiedSince != null) {
+ invocationBuilder = invocationBuilder.header("If-Modified-Since", modifiedSince);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(DomainList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Domain postTopLevelDomain(String auditRef, TopLevelDomain detail) {
+ WebTarget target = base.path("/domain");
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.post(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Domain.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Domain postSubDomain(String parent, String auditRef, SubDomain detail) {
+ WebTarget target = base.path("/subdomain/{parent}")
+ .resolveTemplate("parent", parent);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.post(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Domain.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Domain postUserDomain(String name, String auditRef, UserDomain detail) {
+ WebTarget target = base.path("/userdomain/{name}")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.post(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Domain.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TopLevelDomain deleteTopLevelDomain(String name, String auditRef) {
+ WebTarget target = base.path("/domain/{name}")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public SubDomain deleteSubDomain(String parent, String name, String auditRef) {
+ WebTarget target = base.path("/subdomain/{parent}/{name}")
+ .resolveTemplate("parent", parent)
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public UserDomain deleteUserDomain(String name, String auditRef) {
+ WebTarget target = base.path("/userdomain/{name}")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Domain putDomainMeta(String name, String auditRef, DomainMeta detail) {
+ WebTarget target = base.path("/domain/{name}/meta")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DomainTemplate putDomainTemplate(String name, String auditRef, DomainTemplate template) {
+ WebTarget target = base.path("/domain/{name}/template")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(template, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DomainTemplateList getDomainTemplateList(String name) {
+ WebTarget target = base.path("/domain/{name}/template")
+ .resolveTemplate("name", name);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(DomainTemplateList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DomainTemplate deleteDomainTemplate(String name, String template, String auditRef) {
+ WebTarget target = base.path("/domain/{name}/template/{template}")
+ .resolveTemplate("name", name)
+ .resolveTemplate("template", template);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DomainDataCheck getDomainDataCheck(String domainName) {
+ WebTarget target = base.path("/domain/{domainName}/check")
+ .resolveTemplate("domainName", domainName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(DomainDataCheck.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Entity putEntity(String domainName, String entityName, String auditRef, Entity entity) {
+ WebTarget target = base.path("/domain/{domainName}/entity/{entityName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("entityName", entityName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(entity, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Entity getEntity(String domainName, String entityName) {
+ WebTarget target = base.path("/domain/{domainName}/entity/{entityName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("entityName", entityName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Entity.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Entity deleteEntity(String domainName, String entityName, String auditRef) {
+ WebTarget target = base.path("/domain/{domainName}/entity/{entityName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("entityName", entityName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public EntityList getEntityList(String domainName) {
+ WebTarget target = base.path("/domain/{domainName}/entity")
+ .resolveTemplate("domainName", domainName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(EntityList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public RoleList getRoleList(String domainName, Integer limit, String skip) {
+ WebTarget target = base.path("/domain/{domainName}/role")
+ .resolveTemplate("domainName", domainName);
+ if (limit != null) {
+ target = target.queryParam("limit", limit);
+ }
+ if (skip != null) {
+ target = target.queryParam("skip", skip);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(RoleList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Roles getRoles(String domainName, Boolean members) {
+ WebTarget target = base.path("/domain/{domainName}/roles")
+ .resolveTemplate("domainName", domainName);
+ if (members != null) {
+ target = target.queryParam("members", members);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Roles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Role getRole(String domainName, String roleName, Boolean auditLog, Boolean expand) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName);
+ if (auditLog != null) {
+ target = target.queryParam("auditLog", auditLog);
+ }
+ if (expand != null) {
+ target = target.queryParam("expand", expand);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Role.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Role putRole(String domainName, String roleName, String auditRef, Role role) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(role, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Role deleteRole(String domainName, String roleName, String auditRef) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Membership getMembership(String domainName, String roleName, String memberName) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}/member/{memberName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName)
+ .resolveTemplate("memberName", memberName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Membership.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Membership putMembership(String domainName, String roleName, String memberName, String auditRef, Membership membership) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}/member/{memberName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName)
+ .resolveTemplate("memberName", memberName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(membership, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Membership deleteMembership(String domainName, String roleName, String memberName, String auditRef) {
+ WebTarget target = base.path("/domain/{domainName}/role/{roleName}/member/{memberName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("roleName", roleName)
+ .resolveTemplate("memberName", memberName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public DefaultAdmins putDefaultAdmins(String domainName, String auditRef, DefaultAdmins defaultAdmins) {
+ WebTarget target = base.path("/domain/{domainName}/admins")
+ .resolveTemplate("domainName", domainName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(defaultAdmins, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public PolicyList getPolicyList(String domainName, Integer limit, String skip) {
+ WebTarget target = base.path("/domain/{domainName}/policy")
+ .resolveTemplate("domainName", domainName);
+ if (limit != null) {
+ target = target.queryParam("limit", limit);
+ }
+ if (skip != null) {
+ target = target.queryParam("skip", skip);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(PolicyList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Policies getPolicies(String domainName, Boolean assertions) {
+ WebTarget target = base.path("/domain/{domainName}/policies")
+ .resolveTemplate("domainName", domainName);
+ if (assertions != null) {
+ target = target.queryParam("assertions", assertions);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Policies.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Policy getPolicy(String domainName, String policyName) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Policy.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Policy putPolicy(String domainName, String policyName, String auditRef, Policy policy) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(policy, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Policy deletePolicy(String domainName, String policyName, String auditRef) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Assertion getAssertion(String domainName, String policyName, Long assertionId) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}/assertion/{assertionId}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName)
+ .resolveTemplate("assertionId", assertionId);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Assertion.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Assertion putAssertion(String domainName, String policyName, String auditRef, Assertion assertion) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}/assertion")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(assertion, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ case 201:
+ return response.readEntity(Assertion.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Assertion deleteAssertion(String domainName, String policyName, Long assertionId, String auditRef) {
+ WebTarget target = base.path("/domain/{domainName}/policy/{policyName}/assertion/{assertionId}")
+ .resolveTemplate("domainName", domainName)
+ .resolveTemplate("policyName", policyName)
+ .resolveTemplate("assertionId", assertionId);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServiceIdentity putServiceIdentity(String domain, String service, String auditRef, ServiceIdentity detail) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServiceIdentity getServiceIdentity(String domain, String service) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ServiceIdentity.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServiceIdentity deleteServiceIdentity(String domain, String service, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServiceIdentities getServiceIdentities(String domainName, Boolean publickeys, Boolean hosts) {
+ WebTarget target = base.path("/domain/{domainName}/services")
+ .resolveTemplate("domainName", domainName);
+ if (publickeys != null) {
+ target = target.queryParam("publickeys", publickeys);
+ }
+ if (hosts != null) {
+ target = target.queryParam("hosts", hosts);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ServiceIdentities.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServiceIdentityList getServiceIdentityList(String domainName, Integer limit, String skip) {
+ WebTarget target = base.path("/domain/{domainName}/service")
+ .resolveTemplate("domainName", domainName);
+ if (limit != null) {
+ target = target.queryParam("limit", limit);
+ }
+ if (skip != null) {
+ target = target.queryParam("skip", skip);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ServiceIdentityList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public PublicKeyEntry getPublicKeyEntry(String domain, String service, String id) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/publickey/{id}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("id", id);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(PublicKeyEntry.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public PublicKeyEntry putPublicKeyEntry(String domain, String service, String id, String auditRef, PublicKeyEntry publicKeyEntry) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/publickey/{id}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("id", id);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(publicKeyEntry, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public PublicKeyEntry deletePublicKeyEntry(String domain, String service, String id, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/publickey/{id}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("id", id);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Tenancy putTenancy(String domain, String service, String auditRef, Tenancy detail) {
+ WebTarget target = base.path("/domain/{domain}/tenancy/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Tenancy getTenancy(String domain, String service) {
+ WebTarget target = base.path("/domain/{domain}/tenancy/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Tenancy.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Tenancy deleteTenancy(String domain, String service, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/tenancy/{service}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenancyResourceGroup putTenancyResourceGroup(String domain, String service, String resourceGroup, String auditRef, TenancyResourceGroup detail) {
+ WebTarget target = base.path("/domain/{domain}/tenancy/{service}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenancyResourceGroup deleteTenancyResourceGroup(String domain, String service, String resourceGroup, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/tenancy/{service}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantRoles putTenantRoles(String domain, String service, String tenantDomain, String auditRef, TenantRoles detail) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ case 201:
+ return response.readEntity(TenantRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantRoles getTenantRoles(String domain, String service, String tenantDomain) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(TenantRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantRoles deleteTenantRoles(String domain, String service, String tenantDomain, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantResourceGroupRoles putTenantResourceGroupRoles(String domain, String service, String tenantDomain, String resourceGroup, String auditRef, TenantResourceGroupRoles detail) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ case 201:
+ return response.readEntity(TenantResourceGroupRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantResourceGroupRoles getTenantResourceGroupRoles(String domain, String service, String tenantDomain, String resourceGroup) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(TenantResourceGroupRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public TenantResourceGroupRoles deleteTenantResourceGroupRoles(String domain, String service, String tenantDomain, String resourceGroup, String auditRef) {
+ WebTarget target = base.path("/domain/{domain}/service/{service}/tenant/{tenantDomain}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("domain", domain)
+ .resolveTemplate("service", service)
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ProviderResourceGroupRoles putProviderResourceGroupRoles(String tenantDomain, String provDomain, String provService, String resourceGroup, String auditRef, ProviderResourceGroupRoles detail) {
+ WebTarget target = base.path("/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("provDomain", provDomain)
+ .resolveTemplate("provService", provService)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.put(javax.ws.rs.client.Entity.entity(detail, "application/json"));
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ case 201:
+ return response.readEntity(ProviderResourceGroupRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ProviderResourceGroupRoles getProviderResourceGroupRoles(String tenantDomain, String provDomain, String provService, String resourceGroup) {
+ WebTarget target = base.path("/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("provDomain", provDomain)
+ .resolveTemplate("provService", provService)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ProviderResourceGroupRoles.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ProviderResourceGroupRoles deleteProviderResourceGroupRoles(String tenantDomain, String provDomain, String provService, String resourceGroup, String auditRef) {
+ WebTarget target = base.path("/domain/{tenantDomain}/provDomain/{provDomain}/provService/{provService}/resourceGroup/{resourceGroup}")
+ .resolveTemplate("tenantDomain", tenantDomain)
+ .resolveTemplate("provDomain", provDomain)
+ .resolveTemplate("provService", provService)
+ .resolveTemplate("resourceGroup", resourceGroup);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (auditRef != null) {
+ invocationBuilder = invocationBuilder.header("Y-Audit-Ref", auditRef);
+ }
+ Response response = invocationBuilder.delete();
+ int code = response.getStatus();
+ switch (code) {
+ case 204:
+ return null;
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Access getAccess(String action, String resource, String domain, String checkPrincipal) {
+ WebTarget target = base.path("/access/{action}/{resource}")
+ .resolveTemplate("action", action)
+ .resolveTemplate("resource", resource);
+ if (domain != null) {
+ target = target.queryParam("domain", domain);
+ }
+ if (checkPrincipal != null) {
+ target = target.queryParam("principal", checkPrincipal);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Access.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Access getAccessExt(String action, String resource, String domain, String checkPrincipal) {
+ WebTarget target = base.path("/access/{action}")
+ .resolveTemplate("action", action);
+ if (resource != null) {
+ target = target.queryParam("resource", resource);
+ }
+ if (domain != null) {
+ target = target.queryParam("domain", domain);
+ }
+ if (checkPrincipal != null) {
+ target = target.queryParam("principal", checkPrincipal);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Access.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ResourceAccessList getResourceAccessList(String principal, String action) {
+ WebTarget target = base.path("/resource");
+ if (principal != null) {
+ target = target.queryParam("principal", principal);
+ }
+ if (action != null) {
+ target = target.queryParam("action", action);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ResourceAccessList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public SignedDomains getSignedDomains(String domain, String metaOnly, String matchingTag, java.util.Map> headers) {
+ WebTarget target = base.path("/sys/modified_domains");
+ if (domain != null) {
+ target = target.queryParam("domain", domain);
+ }
+ if (metaOnly != null) {
+ target = target.queryParam("metaonly", metaOnly);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ if (matchingTag != null) {
+ invocationBuilder = invocationBuilder.header("If-None-Match", matchingTag);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ case 304:
+ if (headers != null) {
+ headers.put("tag", java.util.Arrays.asList((String)response.getHeaders().getFirst("ETag")));
+ }
+ if (code == 304) {
+ return null;
+ }
+ return response.readEntity(SignedDomains.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public UserToken getUserToken(String userName, String serviceNames) {
+ WebTarget target = base.path("/user/{userName}/token")
+ .resolveTemplate("userName", userName);
+ if (serviceNames != null) {
+ target = target.queryParam("services", serviceNames);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(UserToken.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public UserToken optionsUserToken(String userName, String serviceNames) {
+ WebTarget target = base.path("/user/{userName}/token")
+ .resolveTemplate("userName", userName);
+ if (serviceNames != null) {
+ target = target.queryParam("services", serviceNames);
+ }
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ Response response = invocationBuilder.options();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(UserToken.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServicePrincipal getServicePrincipal() {
+ WebTarget target = base.path("/principal");
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ServicePrincipal.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public ServerTemplateList getServerTemplateList() {
+ WebTarget target = base.path("/template");
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(ServerTemplateList.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+ public Template getTemplate(String template) {
+ WebTarget target = base.path("/template/{template}")
+ .resolveTemplate("template", template);
+ Invocation.Builder invocationBuilder = target.request("application/json");
+ if (credsHeader != null) {
+ invocationBuilder = invocationBuilder.header(credsHeader, credsToken);
+ }
+ Response response = invocationBuilder.get();
+ int code = response.getStatus();
+ switch (code) {
+ case 200:
+ return response.readEntity(Template.class);
+ default:
+ throw new ResourceException(code, response.readEntity(ResourceError.class));
+ }
+
+ }
+
+}
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.JsonFactory b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.JsonFactory
new file mode 100644
index 00000000000..d1ec3d025c3
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.JsonFactory
@@ -0,0 +1 @@
+athenz.shade.zms.com.fasterxml.jackson.core.JsonFactory
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.ObjectCodec b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.ObjectCodec
new file mode 100644
index 00000000000..9d360420066
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.core.ObjectCodec
@@ -0,0 +1 @@
+athenz.shade.zms.com.fasterxml.jackson.databind.ObjectMapper
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.databind.Module b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.databind.Module
new file mode 100644
index 00000000000..da39184c36f
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.com.fasterxml.jackson.databind.Module
@@ -0,0 +1 @@
+athenz.shade.zms.com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.client.ClientBuilder b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.client.ClientBuilder
new file mode 100644
index 00000000000..781eadbf366
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.client.ClientBuilder
@@ -0,0 +1 @@
+athenz.shade.zms.org.glassfish.jersey.client.JerseyClientBuilder
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyReader b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyReader
new file mode 100644
index 00000000000..195261405f6
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyReader
@@ -0,0 +1 @@
+athenz.shade.zms.com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyWriter b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyWriter
new file mode 100644
index 00000000000..195261405f6
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.MessageBodyWriter
@@ -0,0 +1 @@
+athenz.shade.zms.com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.RuntimeDelegate b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.RuntimeDelegate
new file mode 100644
index 00000000000..2cddd883218
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.javax.ws.rs.ext.RuntimeDelegate
@@ -0,0 +1 @@
+athenz.shade.zms.org.glassfish.jersey.internal.RuntimeDelegateImpl
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.hk2.extension.ServiceLocatorGenerator b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.hk2.extension.ServiceLocatorGenerator
new file mode 100644
index 00000000000..b5ccd1a122f
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.hk2.extension.ServiceLocatorGenerator
@@ -0,0 +1 @@
+athenz.shade.zms.org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl
diff --git a/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.jersey.internal.spi.AutoDiscoverable b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.jersey.internal.spi.AutoDiscoverable
new file mode 100644
index 00000000000..842e2b62138
--- /dev/null
+++ b/clients/java/zms/src/main/resources/META-INF/services/athenz.shade.zms.org.glassfish.jersey.internal.spi.AutoDiscoverable
@@ -0,0 +1,2 @@
+athenz.shade.zms.org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable
+athenz.shade.zms.org.glassfish.jersey.logging.LoggingFeatureAutoDiscoverable
diff --git a/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ResourceExceptionTest.java b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ResourceExceptionTest.java
new file mode 100644
index 00000000000..489c3dda0c1
--- /dev/null
+++ b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ResourceExceptionTest.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class ResourceExceptionTest {
+ public final static int OK = 200;
+ public final static int CREATED = 201;
+ public final static int ACCEPTED = 202;
+ public final static int NO_CONTENT = 204;
+ public final static int MOVED_PERMANENTLY = 301;
+ public final static int FOUND = 302;
+ public final static int SEE_OTHER = 303;
+ public final static int NOT_MODIFIED = 304;
+ public final static int TEMPORARY_REDIRECT = 307;
+ public final static int BAD_REQUEST = 400;
+ public final static int UNAUTHORIZED = 401;
+ public final static int FORBIDDEN = 403;
+ public final static int NOT_FOUND = 404;
+ public final static int CONFLICT = 409;
+ public final static int GONE = 410;
+ public final static int PRECONDITION_FAILED = 412;
+ public final static int UNSUPPORTED_MEDIA_TYPE = 415;
+ public final static int INTERNAL_SERVER_ERROR = 500;
+ public final static int NOT_IMPLEMENTED = 501;
+ public final static int SERVICE_UNAVAILABLE = 503;
+
+ @Test
+ public void testCodeToString() {
+
+ assertEquals("OK", ResourceException.codeToString(200));
+ assertEquals("Created", ResourceException.codeToString(201));
+ assertEquals("Accepted", ResourceException.codeToString(202));
+ assertEquals("No Content", ResourceException.codeToString(204));
+ assertEquals("Moved Permanently", ResourceException.codeToString(301));
+ assertEquals("Found", ResourceException.codeToString(302));
+ assertEquals("See Other", ResourceException.codeToString(303));
+ assertEquals("Not Modified", ResourceException.codeToString(304));
+ assertEquals("Temporary Redirect", ResourceException.codeToString(307));
+ assertEquals("Bad Request", ResourceException.codeToString(400));
+ assertEquals("Unauthorized", ResourceException.codeToString(401));
+ assertEquals("Forbidden", ResourceException.codeToString(403));
+ assertEquals("Not Found", ResourceException.codeToString(404));
+ assertEquals("Conflict", ResourceException.codeToString(409));
+ assertEquals("Gone", ResourceException.codeToString(410));
+ assertEquals("Precondition Failed", ResourceException.codeToString(412));
+ assertEquals("Unsupported Media Type", ResourceException.codeToString(415));
+ assertEquals("Internal Server Error", ResourceException.codeToString(500));
+ assertEquals("Not Implemented", ResourceException.codeToString(501));
+ assertEquals("1001", ResourceException.codeToString(1001));
+ }
+
+ @Test
+ public void testCodeOnly() {
+
+ ResourceException exc = new ResourceException(400);
+ assertEquals(exc.getData().toString(), "{code: 400, message: \"Bad Request\"}");
+ }
+
+ @Test
+ public void testGetData() {
+
+ ResourceException exc = new ResourceException(400, "Invalid domain name");
+ assertEquals(exc.getData(), "Invalid domain name");
+ }
+
+ @Test
+ public void testGetDataCast() {
+
+ ResourceException exc = new ResourceException(400, new Integer(5000));
+ assertEquals(exc.getData(Integer.class), new Integer(5000));
+ }
+}
diff --git a/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSAuthorizerTest.java b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSAuthorizerTest.java
new file mode 100644
index 00000000000..a3a327d4675
--- /dev/null
+++ b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSAuthorizerTest.java
@@ -0,0 +1,349 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.yahoo.athenz.auth.Authority;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+import com.yahoo.athenz.zms.ZMSAuthorizer;
+
+import static org.testng.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.mockito.Mockito;
+
+public class ZMSAuthorizerTest {
+
+ private static String ZMS_CLIENT_PROP_TEST_ADMIN = "athenz.zms.client.test_admin";
+ private static final String AUDIT_REF = "zmsjcltauthtest";
+
+ private String systemAdminUser = null;
+ private String systemAdminFullUser = null;
+ private final String zmsUrl = "http://localhost:10080/";
+
+ @BeforeClass
+ public void setup() {
+ systemAdminUser = System.getProperty(ZMS_CLIENT_PROP_TEST_ADMIN, "user_admin");
+ systemAdminFullUser = "user." + systemAdminUser;
+ System.setProperty(ZMSClient.ZMS_CLIENT_PROP_ATHENZ_CONF, "src/test/resources/athenz.conf");
+ }
+
+ @Test
+ public void testAuthorizer() {
+
+ ZMSClient client = getClient(systemAdminUser);
+ String domain = "AuthorizerDom1";
+ ZMSAuthorizer authorizer = new ZMSAuthorizer(zmsUrl, domain);
+ assertNotNull(authorizer);
+
+ // create 3 user client objects
+
+ Principal p1 = createPrincipal("user1");
+ Principal p2 = createPrincipal("user2");
+ Principal p3 = createPrincipal("user3");
+
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class)))
+ .thenReturn(domainMock);
+
+ setupAccess(client, domain);
+
+ // only user1 and user3 have access to UPDATE/resource1
+ ZMSClient mockZMSClient = Mockito.mock(ZMSClient.class);
+ authorizer.setZMSClient(mockZMSClient);
+ Access accessMock = Mockito.mock(Access.class);
+ Mockito.when(mockZMSClient.getAccess("UPDATE", "AuthorizerDom1:resource1", "AuthorizerDom1"))
+ .thenReturn(accessMock, accessMock, accessMock);
+ Mockito.when(accessMock.getGranted()).thenReturn(true, true, false, false, true, true);
+ Mockito.when(c.getAccess("UPDATE", "AuthorizerDom1:resource1", "AuthorizerDom1", null)).thenReturn(accessMock);
+
+ boolean access = authorizer.access("UPDATE", "resource1", p1, domain);
+ assertTrue(access);
+
+ // we're going to use a principal token as well to test this access
+
+ String principalToken1 = "v=U1;d=user;n=user1;s=signature";
+ access = authorizer.access("UPDATE", "resource1", principalToken1, domain);
+ assertTrue(access);
+
+ access = authorizer.access("UPDATE", "resource1", p2, domain);
+ assertFalse(access);
+
+ String principalToken2 = "v=U1;d=user;n=user2;s=signature";
+ access = authorizer.access("UPDATE", "resource1", principalToken2, domain);
+ assertFalse(access);
+
+ access = authorizer.access("UPDATE", "resource1", p3, domain);
+ assertTrue(access);
+
+ String principalToken3 = "v=U1;d=user;n=user3;s=signature";
+ access = authorizer.access("UPDATE", "resource1", principalToken3, domain);
+ assertTrue(access);
+
+ // we should get exception with no principal
+ try {
+ authorizer.access("UPDATE", "resource1", (Principal) null, domain);
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ // we should get exception with no principal token
+
+ try {
+ authorizer.access("UPDATE", "resource1", (String) null, domain);
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ TopLevelDomain topLevelDomainMock = Mockito.mock(TopLevelDomain.class);
+ Mockito.when(c.deleteTopLevelDomain(domain, AUDIT_REF)).thenReturn(topLevelDomainMock);
+ cleanUpAccess(domain);
+ }
+
+ @Test
+ public void testAuthorizerNoEndpoint() {
+ String domain = "AuthorizerDom2";
+ ZMSAuthorizer authorizer = new ZMSAuthorizer(domain);
+ assertNotNull(authorizer);
+ }
+
+ @Test
+ public void TestAddCredentials() {
+ ZMSClient client = getClient(systemAdminUser);
+ String domain = "AuthorizerDom5";
+ ZMSAuthorizer authorizer = new ZMSAuthorizer(zmsUrl, null);
+
+ Principal p1 = createPrincipal("user1");
+ Principal p2 = createPrincipal("user2");
+ Principal p3 = createPrincipal("user3");
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class)))
+ .thenReturn(domainMock);
+
+ setupAccess(client, domain);
+ ZMSClient mockZMSClient = Mockito.mock(ZMSClient.class);
+ authorizer.setZMSClient(mockZMSClient);
+
+ Access accessMock = Mockito.mock(Access.class);
+ Mockito.when(mockZMSClient.getAccess("UPDATE", "AuthorizerDom3:resource1", "AuthorizerDom3"))
+ .thenReturn(accessMock);
+ Mockito.when(accessMock.getGranted()).thenReturn(true, false, true);
+ Mockito.when(c.getAccess("UPDATE", "AuthorizerDom3:resource1", "AuthorizerDom3", null)).thenReturn(accessMock);
+ try {
+ Mockito.when(mockZMSClient.addCredentials(p1)).thenThrow(new ResourceException(204));
+ authorizer.access("UPDATE", domain + ":resource1", p1, domain);
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ try {
+ Mockito.when(mockZMSClient.addCredentials(p2)).thenThrow(new ZMSClientException(204, "No Content"));
+ authorizer.access("UPDATE", domain + ":resource1", p2, domain);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ Mockito.when(mockZMSClient.addCredentials(p3)).thenThrow(new ZMSClientException(404, "Not Found"));
+ authorizer.access("UPDATE", domain + ":resource1", p3, domain);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ authorizer.close();
+ }
+
+ @Test
+ public void TestAuthorizerNoDomain() {
+ ZMSClient client = getClient(systemAdminUser);
+ String domain = "AuthorizerDom3";
+ ZMSAuthorizer authorizer = new ZMSAuthorizer(zmsUrl, null);
+ assertNotNull(authorizer);
+
+ // create 3 user client objects
+
+ Principal p1 = createPrincipal("user1");
+ Principal p2 = createPrincipal("user2");
+ Principal p3 = createPrincipal("user3");
+
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class)))
+ .thenReturn(domainMock);
+
+ setupAccess(client, domain);
+ ZMSClient mockZMSClient = Mockito.mock(ZMSClient.class);
+ authorizer.setZMSClient(mockZMSClient);
+
+ // only user1 and user3 have access to UPDATE/resource1
+ Access accessMock = Mockito.mock(Access.class);
+ Mockito.when(mockZMSClient.getAccess("UPDATE", "AuthorizerDom3:resource1", "AuthorizerDom3"))
+ .thenReturn(accessMock);
+ Mockito.when(accessMock.getGranted()).thenReturn(true, false, true);
+ Mockito.when(c.getAccess("UPDATE", "AuthorizerDom3:resource1", "AuthorizerDom3", null)).thenReturn(accessMock);
+ boolean access = authorizer.access("UPDATE", domain + ":resource1", p1, domain);
+ assertTrue(access);
+
+ access = authorizer.access("UPDATE", domain + ":resource1", p2, domain);
+ assertFalse(access);
+
+ access = authorizer.access("UPDATE", domain + ":resource1", p3, domain);
+ assertTrue(access);
+ TopLevelDomain topLevelDomainMock = Mockito.mock(TopLevelDomain.class);
+ Mockito.when(c.deleteTopLevelDomain(domain, AUDIT_REF)).thenReturn(topLevelDomainMock);
+ authorizer.close();
+ cleanUpAccess(domain);
+ }
+
+ @Test
+ public void TestAuthorizerResourceWithDomain() {
+ ZMSClient client = getClient(systemAdminUser);
+ String domain = "AuthorizerDom4";
+ ZMSAuthorizer authorizer = new ZMSAuthorizer(zmsUrl, domain);
+ assertNotNull(authorizer);
+
+ // create 3 user client objects
+
+ Principal p1 = createPrincipal("user1");
+ Principal p2 = createPrincipal("user2");
+ Principal p3 = createPrincipal("user3");
+
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class)))
+ .thenReturn(domainMock);
+ setupAccess(client, domain);
+
+ // only user1 and user3 have access to UPDATE/resource1
+ ZMSClient mockZMSClient = Mockito.mock(ZMSClient.class);
+ authorizer.setZMSClient(mockZMSClient);
+ Access accessMock = Mockito.mock(Access.class);
+ Mockito.when(mockZMSClient.getAccess("UPDATE", "AuthorizerDom4:resource1", "AuthorizerDom4"))
+ .thenReturn(accessMock);
+ Mockito.when(accessMock.getGranted()).thenReturn(true, false, true);
+ Mockito.when(c.getAccess("UPDATE", "AuthorizerDom4:resource1", "AuthorizerDom4", null)).thenReturn(accessMock);
+ boolean access = authorizer.access("UPDATE", domain + ":resource1", p1, domain);
+ assertTrue(access);
+
+ access = authorizer.access("UPDATE", domain + ":resource1", p2, domain);
+ assertFalse(access);
+
+ access = authorizer.access("UPDATE", domain + ":resource1", p3, domain);
+ assertTrue(access);
+
+ TopLevelDomain topLevelDomainMock = Mockito.mock(TopLevelDomain.class);
+ Mockito.when(c.deleteTopLevelDomain(domain, AUDIT_REF)).thenReturn(topLevelDomainMock);
+ cleanUpAccess(domain);
+
+ }
+
+ private Role createRoleObject(ZMSClient client, String domainName, String roleName, String trust, String member1,
+ String member2) {
+
+ Role role = new Role();
+ role.setName(client.generateRoleName(domainName, roleName));
+ role.setTrust(trust);
+
+ List members = new ArrayList();
+ members.add(member1);
+ if (member2 != null) {
+ members.add(member2);
+ }
+ role.setMembers(members);
+ return role;
+ }
+
+ private Policy createPolicyObject(ZMSClient client, String domainName, String policyName, String roleName,
+ String action, String resource, AssertionEffect effect) {
+
+ Policy policy = new Policy();
+ policy.setName(client.generatePolicyName(domainName, policyName));
+
+ Assertion assertion = new Assertion();
+ assertion.setAction(action);
+ assertion.setEffect(effect);
+ assertion.setResource(resource);
+ assertion.setRole(client.generateRoleName(domainName, roleName));
+
+ List assertList = new ArrayList();
+ assertList.add(assertion);
+
+ policy.setAssertions(assertList);
+ return policy;
+ }
+
+ private TopLevelDomain createTopLevelDomainObject(String name, String description, String org, String admin) {
+
+ TopLevelDomain dom = new TopLevelDomain();
+ dom.setName(name);
+ dom.setDescription(description);
+ dom.setOrg(org);
+ dom.setEnabled(true);
+ dom.setYpmId(2000);
+
+ List admins = new ArrayList();
+ admins.add(admin);
+ dom.setAdminUsers(admins);
+ return dom;
+ }
+
+ private Principal createPrincipal(String userName) {
+ Authority authority = new com.yahoo.athenz.auth.impl.PrincipalAuthority();
+ Principal p = SimplePrincipal.create("user", userName, "v=U1;d=user;n=" + userName + ";s=signature", 0,
+ authority);
+ return p;
+ }
+
+ private ZMSClient getClient(String userName) {
+ ZMSClient client = new ZMSClient(zmsUrl);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ client.addCredentials(createPrincipal(userName));
+ return client;
+ }
+
+ private void setupAccess(ZMSClient client, String domain) {
+ TopLevelDomain dom1 = createTopLevelDomainObject(domain, "Test Domain1", "testOrg", systemAdminFullUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Role role1 = createRoleObject(client, domain, "Role1", null, "user.user1", "user.user3");
+ client.putRole(domain, "Role1", AUDIT_REF, role1);
+
+ Policy policy1 = createPolicyObject(client, domain, "Policy1", "Role1", "UPDATE", domain + ":resource1",
+ AssertionEffect.ALLOW);
+ client.putPolicy(domain, "Policy1", AUDIT_REF, policy1);
+ }
+
+ private void cleanUpAccess(String domain) {
+ ZMSClient client = getClient(systemAdminUser);
+ client.deleteTopLevelDomain(domain, AUDIT_REF);
+ }
+}
diff --git a/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientMockTest.java b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientMockTest.java
new file mode 100644
index 00000000000..a67b26484a4
--- /dev/null
+++ b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientMockTest.java
@@ -0,0 +1,1100 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import java.util.List;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.rdl.Struct;
+import com.yahoo.rdl.Timestamp;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import org.testng.annotations.BeforeMethod;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Matchers;
+import org.testng.annotations.Test;
+
+public class ZMSClientMockTest {
+
+ @Mock ZMSRDLGeneratedClient mockZMS;
+
+ ZMSClient zclt;
+ String zmsUrl = "";
+ List userList;
+ String auditRef = "zmsjcltmktest";
+
+ static final Struct TABLE_PROVIDER_ROLE_ACTIONS = new Struct()
+ .with("admin", "*").with("writer", "WRITE").with("reader", "READ");
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ Mockito.doReturn(new DomainList()).when(mockZMS).getDomainList(Matchers.isA(Integer.class),
+ Matchers.isA(String.class), Matchers.isA(String.class), Matchers.isA(Integer.class),
+ Matchers.isA(String.class), Matchers.isA(Integer.class), Matchers.isA(String.class),
+ Matchers.isA(String.class), Matchers.isA(String.class));
+ userList = new ArrayList();
+ userList.add("user.johnny");
+ zclt = new ZMSClient(zmsUrl);
+ zclt.client = mockZMS;
+ }
+
+ @Test
+ public void testDomain() throws Exception {
+
+ String domName = "testdom";
+ Mockito.doReturn(new Domain()).when(mockZMS).getDomain(domName);
+ Mockito.doReturn(new DomainList()).when(mockZMS).getDomainList(null, null, null,
+ null, null, null, null, null, null);
+
+ DomainList domList = zclt.getDomainList();
+ assertNotNull(domList);
+
+ Domain dom = zclt.getDomain(domName);
+ assertNotNull(dom);
+
+ try {
+ TopLevelDomain tld = new TopLevelDomain().setName(domName).setOrg("testOrg")
+ .setDescription("test domain").setAdminUsers(userList);
+ dom = zclt.postTopLevelDomain(auditRef, tld);
+
+ DomainMeta meta = new DomainMeta();
+ zclt.putDomainMeta(domName, auditRef, meta);
+
+ zclt.deleteTopLevelDomain(domName, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testDomainListModifiedSince() throws Exception {
+
+ DomainList domList = new DomainList();
+ List domains = new ArrayList<>();
+ domains.add("dom1");
+ domList.setNames(domains);
+
+ Date now = new Date();
+ DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz");
+ String modifiedSince = df.format(now);
+ Mockito.doReturn(domList).when(mockZMS).getDomainList(null, null, null,
+ null, null, null, null, null, modifiedSince);
+
+ DomainList domainList = zclt.getDomainList(null, null, null,
+ null, null, null, now);
+ assertNotNull(domainList);
+ assertTrue(domainList.getNames().contains("dom1"));
+ }
+
+ @Test
+ public void testSubDomain() throws Exception {
+
+ String parentName = "parentdom";
+ String subDomName = "childdom";
+
+ try {
+ SubDomain subDom = new SubDomain();
+ zclt.postSubDomain(parentName, auditRef, subDom);
+ zclt.deleteSubDomain(parentName, subDomName, auditRef);
+
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testUserDomain() throws Exception {
+
+ String userDomName = "userid";
+
+ try {
+ UserDomain userDom = new UserDomain();
+ userDom.setName(userDomName);
+
+ zclt.postUserDomain(userDomName, auditRef, userDom);
+ zclt.deleteUserDomain(userDomName, auditRef);
+
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testGetUserToken() throws Exception {
+
+ String uname = "johnny";
+ Mockito.doReturn(new UserToken()).when(mockZMS).getUserToken(uname, null);
+ Mockito.doReturn(new UserToken()).when(mockZMS).getUserToken(uname, "coretech.storage");
+
+ UserToken utok = zclt.getUserToken(uname);
+ assertNotNull(utok);
+
+ utok = zclt.getUserToken(uname, "coretech.storage");
+ assertNotNull(utok);
+
+ utok = zclt.getUserToken(uname, "sports.hockey");
+ assertNull(utok);
+ }
+
+ @Test
+ public void testPolicy() throws Exception {
+
+ String domName = "johnnies-place";
+ String polName = "chefs";
+ Mockito.doReturn(new Policy()).when(mockZMS).getPolicy(domName, polName);
+ Mockito.doReturn(new PolicyList()).when(mockZMS).getPolicyList(domName, null, null);
+
+ ZMSClient zmsclt2 = new ZMSClient(zmsUrl);
+ zmsclt2.client = mockZMS;
+
+ PolicyList polList = zmsclt2.getPolicyList(domName);
+ assertNotNull(polList);
+
+ Policy pol = zmsclt2.getPolicy(domName, polName);
+ assertNotNull(pol);
+
+ try {
+ zmsclt2.putPolicy(domName, polName, auditRef, pol);
+ zmsclt2.deletePolicy(domName, polName, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ zmsclt2.close();
+ }
+
+ @Test
+ public void testRole() throws Exception {
+
+ String domName = "johnnies-place";
+ String roleName = "manager";
+ Mockito.doReturn(new Role()).when(mockZMS).getRole(domName, roleName, false, false);
+ Mockito.doReturn(new RoleList()).when(mockZMS).getRoleList(domName, null, null);
+
+ RoleList roleList = zclt.getRoleList(domName);
+ assertNotNull(roleList);
+
+ Role role = zclt.getRole(domName, roleName);
+ assertNotNull(role);
+
+ try {
+ zclt.putRole(domName, roleName, auditRef, role);
+ zclt.deletePolicy(domName, roleName, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testRoleChangeLog() throws Exception {
+
+ String domName = "johnnies-place";
+ String roleName = "manager";
+ Role retRole = new Role();
+ retRole.setName(domName + ":role." + roleName);
+
+ List auditLogList = new ArrayList<>();
+ RoleAuditLog logEntry = new RoleAuditLog();
+ logEntry.setAction("ADD").setAdmin("user.admin").setMember("user.user1")
+ .setAuditRef("").setCreated(Timestamp.fromCurrentTime());
+ auditLogList.add(logEntry);
+
+ logEntry = new RoleAuditLog();
+ logEntry.setAction("DELETE").setAdmin("user.admin").setMember("user.user2")
+ .setAuditRef("audit-ref").setCreated(Timestamp.fromCurrentTime());
+ auditLogList.add(logEntry);
+
+ retRole.setAuditLog(auditLogList);
+ Mockito.doReturn(retRole).when(mockZMS).getRole(domName, roleName, true, false);
+
+ Role role = zclt.getRole(domName, roleName, true);
+ assertNotNull(role);
+ List logList = role.getAuditLog();
+ assertNotNull(logList);
+ assertEquals(logList.size(), 2);
+ }
+
+ @Test
+ public void testRoleExpand() throws Exception {
+
+ String domName = "role-expand";
+ String roleName = "manager";
+
+ Role retRoleExpand = new Role();
+ retRoleExpand.setName(domName + ":role." + roleName);
+ retRoleExpand.setTrust("trusted-domain");
+ List members = new ArrayList<>();
+ members.add("user.user1");
+ members.add("coretech.service");
+ retRoleExpand.setMembers(members);
+
+ Role retRoleNoExpand = new Role();
+ retRoleNoExpand.setName(domName + ":role." + roleName);
+ retRoleNoExpand.setTrust("trusted-domain");
+
+ Mockito.doReturn(retRoleExpand).when(mockZMS).getRole(domName, roleName, false, true);
+ Mockito.doReturn(retRoleNoExpand).when(mockZMS).getRole(domName, roleName, false, false);
+
+ // first request with expand option set
+
+ Role role = zclt.getRole(domName, roleName, false, true);
+ assertNotNull(role);
+ assertEquals(role.getTrust(), "trusted-domain");
+ assertNotNull(role.getMembers());
+ assertEquals(role.getMembers().size(), 2);
+ assertTrue(role.getMembers().contains("user.user1"));
+ assertTrue(role.getMembers().contains("coretech.service"));
+
+ // next without expand option
+
+ role = zclt.getRole(domName, roleName, false, false);
+ assertNotNull(role);
+ assertEquals(role.getTrust(), "trusted-domain");
+ assertNull(role.getMembers());
+ }
+
+ @Test
+ public void testGetRoles() throws Exception {
+
+ String domName = "roles-members";
+
+ Role trustRole = new Role();
+ trustRole.setName(domName + ":role.trust-role");
+ trustRole.setTrust("trusted-domain");
+
+ Role groupRoleWithMembers = new Role();
+ groupRoleWithMembers.setName(domName + ":role.group-role");
+ List members = new ArrayList<>();
+ members.add("user.user1");
+ members.add("coretech.service");
+ groupRoleWithMembers.setMembers(members);
+
+ Role groupRoleWithoutMembers = new Role();
+ groupRoleWithoutMembers.setName(domName + ":role.group-role");
+
+ List retListWithMembers = new ArrayList<>();
+ retListWithMembers.add(groupRoleWithMembers);
+ retListWithMembers.add(trustRole);
+ Roles retRolesWithMembers = new Roles().setList(retListWithMembers);
+
+ List retListWithoutMembers = new ArrayList<>();
+ retListWithoutMembers.add(groupRoleWithoutMembers);
+ retListWithoutMembers.add(trustRole);
+ Roles retRolesWithoutMembers = new Roles().setList(retListWithoutMembers);
+
+ Mockito.doReturn(retRolesWithMembers).when(mockZMS).getRoles(domName, true);
+ Mockito.doReturn(retRolesWithoutMembers).when(mockZMS).getRoles(domName, false);
+
+ // first request with members option set
+
+ Roles roles = zclt.getRoles(domName, true);
+ assertNotNull(roles);
+ assertNotNull(roles.getList());
+
+ boolean groupRoleCheck = false;
+ boolean trustRoleCheck = false;
+ for (Role role : roles.getList()) {
+ switch (role.getName()) {
+ case "roles-members:role.trust-role":
+ assertEquals(role.getTrust(), "trusted-domain");
+ assertNull(role.getMembers());
+ trustRoleCheck = true;
+ break;
+ case "roles-members:role.group-role":
+ assertNull(role.getTrust());
+ assertNotNull(role.getMembers());
+ assertEquals(role.getMembers().size(), 2);
+ assertTrue(role.getMembers().contains("user.user1"));
+ assertTrue(role.getMembers().contains("coretech.service"));
+ groupRoleCheck = true;
+ break;
+ }
+ }
+ assertTrue(groupRoleCheck);
+ assertTrue(trustRoleCheck);
+
+ // next without members option
+
+ roles = zclt.getRoles(domName, false);
+ assertNotNull(roles);
+ assertNotNull(roles.getList());
+
+ groupRoleCheck = false;
+ trustRoleCheck = false;
+ for (Role role : roles.getList()) {
+ switch (role.getName()) {
+ case "roles-members:role.trust-role":
+ assertEquals(role.getTrust(), "trusted-domain");
+ assertNull(role.getMembers());
+ trustRoleCheck = true;
+ break;
+ case "roles-members:role.group-role":
+ assertNull(role.getTrust());
+ assertNull(role.getMembers());
+ groupRoleCheck = true;
+ break;
+ }
+ }
+ assertTrue(groupRoleCheck);
+ assertTrue(trustRoleCheck);
+ }
+
+ @Test
+ public void testPutTenancyResourceGroup() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerService = "coretech.storage";
+ String resourceGroup = "hockey";
+ TenancyResourceGroup tenantResourceGroup = new TenancyResourceGroup();
+ tenantResourceGroup.setDomain(tenantDomain).setService(providerService).setResourceGroup(resourceGroup);
+ Mockito.doReturn(null)
+ .when(mockZMS).putTenancyResourceGroup(tenantDomain, providerService, resourceGroup,
+ auditRef, tenantResourceGroup);
+
+ try {
+ zclt.putTenancyResourceGroup(tenantDomain, providerService,
+ resourceGroup, auditRef, tenantResourceGroup);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testDeleteTenancyResourceGroup() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerService = "coretech.storage";
+ String resourceGroup = "hockey";
+ Mockito.doReturn(null)
+ .when(mockZMS).deleteTenancyResourceGroup(tenantDomain, providerService, resourceGroup, auditRef);
+
+ try {
+ zclt.deleteTenancyResourceGroup(tenantDomain, providerService,
+ resourceGroup, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testPutTenantResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles();
+ tenantRoles.setTenant(tenantDomain).setDomain(providerDomain).setService(providerService)
+ .setResourceGroup(resourceGroup);
+
+ List roleActions = new ArrayList();
+ for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
+ roleActions.add(new TenantRoleAction().setRole(f.name()).setAction(
+ (String) f.value()));
+ }
+ tenantRoles.setRoles(roleActions);
+ Mockito.doReturn(null)
+ .when(mockZMS).putTenantResourceGroupRoles(providerDomain, providerService, tenantDomain,
+ resourceGroup, auditRef, tenantRoles);
+
+ try {
+ zclt.putTenantResourceGroupRoles(providerDomain, providerService,
+ tenantDomain, resourceGroup, auditRef, tenantRoles);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testDeleteTenantResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles();
+ tenantRoles.setTenant(tenantDomain).setDomain(providerDomain).setService(providerService)
+ .setResourceGroup(resourceGroup);
+
+ Mockito.doReturn(null)
+ .when(mockZMS).deleteTenantResourceGroupRoles(providerDomain, providerService, tenantDomain,
+ resourceGroup, auditRef);
+
+ try {
+ zclt.deleteTenantResourceGroupRoles(providerDomain, providerService, tenantDomain,
+ resourceGroup, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testGetTenantResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles();
+ tenantRoles.setTenant(tenantDomain).setDomain(providerDomain).setService(providerService)
+ .setResourceGroup(resourceGroup);
+
+ List roleActions = new ArrayList();
+ for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
+ roleActions.add(new TenantRoleAction().setRole(f.name()).setAction(
+ (String) f.value()));
+ }
+ tenantRoles.setRoles(roleActions);
+ Mockito.doReturn(tenantRoles)
+ .when(mockZMS).getTenantResourceGroupRoles(providerDomain,
+ providerService, tenantDomain, resourceGroup);
+
+ TenantResourceGroupRoles retRoles = null;
+ try {
+ retRoles = zclt.getTenantResourceGroupRoles(providerDomain,
+ providerService, tenantDomain, resourceGroup);
+ } catch (Exception exc) {
+ fail();
+ }
+
+ assertNotNull(retRoles);
+ assertEquals(tenantDomain, retRoles.getTenant());
+ assertEquals(providerDomain, retRoles.getDomain());
+ assertEquals(providerService, retRoles.getService());
+ assertEquals(resourceGroup, retRoles.getResourceGroup());
+
+ // try to get unknown resource group that would return null
+
+ try {
+ retRoles = zclt.getTenantResourceGroupRoles(providerDomain,
+ providerService, tenantDomain, "baseball");
+ } catch (Exception exc) {
+ fail();
+ }
+
+ assertNull(retRoles);
+ }
+
+ @Test
+ public void testPutProviderResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ ProviderResourceGroupRoles provRoles = new ProviderResourceGroupRoles();
+ provRoles.setTenant(tenantDomain).setDomain(providerDomain)
+ .setService(providerService).setResourceGroup(resourceGroup);
+
+ List roleActions = new ArrayList();
+ for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
+ roleActions.add(new TenantRoleAction().setRole(f.name()).setAction(
+ (String) f.value()));
+ }
+ provRoles.setRoles(roleActions);
+ Mockito.doReturn(null)
+ .when(mockZMS).putProviderResourceGroupRoles(tenantDomain, providerDomain, providerService,
+ resourceGroup, auditRef, provRoles);
+
+ try {
+ zclt.putProviderResourceGroupRoles(tenantDomain, providerDomain, providerService,
+ resourceGroup, auditRef, provRoles);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testDeleteProviderResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ ProviderResourceGroupRoles provRoles = new ProviderResourceGroupRoles();
+ provRoles.setTenant(tenantDomain).setDomain(providerDomain)
+ .setService(providerService).setResourceGroup(resourceGroup);
+
+ Mockito.doReturn(null)
+ .when(mockZMS).deleteProviderResourceGroupRoles(tenantDomain, providerDomain, providerService,
+ resourceGroup, auditRef);
+
+ try {
+ zclt.deleteProviderResourceGroupRoles(tenantDomain, providerDomain, providerService,
+ resourceGroup, auditRef);
+ } catch (Exception exc) {
+ fail();
+ }
+ }
+
+ @Test
+ public void testGetProviderResourceGroupRoles() throws Exception {
+
+ String tenantDomain = "tenant";
+ String providerDomain = "coretech";
+ String providerService = "storage";
+ String resourceGroup = "hockey";
+ ProviderResourceGroupRoles provRoles = new ProviderResourceGroupRoles();
+ provRoles.setTenant(tenantDomain).setDomain(providerDomain)
+ .setService(providerService).setResourceGroup(resourceGroup);
+
+ List roleActions = new ArrayList();
+ for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
+ roleActions.add(new TenantRoleAction().setRole(f.name()).setAction(
+ (String) f.value()));
+ }
+ provRoles.setRoles(roleActions);
+ Mockito.doReturn(provRoles)
+ .when(mockZMS).getProviderResourceGroupRoles(tenantDomain, providerDomain, providerService, resourceGroup);
+
+ ProviderResourceGroupRoles retRoles = null;
+ try {
+ retRoles = zclt.getProviderResourceGroupRoles(tenantDomain, providerDomain, providerService, resourceGroup);
+ } catch (Exception exc) {
+ fail();
+ }
+
+ assertNotNull(retRoles);
+ assertEquals(tenantDomain, retRoles.getTenant());
+ assertEquals(providerDomain, retRoles.getDomain());
+ assertEquals(providerService, retRoles.getService());
+ assertEquals(resourceGroup, retRoles.getResourceGroup());
+
+ // try to get unknown resource group that would return null
+
+ try {
+ retRoles = zclt.getProviderResourceGroupRoles(tenantDomain, providerDomain, providerService, "baseball");
+ } catch (Exception exc) {
+ fail();
+ }
+
+ assertNull(retRoles);
+ }
+
+ @Test
+ public void testGetTemplate() throws Exception {
+
+ Template template = new Template();
+ Role role = new Role().setName("role1").setTrust("trust-domain");
+ List roleList = new ArrayList<>();
+ roleList.add(role);
+ template.setRoles(roleList);
+ Policy policy = new Policy().setName("policy1");
+ List policyList = new ArrayList<>();
+ policyList.add(policy);
+ template.setPolicies(policyList);
+
+ Mockito.doReturn(template).when(mockZMS).getTemplate("vipng");
+
+ Template solTemplate = zclt.getTemplate("vipng");
+ assertNotNull(solTemplate);
+ List solRoles = solTemplate.getRoles();
+ assertNotNull(solRoles);
+ assertEquals(1, solRoles.size());
+ assertEquals("role1", solRoles.get(0).getName());
+ assertEquals("trust-domain", solRoles.get(0).getTrust());
+
+ List solPolicies = solTemplate.getPolicies();
+ assertNotNull(solPolicies);
+ assertEquals(1, solPolicies.size());
+ assertEquals("policy1", solPolicies.get(0).getName());
+ }
+
+ @Test
+ public void testGetServerTemplateList() throws Exception {
+ ServerTemplateList templateList = new ServerTemplateList();
+ List names = new ArrayList<>();
+ names.add("vipng");
+ names.add("mh2");
+ templateList.setTemplateNames(names);
+
+ Mockito.doReturn(templateList).when(mockZMS).getServerTemplateList();
+
+ ServerTemplateList solTemplateList = zclt.getServerTemplateList();
+ assertNotNull(solTemplateList);
+ assertEquals(2, solTemplateList.getTemplateNames().size());
+ assertTrue(solTemplateList.getTemplateNames().contains("mh2"));
+ assertTrue(solTemplateList.getTemplateNames().contains("vipng"));
+ }
+
+ @Test
+ public void testGetDomainTemplateList() throws Exception {
+ DomainTemplateList templateList = new DomainTemplateList();
+ List names = new ArrayList<>();
+ names.add("vipng");
+ names.add("mh2");
+ templateList.setTemplateNames(names);
+
+ Mockito.doReturn(templateList).when(mockZMS).getDomainTemplateList("iaas.athenz");
+
+ DomainTemplateList domTemplateList = zclt.getDomainTemplateList("iaas.athenz");
+ assertNotNull(domTemplateList);
+ assertEquals(2, domTemplateList.getTemplateNames().size());
+ assertTrue(domTemplateList.getTemplateNames().contains("mh2"));
+ assertTrue(domTemplateList.getTemplateNames().contains("vipng"));
+ }
+
+ @Test
+ public void testGetPrincipal() {
+
+ ServicePrincipal svcPrincipal = new ServicePrincipal().setDomain("coretech").setService("storage");
+ Mockito.doReturn(svcPrincipal).when(mockZMS).getServicePrincipal();
+
+ Principal principal = zclt.getPrincipal("v=U1;d=coretech;n=storage;s=signature");
+ assertNotNull(principal);
+ assertTrue(principal.getName().equals("storage"));
+ assertTrue(principal.getDomain().equals("coretech"));
+ }
+
+ @Test
+ public void testDomainListByAccount() throws Exception {
+
+ DomainList domList = new DomainList();
+ List domains = new ArrayList<>();
+ domains.add("dom1");
+ domList.setNames(domains);
+
+ DomainList domEmptyList = new DomainList();
+
+ Mockito.doReturn(domList).when(mockZMS).getDomainList(null, null, null, null,
+ "1234", null, null, null, null);
+ Mockito.doReturn(domEmptyList).when(mockZMS).getDomainList(null, null, null, null,
+ "1235", null, null, null, null);
+
+ DomainList domainList = zclt.getDomainList(null, null, null, null, "1234", null, null);
+ assertNotNull(domainList);
+ assertTrue(domainList.getNames().contains("dom1"));
+
+ domainList = zclt.getDomainList(null, null, null, null, "1235", null, null);
+ assertNotNull(domainList);
+ assertNull(domainList.getNames());
+ }
+
+ @Test
+ public void testDomainListByProductId() throws Exception {
+
+ DomainList domList = new DomainList();
+ List domains = new ArrayList<>();
+ domains.add("dom1");
+ domList.setNames(domains);
+
+ DomainList domEmptyList = new DomainList();
+
+ Mockito.doReturn(domList).when(mockZMS).getDomainList(null, null, null, null, null,
+ Integer.valueOf(101), null, null, null);
+ Mockito.doReturn(domEmptyList).when(mockZMS).getDomainList(null, null, null, null, null,
+ Integer.valueOf(102), null, null, null);
+
+ DomainList domainList = zclt.getDomainList(null, null, null, null, null, Integer.valueOf(101), null);
+ assertNotNull(domainList);
+ assertTrue(domainList.getNames().contains("dom1"));
+
+ domainList = zclt.getDomainList(null, null, null, null, null, Integer.valueOf(102), null);
+ assertNotNull(domainList);
+ assertNull(domainList.getNames());
+ }
+
+ @Test
+ public void testDomainListByRole() throws Exception {
+
+ DomainList domList = new DomainList();
+ List domains = new ArrayList<>();
+ domains.add("dom1");
+ domList.setNames(domains);
+
+ DomainList domEmptyList = new DomainList();
+
+ Mockito.doReturn(domList).when(mockZMS).getDomainList(null, null, null, null, null,
+ null, "user.user1", "admin", null);
+ Mockito.doReturn(domEmptyList).when(mockZMS).getDomainList(null, null, null, null, null,
+ null, "user.user2", "admin", null);
+
+ DomainList domainList = zclt.getDomainList("user.user1", "admin");
+ assertNotNull(domainList);
+ assertTrue(domainList.getNames().contains("dom1"));
+
+ domainList = zclt.getDomainList("user.user2", "admin");
+ assertNotNull(domainList);
+ assertNull(domainList.getNames());
+ }
+
+ @Test
+ public void testEntityList() {
+
+ String domName = "johnnies-place";
+ List names = new ArrayList<>();
+ names.add("entity1");
+ names.add("entity2");
+ EntityList entList = new EntityList().setNames(names);
+
+ Mockito.doReturn(entList).when(mockZMS).getEntityList(domName);
+
+ EntityList list = zclt.getEntityList(domName);
+ assertNotNull(list);
+ List ents = list.getNames();
+ assertEquals(ents.size(), 2);
+ assertTrue(ents.contains("entity1"));
+ assertTrue(ents.contains("entity2"));
+ }
+
+ @Test
+ public void testGetResourceAccessList() throws Exception {
+
+ ResourceAccessList rsrcEmptyList = new ResourceAccessList();
+
+ ResourceAccessList rsrcList = new ResourceAccessList();
+
+ ResourceAccess rsrcAccess = new ResourceAccess();
+ rsrcAccess.setPrincipal("user.user");
+ Assertion assertion = new Assertion().setAction("update").setRole("athenz:role.role1").setResource("athenz:resource1");
+ List assertions = new ArrayList<>();
+ assertions.add(assertion);
+ rsrcAccess.setAssertions(assertions);
+
+ List resources = new ArrayList<>();
+ resources.add(rsrcAccess);
+
+ rsrcList.setResources(resources);
+
+ Mockito.doReturn(rsrcList).when(mockZMS).getResourceAccessList("user.user", "update");
+ Mockito.doReturn(rsrcEmptyList).when(mockZMS).getResourceAccessList("user.user1", "create");
+
+ ResourceAccessList rsrcAccessList = zclt.getResourceAccessList("user.user", "update");
+ assertNotNull(rsrcAccessList);
+ assertEquals(rsrcAccessList.getResources().size(), 1);
+
+ rsrcAccess = rsrcAccessList.getResources().get(0);
+ assertEquals(rsrcAccess.getPrincipal(), "user.user");
+
+ rsrcAccessList = zclt.getResourceAccessList("user.user1", "create");
+ assertNotNull(rsrcAccessList);
+ assertNull(rsrcAccessList.getResources());
+ }
+
+ @Test
+ public void testGetPolicies() throws Exception {
+
+ final String domName = "get-policies";
+
+ Policy policyWithAssertions = new Policy();
+ policyWithAssertions.setName(domName + ":policy.assert-policy");
+ policyWithAssertions.setModified(Timestamp.fromCurrentTime());
+ List assertions = new ArrayList<>();
+ Assertion assertion = new Assertion()
+ .setAction("update")
+ .setEffect(AssertionEffect.ALLOW)
+ .setId((long) 101)
+ .setResource(domName + ":*")
+ .setRole("admin");
+ assertions.add(assertion);
+ policyWithAssertions.setAssertions(assertions);
+
+ Policy policyWithOutAssertions = new Policy();
+ policyWithOutAssertions.setName(domName + ":policy.no-assert-policy");
+ policyWithOutAssertions.setModified(Timestamp.fromCurrentTime());
+
+ List retListWithAssertions = new ArrayList<>();
+ retListWithAssertions.add(policyWithAssertions);
+ Policies retPoliciesWithAssertions = new Policies().setList(retListWithAssertions);
+
+ List retListWithOutAssertions = new ArrayList<>();
+ retListWithOutAssertions.add(policyWithOutAssertions);
+ Policies retPoliciesWithOutAssertions = new Policies().setList(retListWithOutAssertions);
+
+ Mockito.doReturn(retPoliciesWithAssertions).when(mockZMS).getPolicies(domName, true);
+ Mockito.doReturn(retPoliciesWithOutAssertions).when(mockZMS).getPolicies(domName, false);
+
+ // first request with assertions option set
+
+ Policies policies = zclt.getPolicies(domName, true);
+ assertNotNull(policies);
+ assertNotNull(policies.getList());
+
+ boolean policyCheck = false;
+ for (Policy policy : policies.getList()) {
+ switch (policy.getName()) {
+ case "get-policies:policy.assert-policy":
+ assertNotNull(policy.getModified());
+ List testAssertions = policy.getAssertions();
+ assertNotNull(testAssertions);
+ assertEquals(testAssertions.size(), 1);
+ assertEquals(testAssertions.get(0).getAction(), "update");
+ policyCheck = true;
+ break;
+ }
+ }
+ assertTrue(policyCheck);
+
+ // next without assertions option
+
+ policies = zclt.getPolicies(domName, false);
+ assertNotNull(policies);
+ assertNotNull(policies.getList());
+
+ policyCheck = false;
+ for (Policy policy : policies.getList()) {
+ switch (policy.getName()) {
+ case "get-policies:policy.no-assert-policy":
+ assertNotNull(policy.getModified());
+ assertNull(policy.getAssertions());
+ policyCheck = true;
+ break;
+ }
+ }
+ assertTrue(policyCheck);
+ }
+
+ @Test
+ public void testGetServices() throws Exception {
+
+ final String domName = "get-services";
+
+ ServiceIdentity serviceWithKeysHosts = new ServiceIdentity();
+ serviceWithKeysHosts.setName(domName + ".service-key-host")
+ .setGroup("users")
+ .setExecutable("/usr/bin/jetty")
+ .setModified(Timestamp.fromCurrentTime())
+ .setUser("root");
+ List publicKeys = new ArrayList<>();
+ PublicKeyEntry publicKey = new PublicKeyEntry().setId("0").setKey("key");
+ publicKeys.add(publicKey);
+ serviceWithKeysHosts.setPublicKeys(publicKeys);
+
+ List hosts = new ArrayList<>();
+ hosts.add("host1");
+ serviceWithKeysHosts.setHosts(hosts);
+
+ ServiceIdentity serviceWithKeysOnly = new ServiceIdentity();
+ serviceWithKeysOnly.setName(domName + ".service-key-only")
+ .setGroup("users")
+ .setExecutable("/usr/bin/jetty")
+ .setModified(Timestamp.fromCurrentTime())
+ .setUser("root")
+ .setPublicKeys(publicKeys);
+
+ ServiceIdentity serviceWithHostsOnly = new ServiceIdentity();
+ serviceWithHostsOnly.setName(domName + ".service-host-only")
+ .setGroup("users")
+ .setExecutable("/usr/bin/jetty")
+ .setModified(Timestamp.fromCurrentTime())
+ .setUser("root")
+ .setHosts(hosts);
+
+ List retListWithKeysHosts = new ArrayList<>();
+ retListWithKeysHosts.add(serviceWithKeysHosts);
+ ServiceIdentities retServicesWithKeysHosts = new ServiceIdentities().setList(retListWithKeysHosts);
+
+ List retListWithKeysOnly = new ArrayList<>();
+ retListWithKeysOnly.add(serviceWithKeysOnly);
+ ServiceIdentities retServicesWithKeysOnly = new ServiceIdentities().setList(retListWithKeysOnly);
+
+ List retListWithHostsOnly = new ArrayList<>();
+ retListWithHostsOnly.add(serviceWithHostsOnly);
+ ServiceIdentities retServicesWithHostsOnly = new ServiceIdentities().setList(retListWithHostsOnly);
+
+ Mockito.doReturn(retServicesWithKeysHosts).when(mockZMS).getServiceIdentities(domName, true, true);
+ Mockito.doReturn(retServicesWithKeysOnly).when(mockZMS).getServiceIdentities(domName, true, false);
+ Mockito.doReturn(retServicesWithHostsOnly).when(mockZMS).getServiceIdentities(domName, false, true);
+
+ // first request with keys and hosts option set
+
+ ServiceIdentities services = zclt.getServiceIdentities(domName, true, true);
+ assertNotNull(services);
+ assertNotNull(services.getList());
+
+ boolean serviceCheck = false;
+ for (ServiceIdentity service : services.getList()) {
+ switch (service.getName()) {
+ case "get-services.service-key-host":
+ assertNotNull(service.getModified());
+ List testPublicKeys = service.getPublicKeys();
+ assertNotNull(testPublicKeys);
+ assertEquals(testPublicKeys.size(), 1);
+ assertEquals(testPublicKeys.get(0).getId(), "0");
+ assertEquals(testPublicKeys.get(0).getKey(), "key");
+ List testHosts = service.getHosts();
+ assertNotNull(testHosts);
+ assertEquals(testHosts.size(), 1);
+ assertEquals(testHosts.get(0), "host1");
+ serviceCheck = true;
+ break;
+ }
+ }
+ assertTrue(serviceCheck);
+
+ // next with only key option
+
+ services = zclt.getServiceIdentities(domName, true, false);
+ assertNotNull(services);
+ assertNotNull(services.getList());
+
+ serviceCheck = false;
+ for (ServiceIdentity service : services.getList()) {
+ switch (service.getName()) {
+ case "get-services.service-key-only":
+ assertNotNull(service.getModified());
+ List testPublicKeys = service.getPublicKeys();
+ assertNotNull(testPublicKeys);
+ assertEquals(testPublicKeys.size(), 1);
+ assertEquals(testPublicKeys.get(0).getId(), "0");
+ assertEquals(testPublicKeys.get(0).getKey(), "key");
+ assertNull(service.getHosts());
+ serviceCheck = true;
+ break;
+ }
+ }
+ assertTrue(serviceCheck);
+
+ // next with only host option
+
+ services = zclt.getServiceIdentities(domName, false, true);
+ assertNotNull(services);
+ assertNotNull(services.getList());
+
+ serviceCheck = false;
+ for (ServiceIdentity service : services.getList()) {
+ switch (service.getName()) {
+ case "get-services.service-host-only":
+ assertNotNull(service.getModified());
+ assertNull(service.getPublicKeys());
+ List testHosts = service.getHosts();
+ assertNotNull(testHosts);
+ assertEquals(testHosts.size(), 1);
+ assertEquals(testHosts.get(0), "host1");
+ serviceCheck = true;
+ break;
+ }
+ }
+ assertTrue(serviceCheck);
+ }
+
+ @Test
+ public void testGetAssertion() throws Exception {
+
+ final String domName = "get-assertion";
+ Assertion assertion = new Assertion()
+ .setAction("update")
+ .setEffect(AssertionEffect.ALLOW)
+ .setId((long) 101)
+ .setResource(domName + ":*")
+ .setRole("admin");
+
+ Mockito.doReturn(assertion).when(mockZMS).getAssertion(domName, "policy1", new Long(101));
+ Mockito.doThrow(new ResourceException(404)).when(mockZMS).getAssertion(domName, "policy1", new Long(202));
+
+ // first invalid test cases
+
+ // unknown policy name
+ Assertion testAssertion = zclt.getAssertion(domName, "policy2", new Long(101));
+ assertNull(testAssertion);
+
+ // unknown domain name
+
+ testAssertion = zclt.getAssertion("unknown", "policy1", new Long(101));
+ assertNull(testAssertion);
+
+ // unknown assertion id
+
+ testAssertion = zclt.getAssertion(domName, "policy1", new Long(102));
+ assertNull(testAssertion);
+
+ // exception unit test
+
+ try {
+ zclt.getAssertion(domName, "policy1", new Long(202));
+ fail();
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 404);
+ }
+
+ // now valid case
+
+ testAssertion = zclt.getAssertion(domName, "policy1", new Long(101));
+ assertNotNull(testAssertion);
+ assertEquals(assertion.getAction(), "update");
+ assertEquals((long) assertion.getId(), (long) 101);
+ }
+
+ @Test
+ public void testDeleteAssertion() throws Exception {
+
+ final String domName = "delete-assertion";
+
+ Mockito.doReturn(null).when(mockZMS).deleteAssertion(domName, "policy1", new Long(101), auditRef);
+ Mockito.doThrow(new ResourceException(403)).when(mockZMS).deleteAssertion(domName, "policy1", new Long(202), auditRef);
+
+ // first valid case should complete successfully
+
+ zclt.deleteAssertion(domName, "policy1", new Long(101), auditRef);
+
+ // now this should throw an exception
+
+ try {
+ zclt.deleteAssertion(domName, "policy1", new Long(202), auditRef);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 403);
+ }
+ }
+
+ @Test
+ public void testPutAssertion() throws Exception {
+
+ final String domName = "put-assertion";
+ Assertion assertion = new Assertion()
+ .setAction("update")
+ .setEffect(AssertionEffect.ALLOW)
+ .setResource(domName + ":*")
+ .setRole("admin");
+
+ Assertion retAssertion = new Assertion()
+ .setAction("update")
+ .setEffect(AssertionEffect.ALLOW)
+ .setId((long) 101)
+ .setResource(domName + ":*")
+ .setRole("admin");
+
+ Mockito.doReturn(retAssertion).when(mockZMS).putAssertion(domName, "policy1", auditRef, assertion);
+ Mockito.doThrow(new ResourceException(403)).when(mockZMS).putAssertion(domName, "policy2", auditRef, assertion);
+
+ // first valid case should complete successfully
+
+ Assertion checkAssertion = zclt.putAssertion(domName, "policy1", auditRef, assertion);
+ assertEquals(checkAssertion.getId(), Long.valueOf(101));
+
+ // now this should throw an exception
+
+ try {
+ zclt.putAssertion(domName, "policy2", auditRef, assertion);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 403);
+ }
+ }
+}
+
diff --git a/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientTest.java b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientTest.java
new file mode 100644
index 00000000000..338fa823211
--- /dev/null
+++ b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSClientTest.java
@@ -0,0 +1,2076 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.yahoo.athenz.auth.Authority;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+import com.yahoo.rdl.Array;
+import com.yahoo.rdl.Struct;
+
+import static org.testng.Assert.*;
+
+import org.mockito.Mockito;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ZMSClientTest {
+
+ private String systemAdminUser = null;
+ private String systemAdminFullUser = null;
+ private static String ZMS_CLIENT_PROP_ZMS_URL = "athenz.zms.client.zms_url";
+ private static String ZMS_CLIENT_PROP_TEST_ADMIN = "athenz.zms.client.test_admin";
+
+ private static final String PUB_KEY_ZONE1 = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BM"
+ + "EdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDMXRHU1ZDQTh3bDVldzVZNzZXajJySkFVRA"
+ + "pZYW5FSmZLbUFseDVjUS84aEtFVWZTU2dwWHIzQ3pkaDFhMjZkbGI3bW1LMjlxbVhKWGg2dW1XOUF"
+ + "5ZlRPS1ZvCis2QVNsb1ZVM2F2dnVmbEdVT0VnMmpzbWRha1IyNEtjTGpBdTZRclVlNDE3bEczdDhx"
+ + "U1BJR2pTNUMrQ3NKVXcKaDA0aEh4NWYrUEV3eFY0cmJRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLR"
+ + "VktLS0tLQo-";
+ private static final String PUB_KEY_ZONE2 = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRW"
+ + "UpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTDRnNlF1bGVRcG42bytpSmorK09nenNZM3hXekhHUw"
+ + "p4ZW1xZzZhdkkvbHhvT3Jzd2h4YW93MjMrR3AxZXhOWEdzQlNsTkFQSXh5N3RHTXZaRnY0Q3ZrQ0F"
+ + "3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-";
+
+ private boolean printURL = true;
+
+ static final Struct TABLE_PROVIDER_ROLE_ACTIONS = new Struct()
+ .with("admin", "*").with("writer", "WRITE").with("reader", "READ");
+
+ private static String AUDIT_REF = "zmsjcltest";
+
+ static final int BASE_PRODUCT_ID = 100000000; // these product id's will lie in 100 million range
+ static java.util.Random domainProductId = new java.security.SecureRandom();
+
+ static synchronized int getRandomProductId() {
+ return BASE_PRODUCT_ID + domainProductId.nextInt(99999999);
+ }
+
+ @BeforeClass
+ public void setup() {
+ System.setProperty(ZMS_CLIENT_PROP_ZMS_URL, "http://localhost:10080/");
+
+ systemAdminUser = System.getProperty(ZMS_CLIENT_PROP_TEST_ADMIN, "user_admin");
+ systemAdminFullUser = "user." + systemAdminUser;
+ }
+
+ private Principal createPrincipal(String userName) {
+ Authority authority = new com.yahoo.athenz.auth.impl.PrincipalAuthority();
+ Principal p = SimplePrincipal.create("user", userName,
+ "v=U1;d=user;n=" + userName + ";s=signature", 0, authority);
+ return p;
+ }
+
+ private DomainMeta createDomainMetaObject(String description, String org, boolean auditEnabled) {
+
+ DomainMeta meta = new DomainMeta();
+ meta.setDescription(description);
+ meta.setOrg(org);
+ meta.setAuditEnabled(auditEnabled);
+
+ return meta;
+ }
+
+ private ZMSClient createClient(String userName) {
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ client.addCredentials(createPrincipal(userName));
+
+ if (printURL) {
+ System.out.println("ZMS Url set to: " + client.getZmsUrl());
+ printURL = false;
+ }
+
+ return client;
+ }
+
+ private String getZMSUrl() {
+
+ // if we're given a config setting then use that
+
+ String zmsUrl = System.getProperty(ZMS_CLIENT_PROP_ZMS_URL);
+
+ // if the value is not available then check the env setting
+
+ if (zmsUrl == null) {
+ zmsUrl = System.getenv("ZMS_URL");
+ }
+
+ return zmsUrl;
+ }
+
+ private TopLevelDomain createTopLevelDomainObject(String name,
+ String description, String org, String admin) {
+
+ TopLevelDomain dom = new TopLevelDomain();
+ dom.setName(name);
+ dom.setDescription(description);
+ dom.setOrg(org);
+ dom.setEnabled(true);
+ dom.setYpmId(getRandomProductId());
+
+ List admins = new ArrayList();
+ admins.add(admin);
+ dom.setAdminUsers(admins);
+
+ return dom;
+ }
+
+ private SubDomain createSubDomainObject(String name, String parent,
+ String description, String org, String admin) {
+
+ SubDomain dom = new SubDomain();
+ dom.setName(name);
+ dom.setDescription(description);
+ dom.setOrg(org);
+ dom.setParent(parent);
+ dom.setEnabled(true);
+
+ List admins = new ArrayList();
+ admins.add(admin);
+ dom.setAdminUsers(admins);
+
+ return dom;
+ }
+
+ private Role createRoleObject(ZMSClient client, String domainName, String roleName,
+ String trust, String member1, String member2) {
+
+ Role role = new Role();
+ role.setName(client.generateRoleName(domainName, roleName));
+ role.setTrust(trust);
+
+ List members = new ArrayList();
+ members.add(member1);
+ if (member2 != null) {
+ members.add(member2);
+ }
+ role.setMembers(members);
+ return role;
+ }
+
+ private Policy createPolicyObject(ZMSClient client, String domainName, String policyName,
+ String roleName, String action, String resource, AssertionEffect effect) {
+
+ Policy policy = new Policy();
+ policy.setName(client.generatePolicyName(domainName, policyName));
+
+ Assertion assertion = new Assertion();
+ assertion.setAction(action);
+ assertion.setEffect(effect);
+ assertion.setResource(resource);
+ assertion.setRole(client.generateRoleName(domainName, roleName));
+
+ List assertList = new ArrayList();
+ assertList.add(assertion);
+
+ policy.setAssertions(assertList);
+ return policy;
+ }
+
+ private Policy createPolicyObject(ZMSClient client, String domainName, String policyName) {
+ return createPolicyObject(client, domainName, policyName, "Role1", "*", domainName + ":*", AssertionEffect.ALLOW);
+ }
+
+ private ServiceIdentity createServiceObject(ZMSClient client, String domainName,
+ String serviceName, String endPoint, String executable, String user,
+ String group, String host) {
+
+ ServiceIdentity service = new ServiceIdentity();
+ service.setExecutable(executable);
+ service.setName(client.generateServiceIdentityName(domainName, serviceName));
+
+ List pubKeys = new ArrayList<>();
+ pubKeys.add(new PublicKeyEntry().setId("0")
+ .setKey("LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTk"
+ + "FEQ0JpUUtCZ1FDMXRHU1ZDQTh3bDVldzVZNzZXajJySkFVRApZYW5FSmZLbUFseDVjUS84aEtFVWZTU2dwWHI"
+ + "zQ3pkaDFhMjZkbGI3bW1LMjlxbVhKWGg2dW1XOUF5ZlRPS1ZvCis2QVNsb1ZVM2F2dnVmbEdVT0VnMmpzbWRh"
+ + "a1IyNEtjTGpBdTZRclVlNDE3bEczdDhxU1BJR2pTNUMrQ3NKVXcKaDA0aEh4NWYrUEV3eFY0cmJRSURBUUFCC"
+ + "i0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"));
+
+ service.setPublicKeys(pubKeys);
+
+ service.setUser(user);
+ service.setGroup(group);
+
+ service.setProviderEndpoint(endPoint);
+
+ List hosts = new ArrayList();
+ hosts.add(host);
+ service.setHosts(hosts);
+
+ return service;
+ }
+
+ private ServiceIdentity createServiceObjectWithZoneKeys(ZMSClient client, String domainName,
+ String serviceName, String endPoint, String executable, String user,
+ String group, String host) {
+
+ ServiceIdentity service = new ServiceIdentity();
+ service.setExecutable(executable);
+ service.setGroup(group);
+ service.setName(client.generateServiceIdentityName(domainName, serviceName));
+ service.setUser(user);
+
+ List pubKeys = new ArrayList<>();
+
+ PublicKeyEntry key1 = new PublicKeyEntry();
+ key1.setId("zone1");
+ key1.setKey(PUB_KEY_ZONE1);
+
+ PublicKeyEntry key2 = new PublicKeyEntry();
+ key2.setId("zone2");
+ key2.setKey(PUB_KEY_ZONE2);
+
+ pubKeys.add(key1);
+ pubKeys.add(key2);
+ service.setPublicKeys(pubKeys);
+
+ service.setProviderEndpoint(endPoint);
+
+ List hosts = new ArrayList();
+ hosts.add(host);
+ service.setHosts(hosts);
+
+ return service;
+ }
+
+ private Entity createEntityObject(ZMSClient client, String entityName) {
+
+ Entity entity = new Entity();
+ entity.setName(entityName);
+
+ Struct value = new Struct();
+ value.put("Key1", "Value1");
+ entity.setValue(value);
+
+ return entity;
+ }
+
+ private Tenancy createTenantObject(String domain, String service) {
+
+ Tenancy tenant = new Tenancy();
+ tenant.setDomain(domain);
+ tenant.setService(service);
+
+ return tenant;
+ }
+
+ private void testCreateTopLevelDomain(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddTopDom1",
+ "Test Domain1", "testOrg", adminUser);
+ Domain resDom1 = client.postTopLevelDomain(AUDIT_REF, dom1);
+ assertNotNull(resDom1);
+
+ Domain resDom2 = client.getDomain("AddTopDom1");
+ assertNotNull(resDom2);
+
+ try {
+ client.getDomain("AddTopDom3");
+ fail();
+ } catch(ResourceException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ client.getDomain("AddTopDom3");
+ fail();
+ } catch(ResourceException ex) {
+ assertTrue(true);
+ }
+
+ client.deleteTopLevelDomain("AddTopDom1", AUDIT_REF);
+ }
+
+ private void testCreateTopLevelDomainOnceOnly(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddOnceTopDom1",
+ "Test Domain1", "testOrg", adminUser);
+ Domain resDom1 = client.postTopLevelDomain(AUDIT_REF, dom1);
+ assertNotNull(resDom1);
+
+ // we should get an exception for the second call
+
+ try {
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ client.deleteTopLevelDomain("AddOnceTopDom1", AUDIT_REF);
+ }
+
+ private void testCreateSubDomain(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddSubDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ SubDomain dom2 = createSubDomainObject("AddSubDom2", "AddSubDom1",
+ "Test Domain2", "testOrg", adminUser);
+ Domain resDom1 = client.postSubDomain("AddSubDom1", AUDIT_REF, dom2);
+ assertNotNull(resDom1);
+ try {
+ client.postSubDomain("AddSubDom3", AUDIT_REF, dom2);
+ fail();
+ } catch(ResourceException ex) {
+ assertTrue(true);
+ }
+
+ Domain resDom2 = client.getDomain("AddSubDom1.AddSubDom2");
+ assertNotNull(resDom2);
+
+ client.deleteSubDomain("AddSubDom1", "AddSubDom2", AUDIT_REF);
+
+ client.deleteTopLevelDomain("AddSubDom1", AUDIT_REF);
+ }
+
+ private void testCreateSubdomainOnceOnly(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddOnceSubDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ SubDomain dom2 = createSubDomainObject("AddOnceSubDom2", "AddOnceSubDom1",
+ "Test Domain2", "testOrg", adminUser);
+ Domain resDom1 = client.postSubDomain("AddOnceSubDom1", AUDIT_REF, dom2);
+ assertNotNull(resDom1);
+
+ // we should get an exception for the second call
+
+ try {
+ client.postSubDomain("AddOnceSubDom1", AUDIT_REF, dom2);
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ client.deleteSubDomain("AddOnceSubDom1", "AddOnceSubDom2", AUDIT_REF);
+ client.deleteTopLevelDomain("AddOnceSubDom1", AUDIT_REF);
+ }
+
+ private void testCreateRole(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("CreateRoleDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Role role1 = createRoleObject(client, "CreateRoleDom1", "Role1", null, "user.joe", "user.jane");
+ client.putRole("CreateRoleDom1", "Role1", AUDIT_REF, role1);
+
+ Role role3 = client.getRole("CreateRoleDom1", "Role1");
+ assertNotNull(role3);
+ assertEquals(role3.getName(), "CreateRoleDom1:role.Role1".toLowerCase());
+ assertNull(role3.getTrust());
+
+ try {
+ client.putRole("CreateRoleDom1", "Role2", AUDIT_REF, role1);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ client.putRole("CreateRoleDom1", "Role3", AUDIT_REF, role1);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ client.getRole("CreateRoleDom1", "Role2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ client.getRole("CreateRoleDom1", "Role3");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ client.deleteTopLevelDomain("CreateRoleDom1", AUDIT_REF);
+ }
+
+ private void testAddMembership(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("MbrAddDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Role role1 = createRoleObject(client, "MbrAddDom1", "Role1", null, "user.joe", "user.jane");
+ client.putRole("MbrAddDom1", "Role1", AUDIT_REF, role1);
+ client.putMembership("MbrAddDom1", "Role1", "user.doe", AUDIT_REF);
+ Role role = client.getRole("MbrAddDom1", "Role1");
+ assertNotNull(role);
+
+ List members = role.getMembers();
+ assertNotNull(members);
+ assertEquals(members.size(), 3);
+
+ assertTrue(members.contains("user.joe"));
+ assertTrue(members.contains("user.jane"));
+ assertTrue(members.contains("user.doe"));
+
+ client.deleteTopLevelDomain("MbrAddDom1", AUDIT_REF);
+ }
+
+ private void testDeleteMembership(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("MbrDelDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Role role1 = createRoleObject(client, "MbrDelDom1", "Role1", null, "user.joe", "user.jane");
+ client.putRole("MbrDelDom1", "Role1", AUDIT_REF, role1);
+ client.deleteMembership("MbrDelDom1", "Role1", "user.joe", AUDIT_REF);
+
+ Role role = client.getRole("MbrDelDom1", "Role1");
+ assertNotNull(role);
+
+ List members = role.getMembers();
+ assertNotNull(members);
+ assertEquals(members.size(), 1);
+
+ assertFalse(members.contains("user.joe"));
+ assertTrue(members.contains("user.jane"));
+
+ client.deleteTopLevelDomain("MbrDelDom1", AUDIT_REF);
+ }
+
+ private void testCreatePolicy(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("PolicyAddDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Policy policy1 = createPolicyObject(client, "PolicyAddDom1", "Policy1");
+ client.putPolicy("PolicyAddDom1", "Policy1", AUDIT_REF, policy1);
+
+ Policy policyRes2 = client.getPolicy("PolicyAddDom1", "Policy1");
+ assertNotNull(policyRes2);
+ assertEquals(policyRes2.getName(), "PolicyAddDom1:policy.Policy1".toLowerCase());
+
+ client.deleteTopLevelDomain("PolicyAddDom1", AUDIT_REF);
+ }
+
+ private void testDeletePolicy(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("PolicyDelDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Policy policy1 = createPolicyObject(client, "PolicyDelDom1", "Policy1");
+ client.putPolicy("PolicyDelDom1", "Policy1", AUDIT_REF, policy1);
+
+ Policy policy2 = createPolicyObject(client, "PolicyDelDom1", "Policy2");
+ client.putPolicy("PolicyDelDom1", "Policy2", AUDIT_REF, policy2);
+
+ Policy policyRes1 = client.getPolicy("PolicyDelDom1", "Policy1");
+ assertNotNull(policyRes1);
+
+ Policy policyRes2 = client.getPolicy("PolicyDelDom1", "Policy2");
+ assertNotNull(policyRes2);
+
+ client.deletePolicy("PolicyDelDom1", "Policy1", AUDIT_REF);
+
+ // we need to get an exception here
+ try {
+ client.getPolicy("PolicyDelDom1", "Policy1");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ policyRes2 = client.getPolicy("PolicyDelDom1", "Policy2");
+ assertNotNull(policyRes2);
+
+ client.deletePolicy("PolicyDelDom1", "Policy2", AUDIT_REF);
+
+ // we need to get an exception here
+ try {
+ client.getPolicy("PolicyDelDom1", "Policy1");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ // we need to get an exception here
+ try {
+ client.getPolicy("PolicyDelDom1", "Policy2");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ client.deleteTopLevelDomain("PolicyDelDom1", AUDIT_REF);
+ }
+
+ private void testCreateServiceIdentity(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("ServiceAddDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ ServiceIdentity service = createServiceObject(client, "ServiceAddDom1", "Service1",
+ "http://localhost", "/usr/bin/java", "root", "users", "host1");
+
+ client.putServiceIdentity("ServiceAddDom1", "Service1", AUDIT_REF, service);
+
+ ServiceIdentity serviceRes2 = client.getServiceIdentity("ServiceAddDom1", "Service1");
+ assertNotNull(serviceRes2);
+ assertEquals(serviceRes2.getName(), "ServiceAddDom1.Service1".toLowerCase());
+
+ client.deleteTopLevelDomain("ServiceAddDom1", AUDIT_REF);
+ }
+
+ private void testDeletePublicKeyEntry(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("DelPublicKeyDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ ServiceIdentity service = createServiceObjectWithZoneKeys(client, "DelPublicKeyDom1", "Service1",
+ "http://localhost", "/usr/bin/java", "root", "users", "host1");
+
+ client.putServiceIdentity("DelPublicKeyDom1", "Service1", AUDIT_REF, service);
+
+ client.deletePublicKeyEntry("DelPublicKeyDom1", "Service1", "zone1", AUDIT_REF);
+
+ try {
+ client.getPublicKeyEntry("DelPublicKeyDom1", "Service1", "zone1");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 404);
+ }
+
+ PublicKeyEntry entry = client.getPublicKeyEntry("DelPublicKeyDom1", "Service1", "zone2");
+ assertNotNull(entry);
+ assertEquals(entry.getKey(), PUB_KEY_ZONE2);
+
+ // we are not allowed to delete the last public key
+
+ try {
+ client.deletePublicKeyEntry("DelPublicKeyDom1", "Service1", "zone2", AUDIT_REF);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 400);
+ }
+
+ client.deleteTopLevelDomain("DelPublicKeyDom1", AUDIT_REF);
+ }
+
+ private void testCreateEntity(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("CreateEntityDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Entity entity1 = createEntityObject(client, "Entity1");
+ client.putEntity("CreateEntityDom1", "Entity1", AUDIT_REF, entity1);
+
+ Entity entity2 = client.getEntity("CreateEntityDom1", "Entity1");
+ assertNotNull(entity2);
+ assertEquals(entity2.getName(), "Entity1".toLowerCase());
+
+ client.deleteTopLevelDomain("CreateEntityDom1", AUDIT_REF);
+ }
+
+ private void testDeleteEntity(ZMSClient client, String adminUser) {
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("DelEntityDom1",
+ "Test Domain1", "testOrg", adminUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ Entity entity1 = createEntityObject(client, "Entity1");
+ client.putEntity("DelEntityDom1", "Entity1", AUDIT_REF, entity1);
+
+ Entity entity2 = createEntityObject(client, "Entity2");
+ client.putEntity("DelEntityDom1", "Entity2", AUDIT_REF, entity2);
+
+ Entity entityRes = client.getEntity("DelEntityDom1", "Entity1");
+ assertNotNull(entityRes);
+
+ entityRes = client.getEntity("DelEntityDom1", "Entity2");
+ assertNotNull(entityRes);
+
+ client.deleteEntity("DelEntityDom1", "Entity1", AUDIT_REF);
+
+ try {
+ entityRes = client.getEntity("DelEntityDom1", "Entity1");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ entityRes = client.getEntity("DelEntityDom1", "Entity2");
+ assertNotNull(entityRes);
+
+ client.deleteEntity("DelEntityDom1", "Entity2", AUDIT_REF);
+
+ try {
+ entityRes = client.getEntity("DelEntityDom1", "Entity1");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ try {
+ entityRes = client.getEntity("DelEntityDom1", "Entity2");
+ fail();
+ } catch (Exception ex) {
+ assertTrue(true);
+ }
+
+ client.deleteTopLevelDomain("DelEntityDom1", AUDIT_REF);
+ }
+
+ // Unit Tests for ZMS Java Client
+
+ @Test
+ public void testClientNoAuth() {
+ ZMSClient client = new ZMSClient("http://localhost:10080/zms/v1");
+ assertNotNull(client);
+ }
+
+ @Test
+ public void testClientOnlyUrl() {
+ String zmsUrl = getZMSUrl();
+ ZMSClient client = new ZMSClient(zmsUrl);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ assertNotNull(client);
+
+ // verify we can get domain list
+ DomainList domainListMock = Mockito.mock(DomainList.class);
+ Mockito.when(client.getDomainList()).thenReturn(domainListMock).thenThrow(new ResourceException(400));
+ DomainList domList = client.getDomainList();
+ assertNotNull(domList);
+ try {
+ client.getDomainList();
+ fail();
+ } catch(ResourceException ex) {
+ assertTrue(true);
+ }
+
+ // verify we can't add a domain
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("OnlyUrlDomain",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+ try {
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1)).thenThrow(new ResourceException(400));
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testClientInvalidPort() {
+ String zmsUrl = "http://localhost:11080/zms/v1";
+ ZMSClient client = new ZMSClient(zmsUrl);
+ assertNotNull(client);
+
+ // verify we can't get domain list and try some
+ // other operations which should all return
+ // zms client exceptions
+
+ try {
+ client.getDomainList();
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ TopLevelDomain dom1 = createTopLevelDomainObject("OnlyUrlDomain",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ client.getAccess("UPDATE", "AccessDom1:resource1", "AccessDom1");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testClientUrlPrincipal() {
+
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ assertNotNull(client);
+
+ // verify we can get domain list
+ DomainList domainListMock = Mockito.mock(DomainList.class);
+ Mockito.when(client.getDomainList()).thenReturn(domainListMock);
+ DomainList domList = client.getDomainList();
+ assertNotNull(domList);
+
+ // verify we can add a domain
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("UrlPrincipalDomain",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1)).thenReturn(domainMock);
+ Domain resDom1 = client.postTopLevelDomain(AUDIT_REF, dom1);
+ assertNotNull(resDom1);
+
+ client.deleteTopLevelDomain("UrlPrincipalDomain", AUDIT_REF);
+ }
+
+ @Test
+ public void testClientClearPrincipal() {
+ String zmsUrl = getZMSUrl();
+ ZMSClient client = new ZMSClient(zmsUrl);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ assertNotNull(client);
+
+ // add credentials
+
+ Authority authority = new com.yahoo.athenz.auth.impl.PrincipalAuthority();
+ Principal p = SimplePrincipal.create("user", systemAdminUser,
+ "v=U1;d=user;n=" + systemAdminUser + ";s=signature", 0, authority);
+
+ client.addCredentials(p);
+
+ // add credentials again
+
+ client.addCredentials(p);
+
+ // verify we can add a domain
+
+ TopLevelDomain dom1 = createTopLevelDomainObject("ClearPrincipalDomain",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1)).thenReturn(domainMock);
+ Domain resDom1 = client.postTopLevelDomain(AUDIT_REF, dom1);
+ assertNotNull(resDom1);
+
+ client.deleteTopLevelDomain("ClearPrincipalDomain", AUDIT_REF);
+
+ // clear the credentials
+
+ client.clearCredentials();
+
+ // verify we can no longer add a new domain
+
+ try {
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1)).thenThrow(new ResourceException(400));
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+
+ // but we should be able to read the domain list
+ DomainList domainListMock = Mockito.mock(DomainList.class);
+ Mockito.when(client.getDomainList()).thenReturn(domainListMock);
+ DomainList domList = client.getDomainList();
+ assertNotNull(domList);
+ }
+
+ @Test
+ public void testClientWithoutEndingSlash() {
+ String zmsUrl = getZMSUrl();
+ if (zmsUrl == null) {
+ zmsUrl = "http://localhost:10080";
+ } else {
+ if (zmsUrl.charAt(zmsUrl.length() - 1) == '/') {
+ zmsUrl = zmsUrl.substring(0, zmsUrl.length() - 1);
+ }
+ }
+
+ ZMSClient client = new ZMSClient(zmsUrl);
+ assertNotNull(client);
+
+ // verify we should be able to read the domain list
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ DomainList domainListMock = Mockito.mock(DomainList.class);
+ Mockito.when(c.getDomainList(null, null, null, null, null, null, null, null, null)).thenReturn(domainListMock);
+ DomainList domList = client.getDomainList();
+ assertNotNull(domList);
+ }
+
+ @Test
+ public void testGetDomainList() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getDomainList(null, null, null, null, null, null, "MemberRole1", "RoleName1", null))
+ .thenThrow(new NullPointerException());
+ client.getDomainList("MemberRole1", "RoleName1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getDomainList(null, null, null, null, null, null, "MemberRole2", "RoleName2", null))
+ .thenThrow(new ResourceException(400));
+ client.getDomainList("MemberRole2", "RoleName2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteSubDomain() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.deleteSubDomain("parent", "domain1", AUDIT_REF)).thenThrow(new NullPointerException());
+ client.deleteSubDomain("parent", "domain1", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteSubDomain("parent", "domain2", AUDIT_REF)).thenThrow(new ResourceException(400));
+ client.deleteSubDomain("parent", "domain2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutTenancyResourceGroup() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TenancyResourceGroup trg = new TenancyResourceGroup().setDomain("test.domain").setService("test-service")
+ .setResourceGroup("test.group");
+ try {
+ Mockito.when(
+ c.putTenancyResourceGroup("TenantDom1", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF, trg))
+ .thenThrow(new NullPointerException());
+ client.putTenancyResourceGroup("TenantDom1", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF, trg);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(
+ c.putTenancyResourceGroup("TenantDom2", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF, trg))
+ .thenThrow(new ResourceException(400));
+ client.putTenancyResourceGroup("TenantDom2", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF, trg);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutTenantResourceGroupRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles();
+ try {
+ Mockito.when(c.putTenantResourceGroupRoles("ProvidorDomain1", "ProvidorService1", "TenantDom1",
+ "ResourceGroup1", AUDIT_REF, tenantRoles)).thenThrow(new NullPointerException());
+ client.putTenantResourceGroupRoles("ProvidorDomain1", "ProvidorService1", "TenantDom1", "ResourceGroup1",
+ AUDIT_REF, tenantRoles);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.putTenantResourceGroupRoles("ProvidorDomain2", "ProvidorService1", "TenantDom1",
+ "ResourceGroup1", AUDIT_REF, tenantRoles)).thenThrow(new ResourceException(400));
+ client.putTenantResourceGroupRoles("ProvidorDomain2", "ProvidorService1", "TenantDom1", "ResourceGroup1",
+ AUDIT_REF, tenantRoles);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetTenantResourceGroupRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getTenantResourceGroupRoles("ProvidorDomain1", "ProvidorService1", "TenantDom1",
+ "ResourceGroup1")).thenThrow(new NullPointerException());
+ client.getTenantResourceGroupRoles("ProvidorDomain1", "ProvidorService1", "TenantDom1", "ResourceGroup1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getTenantResourceGroupRoles("ProvidorDomain2", "ProvidorService1", "TenantDom1",
+ "ResourceGroup1")).thenThrow(new ResourceException(400));
+ client.getTenantResourceGroupRoles("ProvidorDomain2", "ProvidorService1", "TenantDom1", "ResourceGroup1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteTenancyResourceGroup() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.deleteTenancyResourceGroup("TenantDom1", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF))
+ .thenThrow(new NullPointerException());
+ client.deleteTenancyResourceGroup("TenantDom1", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteTenancyResourceGroup("TenantDom2", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF))
+ .thenThrow(new ResourceException(400));
+ client.deleteTenancyResourceGroup("TenantDom2", "DelTenantRolesDom1", "ResourceGroup1", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getRoles("domain1", true)).thenThrow(new NullPointerException());
+ client.getRoles("domain1", true);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getRoles("domain2", true)).thenThrow(new ResourceException(400));
+ client.getRoles("domain2", true);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetPolicies() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getPolicies("domain1", true)).thenThrow(new NullPointerException());
+ client.getPolicies("domain1", true);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getPolicies("domain2", true)).thenThrow(new ResourceException(400));
+ client.getPolicies("domain2", true);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteUserDomain() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.deleteUserDomain("domain1", AUDIT_REF)).thenThrow(new NullPointerException());
+ client.deleteUserDomain("domain1", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteUserDomain("domain2", AUDIT_REF)).thenThrow(new ResourceException(400));
+ client.deleteUserDomain("domain2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutDomainMeta() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ DomainMeta meta = createDomainMetaObject("Test2 Domain", "NewOrg", false);
+ try {
+ Mockito.when(c.putDomainMeta("domain1", AUDIT_REF, meta)).thenThrow(new NullPointerException());
+ client.putDomainMeta("domain1", AUDIT_REF, meta);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.putDomainMeta("domain2", AUDIT_REF, meta)).thenThrow(new ResourceException(400));
+ client.putDomainMeta("domain2", AUDIT_REF, meta);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutDomainTemplate() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ List tempNames = new ArrayList();
+ DomainTemplate domTempl = new DomainTemplate().setTemplateNames(tempNames);
+ try {
+ Mockito.when(c.putDomainTemplate("name1", AUDIT_REF, domTempl)).thenThrow(new NullPointerException());
+ client.putDomainTemplate("name1", AUDIT_REF, domTempl);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.putDomainTemplate("name2", AUDIT_REF, domTempl))
+ .thenThrow(new ResourceException(404, "Domain not found"));
+ client.putDomainTemplate("name2", AUDIT_REF, domTempl);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetResourceAccessList() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getResourceAccessList("principal1", "action1")).thenThrow(new NullPointerException());
+ client.getResourceAccessList("principal1", "action1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getResourceAccessList("principal2", "action2")).thenThrow(new ResourceException(400));
+ client.getResourceAccessList("principal2", "action2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testAssertion() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Assertion assertion = new Assertion();
+ Long assertionId = 18000305032230531L;
+ try {
+ Mockito.when(c.putAssertion("domain1", "policy1", AUDIT_REF, assertion))
+ .thenThrow(new NullPointerException());
+ client.putAssertion("domain1", "policy1", AUDIT_REF, assertion);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getAssertion("principal2", "action2", assertionId)).thenThrow(new NullPointerException());
+ client.getAssertion("principal2", "action2", assertionId);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteAssertion("principal2", "action2", assertionId, AUDIT_REF))
+ .thenThrow(new NullPointerException());
+ client.deleteAssertion("principal2", "action2", assertionId, AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetTemplate() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getTemplate("template")).thenThrow(new NullPointerException());
+ client.getTemplate("template");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getTemplate("template2")).thenThrow(new ResourceException(400));
+ client.getTemplate("template2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetProviderResourceGroupRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.getProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup")).thenThrow(new NullPointerException());
+ client.getProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2")).thenThrow(new ResourceException(400));
+ client.getProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteProviderResourceGroupRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ try {
+ Mockito.when(c.deleteProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup", AUDIT_REF)).thenThrow(new NullPointerException());
+ client.deleteProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2", AUDIT_REF)).thenThrow(new ResourceException(400));
+ client.deleteProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutProviderResourceGroupRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ ProviderResourceGroupRoles provRoles = new ProviderResourceGroupRoles();
+ try {
+ Mockito.when(c.putProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup", AUDIT_REF, provRoles)).thenThrow(new NullPointerException());
+ client.putProviderResourceGroupRoles("tenantDomain", "providerDomain", "providerServiceName",
+ "resourceGroup", AUDIT_REF, provRoles);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.putProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2", AUDIT_REF, provRoles)).thenThrow(new ResourceException(400));
+ client.putProviderResourceGroupRoles("tenantDomain2", "providerDomain2", "providerServiceName2",
+ "resourceGroup2", AUDIT_REF, provRoles);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPostUserDomain() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ UserDomain ud = new UserDomain().setDescription("domain desc").setOrg("org:test").setEnabled(true)
+ .setAuditEnabled(false).setAccount("user.test").setYpmId(10).setName("testuser")
+ .setTemplates(new DomainTemplateList().setTemplateNames(Arrays.asList("template")));
+ try {
+ Mockito.when(c.postUserDomain("domain1", AUDIT_REF, ud)).thenThrow(new NullPointerException());
+ client.postUserDomain("domain1", AUDIT_REF, ud);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.postUserDomain("domain2", AUDIT_REF, ud)).thenThrow(new ResourceException(400));
+ client.postUserDomain("domain2", AUDIT_REF, ud);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testUserTokenWithAuthority() {
+ ZMSClient client = createClient(systemAdminUser);
+ assertNotNull(client);
+ }
+
+ @Test
+ public void testCreateTopLevelDomainUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddTopDom1",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+ Domain domainMock = Mockito.mock(Domain.class);
+ dom1.setAuditEnabled(true);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class))).thenReturn(domainMock);
+ Mockito.when(c.getDomain("AddTopDom1")).thenReturn(domainMock);
+ Mockito.when(c.getDomain("AddTopDom3")).thenThrow(new NullPointerException()).thenThrow(new ResourceException(204));;
+ testCreateTopLevelDomain(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateTopLevelDomainOnceOnlyUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1 = createTopLevelDomainObject("AddTopDom1",
+ "Test Domain1", "testOrg", systemAdminFullUser);
+ Domain domainMock = Mockito.mock(Domain.class);
+ dom1.setAuditEnabled(true);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class))).thenReturn(domainMock).thenThrow(new ResourceException(204));
+ testCreateTopLevelDomainOnceOnly(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateSubDomainUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ SubDomain dom2 = createSubDomainObject("AddSubDom2", "AddSubDom1",
+ "Test Domain2", "testOrg", systemAdminFullUser);
+ Mockito.when(c.postSubDomain("AddSubDom1", AUDIT_REF, dom2)).thenReturn(domainMock);
+ Mockito.when(c.getDomain("AddSubDom1.AddSubDom2")).thenReturn(domainMock);
+ Mockito.when(c.postSubDomain("AddSubDom3", AUDIT_REF, dom2)).thenThrow(new NullPointerException());
+ testCreateSubDomain(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateSubdomainOnceOnlyUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ SubDomain dom2 = createSubDomainObject("AddOnceSubDom2", "AddOnceSubDom1",
+ "Test Domain2", "testOrg", systemAdminFullUser);
+ Mockito.when(c.postSubDomain("AddOnceSubDom1", AUDIT_REF, dom2)).thenReturn(domainMock).thenThrow(new ResourceException(204));
+ testCreateSubdomainOnceOnly(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateRoleUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Role role1Mock = Mockito.mock(Role.class);
+ Role role1 = createRoleObject(client, "CreateRoleDom1", "Role1", null, "user.joe", "user.jane");
+ Mockito.when(c.putRole("CreateRoleDom1", "Role1", AUDIT_REF, role1Mock)).thenReturn(role1Mock);
+ Mockito.when(c.getRole("CreateRoleDom1", "Role1", false, false)).thenReturn(role1Mock);
+ Mockito.when(role1Mock.getName()).thenReturn("CreateRoleDom1:role.Role1".toLowerCase());
+ Mockito.when(role1Mock.getTrust()).thenReturn(null);
+ Mockito.when(c.putRole("CreateRoleDom1", "Role2", AUDIT_REF, role1)).thenThrow(new NullPointerException());
+ Mockito.when(c.putRole("CreateRoleDom1", "Role3", AUDIT_REF, role1)).thenThrow(new ResourceException(400));
+ Mockito.when(c.getRole("CreateRoleDom1", "Role2", false, false)).thenThrow(new NullPointerException());
+ Mockito.when(c.getRole("CreateRoleDom1", "Role3", false, false)).thenThrow(new ResourceException(400));
+ testCreateRole(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testGetRoleList() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ RoleList roleListMock = Mockito.mock(RoleList.class);
+ Mockito.when(c.getRoleList("RoleListParamDom1", null, "Role1")).thenReturn(roleListMock);
+ RoleList roleList = client.getRoleList("RoleListParamDom1", null, "Role1");
+ assertNotNull(roleList);
+ try {
+ Mockito.when(c.getRoleList("RoleListParamDom1", null, "Role2")).thenThrow(new ResourceException(204));
+ client.getRoleList("RoleListParamDom1", null, "Role2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getRoleList("RoleListParamDom2", null, "Role2")).thenThrow(new NullPointerException());
+ client.getRoleList("RoleListParamDom2", null, "Role2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getRoleList("RoleListParamDom1", null, null)).thenThrow(new ResourceException(204));
+ client.getRoleList("RoleListParamDom1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getRoleList("RoleListParamDom2", null, null)).thenThrow(new NullPointerException());
+ client.getRoleList("RoleListParamDom2");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteRole() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Role roleMock = Mockito.mock(Role.class);
+ Mockito.when(c.deleteRole("DelRoleDom1", "Role1", AUDIT_REF)).thenReturn(roleMock);
+ client.deleteRole("DelRoleDom1", "Role1", AUDIT_REF);
+ try {
+ Mockito.when(c.deleteRole("DelRoleDom1", "Role2", AUDIT_REF)).thenThrow(new ResourceException(204));
+ client.deleteRole("DelRoleDom1", "Role2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteRole("DelRoleDom2", "Role2", AUDIT_REF)).thenThrow(new NullPointerException());
+ client.deleteRole("DelRoleDom2", "Role2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetMembership() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Membership member1Mock = Mockito.mock(Membership.class);
+ Mockito.when(c.getMembership("MbrGetRoleDom1", "Role1", "user.joe")).thenReturn(member1Mock);
+ client.getMembership("MbrGetRoleDom1", "Role1", "user.doe");
+ try {
+ Mockito.when(c.getMembership("MbrGetRoleDom1", "Role2", "user.joe")).thenThrow(new ResourceException(204));
+ client.getMembership("MbrGetRoleDom1", "Role2", "user.joe");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ Mockito.when(c.getMembership("MbrGetRoleDom1", "Role3", "user.joe")).thenThrow(new NullPointerException());
+ client.getMembership("MbrGetRoleDom1", "Role3", "user.joe");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetPolicyList() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ PolicyList policyListMock = Mockito.mock(PolicyList.class);
+ Mockito.when(c.getPolicyList("PolicyListDom1", null, null)).thenReturn(policyListMock);
+ client.getPolicyList("PolicyListDom1", null, null);
+ try {
+ Mockito.when(c.getPolicyList("PolicyListDom2", null, null)).thenThrow(new ResourceException(204));
+ client.getPolicyList("PolicyListDom2", null, null);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getPolicyList("PolicyListDom3", null, null)).thenThrow(new ResourceException(204));
+ client.getPolicyList("PolicyListDom3");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ try {
+ Mockito.when(c.getPolicyList("PolicyListDom4", null, null)).thenThrow(new NullPointerException());
+ client.getPolicyList("PolicyListDom4");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getPolicyList("PolicyListDom5", null, null)).thenThrow(new NullPointerException());
+ client.getPolicyList("PolicyListDom5", null, null);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteServiceIdentity() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ ServiceIdentity serviceMock = Mockito.mock(ServiceIdentity.class);
+ Mockito.when(c.deleteServiceIdentity("ServiceDelDom1", "Service1", AUDIT_REF)).thenReturn(serviceMock);
+ client.deleteServiceIdentity("ServiceDelDom1", "Service1", AUDIT_REF);
+ try {
+ Mockito.when(c.deleteServiceIdentity("ServiceDelDom1", "Service2", AUDIT_REF)).thenThrow(new ResourceException(204));
+ client.deleteServiceIdentity("ServiceDelDom1", "Service2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteServiceIdentity("ServiceDelDom2", "Service2", AUDIT_REF))
+ .thenThrow(new NullPointerException());
+ client.deleteServiceIdentity("ServiceDelDom2", "Service2", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetServiceIdentityList() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ ServiceIdentityList serviceListMock = Mockito.mock(ServiceIdentityList.class);
+ Mockito.when(c.getServiceIdentityList("ServiceListParamsDom1", null, "Service1")).thenReturn(serviceListMock);
+ client.getServiceIdentityList("ServiceListParamsDom1", null, "Service1");
+ try {
+ Mockito.when(c.getServiceIdentityList("ServiceListParamsDom2", null, "Service1")).thenThrow(new ResourceException(204));
+ client.getServiceIdentityList("ServiceListParamsDom2", null, "Service1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ Mockito.when(c.getServiceIdentityList("ServiceListParamsDom3", null, null)).thenReturn(serviceListMock);
+ client.getServiceIdentityList("ServiceListParamsDom3");
+ try {
+ Mockito.when(c.getServiceIdentityList("ServiceListParamsDom4", null, null)).thenThrow(new ResourceException(204));
+ client.getServiceIdentityList("ServiceListParamsDom4");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutPublicKeyEntry() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ PublicKeyEntry keyEntry = new PublicKeyEntry();
+ PublicKeyEntry keyEntryMock = Mockito.mock(PublicKeyEntry.class);
+ Mockito.when(c.putPublicKeyEntry("PutPublicKeyDom2", "Service1", "zone2", AUDIT_REF, keyEntry)).thenReturn(keyEntryMock);
+ client.putPublicKeyEntry("PutPublicKeyDom2", "Service1", "zone2", AUDIT_REF, keyEntry);
+
+ try {
+ Mockito.when(c.putPublicKeyEntry("PutPublicKeyDom3", "Service2", "zone2", AUDIT_REF, keyEntry)).thenThrow(new ResourceException(204));
+ client.putPublicKeyEntry("PutPublicKeyDom3", "Service2", "zone2", AUDIT_REF, keyEntry);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetTenancy() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Tenancy tenancyMock = Mockito.mock(Tenancy.class);
+ Mockito.when(c.getTenancy("tenantDom1", "providerService1")).thenReturn(tenancyMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.getTenancy("tenantDom1", "providerService1");
+ try {
+ client.getTenancy("tenantDom1", "providerService1");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getTenancy("tenantDom2", "providerService1")).thenThrow(new NullPointerException());
+ client.getTenancy("tenantDom2", "providerService1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteTenancy() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Tenancy tenancyMock = Mockito.mock(Tenancy.class);
+ Mockito.when(c.deleteTenancy("tenantDom1", "providerService1", AUDIT_REF)).thenReturn(tenancyMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.deleteTenancy("tenantDom1", "providerService1", AUDIT_REF);
+ try {
+ client.deleteTenancy("tenantDom1", "providerService1", AUDIT_REF);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.deleteTenancy("tenantDom2", "providerService1", AUDIT_REF))
+ .thenThrow(new NullPointerException());
+ client.deleteTenancy("tenantDom2", "providerService1", AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutTenantRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TenantRoles tenantRoleMock = Mockito.mock(TenantRoles.class);
+ List roleActions = new ArrayList();
+ for (Struct.Field f : TABLE_PROVIDER_ROLE_ACTIONS) {
+ roleActions.add(new TenantRoleAction().setRole(f.name())
+ .setAction((String) f.value()));
+ }
+ TenantRoles tenantRoles = new TenantRoles().setDomain("ProviderDomain1").setService("storage").setTenant("TenantDomain1").setRoles(roleActions);
+ Mockito.when(c.putTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF, tenantRoles)).thenReturn(tenantRoleMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.putTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF, tenantRoles);
+ try {
+ client.putTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF, tenantRoles);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(
+ c.putTenantRoles("ProviderDomain2", "ProviderService1", "TenantDomain1", AUDIT_REF, tenantRoles))
+ .thenThrow(new NullPointerException());
+ client.putTenantRoles("ProviderDomain2", "ProviderService1", "TenantDomain1", AUDIT_REF, tenantRoles);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetTenantRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TenantRoles tenantRoleMock = Mockito.mock(TenantRoles.class);
+ Mockito.when(c.getTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1")).thenReturn(tenantRoleMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.getTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1");
+ try {
+ client.getTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getTenantRoles("ProviderDomain2", "ProviderService1", "TenantDomain1"))
+ .thenThrow(new NullPointerException());
+ client.getTenantRoles("ProviderDomain2", "ProviderService1", "TenantDomain1");
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testDeleteTenantRoles() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TenantRoles tenantRoleMock = Mockito.mock(TenantRoles.class);
+ Mockito.when(c.deleteTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF)).thenReturn(tenantRoleMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.deleteTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF);
+ try {
+ client.deleteTenantRoles("ProviderDomain1", "ProviderService1", "TenantDomain1", AUDIT_REF);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetSignedDomains() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Map> respHdrs = new HashMap>();
+ SignedDomains signedDomain1 = Mockito.mock(SignedDomains.class);
+ Mockito.when(c.getSignedDomains("dom1", "meta1", "tag1", respHdrs)).thenReturn(signedDomain1).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.getSignedDomains("dom1", "meta1", "tag1", respHdrs);
+ try {
+ client.getSignedDomains("dom1", "meta1", "tag1", respHdrs);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutDefaultAdmins() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ DefaultAdmins adminsMock = Mockito.mock(DefaultAdmins.class);
+ Mockito.when(c.putDefaultAdmins("sports", AUDIT_REF, adminsMock)).thenReturn(adminsMock);
+ client.putDefaultAdmins("sports", AUDIT_REF, adminsMock);
+ try {
+ Mockito.when(c.putDefaultAdmins("media", AUDIT_REF, adminsMock)).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.putDefaultAdmins("media", AUDIT_REF, adminsMock);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testGetDomainDataCheck() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ DomainDataCheck checkdom1 = Mockito.mock(DomainDataCheck.class);
+ Mockito.when(c.getDomainDataCheck("domain1")).thenReturn(checkdom1).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.getDomainDataCheck("domain1");
+ try {
+ client.getDomainDataCheck("domain1");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.getDomainDataCheck("domain2")).thenThrow(new NullPointerException());
+ client.getDomainDataCheck("domain2");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testPutTenancy() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Tenancy tenancyMock = Mockito.mock(Tenancy.class);
+ Tenancy tenant = createTenantObject("tenantDom1", "providerDom1" + "." + "providerService1");
+ Mockito.when(c.putTenancy("tenantDom1", "providerService1", AUDIT_REF, tenant)).thenReturn(tenancyMock).thenThrow(new ZMSClientException(400,"Audit reference required"));
+ client.putTenancy("tenantDom1", "providerService1", AUDIT_REF, tenant);
+ try {
+ client.putTenancy("tenantDom1", "providerService1", AUDIT_REF, tenant);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(true);
+ }
+ try {
+ Mockito.when(c.putTenancy("tenantDom2", "providerService1", AUDIT_REF, tenant))
+ .thenThrow(new NullPointerException());
+ client.putTenancy("tenantDom2", "providerService1", AUDIT_REF, tenant);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testAddMembershipUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Role role1Mock = Mockito.mock(Role.class);
+ Role roleMock = Mockito.mock(Role.class);
+ Mockito.when(c.putRole("MbrAddDom1", "Role1", AUDIT_REF, role1Mock)).thenReturn(roleMock);
+ Membership mbr = new Membership();
+ mbr.setRoleName("Role1");
+ mbr.setMemberName("user.doe");
+ mbr.setIsMember(true);
+ Membership membershipMock = Mockito.mock(Membership.class);
+ Mockito.when(c.putMembership("MbrAddDom1", "Role1", "user.doe", AUDIT_REF, mbr)).thenReturn(membershipMock);
+ Mockito.when(c.getRole("MbrAddDom1", "Role1", false, false)).thenReturn(roleMock);
+ @SuppressWarnings("unchecked")
+ List membersMock = Mockito.mock(List.class);
+ Mockito.when(roleMock.getMembers()).thenReturn(membersMock);
+ Mockito.when(membersMock.size()).thenReturn(3);
+ Mockito.when(membersMock.contains(Mockito.anyString())).thenReturn(true);
+ testAddMembership(client, systemAdminFullUser);
+ Mockito.when(c.deleteTopLevelDomain("MbrGetRoleDom1", AUDIT_REF)).thenReturn(dom1Mock);
+ }
+
+ @Test
+ public void testDeleteMembershipUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Role role1Mock = Mockito.mock(Role.class);
+ Mockito.when(c.putRole("MbrDelDom1", "Role1", AUDIT_REF, role1Mock)).thenReturn(role1Mock);
+ Mockito.when(c.getRole("MbrDelDom1", "Role1", false, false)).thenReturn(role1Mock);
+ @SuppressWarnings("unchecked")
+ List membersMock = Mockito.mock(List.class);
+ Mockito.when(role1Mock.getMembers()).thenReturn(membersMock);
+ Mockito.when(membersMock.size()).thenReturn(1);
+ Mockito.when(membersMock.contains("user.joe")).thenReturn(false);
+ Mockito.when(membersMock.contains("user.jane")).thenReturn(true);
+ testDeleteMembership(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreatePolicyUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Policy policy1Mock = Mockito.mock(Policy.class);
+ Mockito.when(c.putPolicy("PolicyAddDom1", "Policy1", AUDIT_REF, policy1Mock)).thenReturn(policy1Mock);
+ Mockito.when(c.getPolicy("PolicyAddDom1", "Policy1")).thenReturn(policy1Mock);
+ Mockito.when(policy1Mock.getName()).thenReturn("PolicyAddDom1:policy.Policy1".toLowerCase());
+ testCreatePolicy(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testDeletePolicyUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Policy policy1Mock = Mockito.mock(Policy.class);
+ Mockito.when(c.putPolicy("PolicyDelDom1", "Policy1", AUDIT_REF, policy1Mock)).thenReturn(policy1Mock);
+ Mockito.when(c.putPolicy("PolicyDelDom1", "Policy2", AUDIT_REF, policy1Mock)).thenReturn(policy1Mock);
+ Mockito.when(c.getPolicy("PolicyDelDom1", "Policy1")).thenReturn(policy1Mock).thenThrow(new ResourceException(204));
+ Mockito.when(c.getPolicy("PolicyDelDom1", "Policy2")).thenReturn(policy1Mock,policy1Mock).thenThrow(new ResourceException(204));
+ testDeletePolicy(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testDeletePublicKeyEntryUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(Mockito.anyString(), Mockito.any(TopLevelDomain.class))).thenReturn(domainMock);
+ ServiceIdentity serviceMock = Mockito.mock(ServiceIdentity.class);
+ Mockito.when(c.putServiceIdentity("DelPublicKeyDom1", "Service1", AUDIT_REF, serviceMock)).thenReturn(serviceMock);
+ PublicKeyEntry entoryMock = Mockito.mock(PublicKeyEntry.class);
+ Mockito.when(c.deletePublicKeyEntry("DelPublicKeyDom1", "Service1", "zone1", AUDIT_REF)).thenReturn(entoryMock);
+ Mockito.when(c.getPublicKeyEntry("DelPublicKeyDom1", "Service1", "zone1")).thenThrow(new ResourceException(404));
+ Mockito.when(c.getPublicKeyEntry("DelPublicKeyDom1", "Service1", "zone2")).thenReturn(entoryMock);
+ Mockito.when(entoryMock.getKey()).thenReturn(PUB_KEY_ZONE2);
+ Mockito.when(c.deletePublicKeyEntry("DelPublicKeyDom1", "Service1", "zone2", AUDIT_REF)).thenThrow(new ResourceException(400));
+ testDeletePublicKeyEntry(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateServiceIdentityUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ ServiceIdentity serviceMock = Mockito.mock(ServiceIdentity.class);
+ Mockito.when(c.putServiceIdentity("ServiceAddDom1", "Service1", AUDIT_REF, serviceMock)).thenReturn(serviceMock);
+ Mockito.when(c.getServiceIdentity("ServiceAddDom1", "Service1")).thenReturn(serviceMock);
+ Mockito.when(serviceMock.getName()).thenReturn("ServiceAddDom1.Service1".toLowerCase());
+ testCreateServiceIdentity(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testCreateEntityUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Entity entityMock = Mockito.mock(Entity.class);
+ Mockito.when(c.putEntity("CreateEntityDom1", "Entity1", AUDIT_REF, entityMock)).thenReturn(entityMock);
+ Mockito.when(c.getEntity("CreateEntityDom1", "Entity1")).thenReturn(entityMock);
+ Mockito.when(entityMock.getName()).thenReturn("Entity1".toLowerCase());
+ testCreateEntity(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testDeleteEntityUserToken() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ TopLevelDomain dom1Mock = Mockito.mock(TopLevelDomain.class);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1Mock)).thenReturn(domainMock);
+ Entity entityMock = Mockito.mock(Entity.class);
+ Mockito.when(c.getEntity("DelEntityDom1", "Entity1")).thenReturn(entityMock).thenThrow(new ResourceException(204));
+ Mockito.when(c.getEntity("DelEntityDom1", "Entity2")).thenReturn(entityMock,entityMock).thenThrow(new ResourceException(204));
+ testDeleteEntity(client, systemAdminFullUser);
+ }
+
+ @Test
+ public void testGetPrincipalNull() {
+
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ try {
+ client.getPrincipal(null);
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(ex.getCode() == 401);
+ }
+ client.close();
+ }
+
+ @Test
+ public void testGetPrincipalInvalid() {
+
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ try {
+ client.getPrincipal("abcdefg");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(ex.getCode() == 401);
+ }
+
+ try {
+ client.getPrincipal("v=U1;d=coretech;t=12345678;s=signature");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(ex.getCode() == 401);
+ }
+
+ try {
+ client.getPrincipal("v=U1;n=storage;t=12345678;s=signature");
+ fail();
+ } catch (ZMSClientException ex) {
+ assertTrue(ex.getCode() == 401);
+ }
+ client.close();
+ }
+
+ Struct setupRespHdrsStruct() {
+
+ Struct respHdrs = new Struct();
+ Array values = new Array();
+ values.add("Value1A");
+ values.add("Value1B");
+ respHdrs.put("tag1", values);
+
+ values = new Array();
+ values.add("Value2A");
+ values.add("Value2B");
+ respHdrs.put("tag2", values);
+
+ return respHdrs;
+ }
+
+ @Test
+ public void testLookupZMSUrl() {
+
+ System.setProperty(ZMSClient.ZMS_CLIENT_PROP_ATHENZ_CONF, "src/test/resources/athenz.conf");
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ assertEquals(client.lookupZMSUrl(), "https://server-zms.athenzcompany.com:4443/");
+ System.clearProperty(ZMSClient.ZMS_CLIENT_PROP_ATHENZ_CONF);
+ client.close();
+ }
+
+ @Test
+ public void testLookupZMSUrlInvalidFile() {
+ System.setProperty(ZMSClient.ZMS_CLIENT_PROP_ATHENZ_CONF, "src/test/resources/athenz_invaild.conf");
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ assertNull(client.lookupZMSUrl());
+ System.clearProperty(ZMSClient.ZMS_CLIENT_PROP_ATHENZ_CONF);
+ client.close();
+ }
+
+ @Test
+ public void testDeleteDomainTemplate() {
+ ZMSClient client = createClient(systemAdminUser);
+ String domName = "templesofold";
+ String domName2 = "templesofold2";
+
+ try {
+ client.deleteTopLevelDomain(domName, AUDIT_REF);
+ } catch (ZMSClientException ex) {
+ // ignore cleanup errors - e.g. not found
+ }
+
+ TopLevelDomain dom1 = createTopLevelDomainObject(domName,
+ "Test Domain", "testOrg", systemAdminFullUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ Domain domainMock = Mockito.mock(Domain.class);
+ Mockito.when(c.postTopLevelDomain(AUDIT_REF, dom1)).thenReturn(domainMock);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+ ServerTemplateList svrTemplListMock = Mockito.mock(ServerTemplateList.class);
+ @SuppressWarnings("unchecked")
+ List svrTemplNamesMock = Mockito.mock(List.class);
+ Mockito.when(c.getServerTemplateList()).thenReturn(svrTemplListMock);
+ ServerTemplateList svrTemplList = client.getServerTemplateList();
+ Mockito.when(svrTemplListMock.getTemplateNames()).thenReturn(svrTemplNamesMock);
+ List svrTemplNames = svrTemplList.getTemplateNames();
+ DomainTemplate domTempl = new DomainTemplate().setTemplateNames(svrTemplNames);
+ client.putDomainTemplate(domName, AUDIT_REF, domTempl);
+ DomainTemplateList domTemplListMock = Mockito.mock(DomainTemplateList.class);
+ Mockito.when(c.getDomainTemplateList(domName)).thenReturn(domTemplListMock);
+ DomainTemplateList domTemplList = client.getDomainTemplateList(domName);
+ assertNotNull(domTemplList);
+ try {
+ Mockito.when(c.getDomainTemplateList(domName2)).thenThrow(new NullPointerException())
+ .thenThrow(new ResourceException(404));
+ client.getDomainTemplateList(domName2);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ client.getDomainTemplateList(domName2);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ List templNames = domTemplList.getTemplateNames();
+ assertNotNull(templNames);
+ assertTrue(templNames.size() == svrTemplNames.size());
+ // HAVE: domain has all the templates
+
+ // domain has multiple templates: deleting 1 at a time
+ for (int cnt = 0; cnt < svrTemplNames.size(); ++cnt) {
+ client.deleteDomainTemplate(domName, svrTemplNames.get(cnt), AUDIT_REF);
+ domTemplList = client.getDomainTemplateList(domName);
+ assertNotNull(domTemplList);
+ templNames = domTemplList.getTemplateNames();
+ assertNotNull(templNames);
+ int templCnt = svrTemplNames.size() - (cnt + 1);
+ assertTrue(templNames.size() == templCnt, "template should be count=" + templCnt);
+ for (int cnt2 = cnt + 1; cnt2 < svrTemplNames.size(); ++cnt2) {
+ assertTrue(templNames.contains(svrTemplNames.get(cnt2)), "should contain=" + svrTemplNames.get(cnt2));
+ }
+ }
+
+ client.deleteTopLevelDomain(domName, AUDIT_REF);
+ }
+
+ @Test
+ public void testDeleteDomainTemplateErrorCases() {
+ ZMSClient client = createClient(systemAdminUser);
+ ZMSRDLGeneratedClient c = Mockito.mock(ZMSRDLGeneratedClient.class);
+ client.setZMSRDLGeneratedClient(c);
+ ServerTemplateList svrTemplListMock = Mockito.mock(ServerTemplateList.class);
+ Mockito.when(c.getServerTemplateList()).thenReturn(svrTemplListMock).thenThrow(new NullPointerException()).thenThrow(new ResourceException(404,"Domain not found"));
+ ServerTemplateList svrTemplList = client.getServerTemplateList();
+ try {
+ client.getServerTemplateList();
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ try {
+ client.getServerTemplateList();
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+ @SuppressWarnings("unchecked")
+ List svrTemplNamesMock = Mockito.mock(List.class);
+ Mockito.when(svrTemplListMock.getTemplateNames()).thenReturn(svrTemplNamesMock);
+ List svrTemplNames = svrTemplList.getTemplateNames();
+ Mockito.when(c.deleteDomainTemplate("nonexistantdomain", svrTemplNames.get(1), AUDIT_REF)).thenThrow(new ResourceException(404, "Domain not found"));
+ // test: no such domain
+ try {
+ client.deleteDomainTemplate("nonexistantdomain", svrTemplNames.get(1), AUDIT_REF);
+ fail("requesterror not thrown by deleteDomainTemplate");
+ } catch (ZMSClientException ex) {
+ assertEquals(ex.getCode(), 404);
+ assertTrue(ex.getMessage().contains("Domain not found"), ex.getMessage());
+ }
+
+ try {
+ Mockito.when(c.deleteDomainTemplate("nonexistantdomain2", svrTemplNames.get(1), AUDIT_REF))
+ .thenThrow(new NullPointerException());
+ client.deleteDomainTemplate("nonexistantdomain2", svrTemplNames.get(1), AUDIT_REF);
+ fail();
+ } catch (ResourceException ex) {
+ assertTrue(true);
+ }
+
+ // test: no such template
+ String domName = "simontemplar";
+
+ try {
+ client.deleteTopLevelDomain(domName, AUDIT_REF);
+ } catch (ZMSClientException ex) {
+ // ignore cleanup errors - e.g. not found
+ }
+
+ TopLevelDomain dom1 = createTopLevelDomainObject(domName,
+ "Test Domain", "testOrg", systemAdminFullUser);
+ client.postTopLevelDomain(AUDIT_REF, dom1);
+
+ client.deleteDomainTemplate(domName, svrTemplNames.get(1), AUDIT_REF);
+ client.deleteTopLevelDomain(domName, AUDIT_REF);
+ }
+}
diff --git a/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSLoadData.java b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSLoadData.java
new file mode 100644
index 00000000000..9a8ed6ecfb2
--- /dev/null
+++ b/clients/java/zms/src/test/java/com/yahoo/athenz/zms/ZMSLoadData.java
@@ -0,0 +1,202 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zms;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import com.yahoo.athenz.auth.Authority;
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.SimplePrincipal;
+
+public class ZMSLoadData {
+
+ private static String AUDIT_REF = "zmsjcltloadtest";
+
+ private Principal createPrincipal(String userName) {
+ Authority authority = new com.yahoo.athenz.auth.impl.PrincipalAuthority();
+ Principal p = SimplePrincipal.create("user", userName,
+ "v=U1;d=user;n=" + userName + ";s=signature", 0, authority);
+ return p;
+ }
+
+ private ZMSClient getClient(String userName) {
+ ZMSClient client = new ZMSClient(getZMSUrl());
+ client.addCredentials(createPrincipal(userName));
+ return client;
+ }
+
+ private String getZMSUrl() {
+
+ // if we're given a config setting then use that
+
+ String zmsUrl = System.getProperty("yahoo.zms_java_client.zms_url");
+
+ // if the value is not available then check the env setting
+
+ if (zmsUrl == null) {
+ zmsUrl = System.getenv("ZMS_URL");
+ }
+
+ return zmsUrl;
+ }
+
+ private TopLevelDomain createTopLevelDomainObject(String name,
+ String description, String org) {
+
+ TopLevelDomain dom = new TopLevelDomain();
+ dom.setName(name);
+ dom.setDescription(description);
+ dom.setOrg(org);
+ dom.setEnabled(true);
+
+ List admins = new ArrayList();
+ admins.add("sys.auth.zts");
+ admins.add("sys.auth.zpu");
+ admins.add("user.zms_admin");
+ admins.add("user.user_admin");
+ admins.add("user.hga");
+ dom.setAdminUsers(admins);
+
+ return dom;
+ }
+
+ private ServiceIdentity createServiceObject(ZMSClient client, String domainName,
+ String serviceName, String endPoint, String executable, String user,
+ String group) {
+
+ ServiceIdentity service = new ServiceIdentity();
+ service.setExecutable(executable);
+ if (group != null) {
+ service.setGroup(group);
+ }
+ if (user!= null) {
+ service.setUser(user);
+ }
+ service.setName(client.generateServiceIdentityName(domainName, serviceName));
+
+ List pubKeys = new ArrayList<>();
+ pubKeys.add(new PublicKeyEntry().setId("0")
+ .setKey("LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTk"
+ + "FEQ0JpUUtCZ1FDMXRHU1ZDQTh3bDVldzVZNzZXajJySkFVRApZYW5FSmZLbUFseDVjUS84aEtFVWZTU2dwWHI"
+ + "zQ3pkaDFhMjZkbGI3bW1LMjlxbVhKWGg2dW1XOUF5ZlRPS1ZvCis2QVNsb1ZVM2F2dnVmbEdVT0VnMmpzbWRh"
+ + "a1IyNEtjTGpBdTZRclVlNDE3bEczdDhxU1BJR2pTNUMrQ3NKVXcKaDA0aEh4NWYrUEV3eFY0cmJRSURBUUFCC"
+ + "i0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"));
+
+ service.setPublicKeys(pubKeys);
+
+ service.setProviderEndpoint(endPoint);
+ return service;
+ }
+
+ private Role createRoleObject(ZMSClient client, String domainName, String roleName,
+ String trust, int memberStart, int memberEnd) {
+
+ Role role = new Role();
+ role.setName(client.generateRoleName(domainName, roleName));
+ if (trust != null) {
+ role.setTrust(trust);
+ }
+
+ List members = new ArrayList();
+ if (memberStart != -1) {
+ for (int i = memberStart; i < memberEnd; i++) {
+ members.add("user.user" + i);
+ }
+ } else {
+ Random userRandomizer = new Random();
+ for (int i = 0; i < 25; i++) {
+ members.add("user.user" + Math.abs(userRandomizer.nextInt() % 1000));
+ }
+ }
+ role.setMembers(members);
+ return role;
+ }
+
+ private Policy createPolicyObject(ZMSClient client, String domainName, String policyName,
+ String roleName, String action, String resource, AssertionEffect effect) {
+
+ Policy policy = new Policy();
+ policy.setName(client.generatePolicyName(domainName, policyName));
+
+ Assertion assertion = new Assertion();
+ assertion.setAction(action);
+ assertion.setEffect(effect);
+ assertion.setResource(resource);
+ assertion.setRole(client.generateRoleName(domainName, roleName));
+
+ List assertList = new ArrayList();
+ assertList.add(assertion);
+
+ policy.setAssertions(assertList);
+ return policy;
+ }
+
+ public static void main(String [] args) {
+
+ if (args.length != 3) {
+ System.out.println("ZMSLoadData ");
+ System.exit(1);
+ }
+
+ String admin = args[0];
+ int startIndex = Integer.parseInt(args[1]);
+ int endIndex = Integer.parseInt(args[2]);
+ ZMSLoadData data = new ZMSLoadData();
+
+ for (int i = startIndex; i < endIndex; i++) {
+
+ ZMSClient client = data.getClient(admin);
+
+ String domainName = "TestDomain" + i;
+ TopLevelDomain domain = data.createTopLevelDomainObject(domainName, "Test Domain: " + domainName, "CoreTech");
+ client.postTopLevelDomain(AUDIT_REF, domain);
+
+ for (int j = 0; j < 10; j++) {
+
+ String serviceName = "Service" + j;
+ ServiceIdentity service = data.createServiceObject(client, domainName, serviceName,
+ "http://localhost:9080/", "/usr/bin/java", null, null);
+
+ client.putServiceIdentity(domainName, serviceName, AUDIT_REF, service);
+ }
+
+ for (int j = 0; j < 40; j++) {
+
+ String roleName = "Role" + j;
+ Role role = data.createRoleObject(client, domainName, roleName, null, j * 25, (j + 1) * 25);
+ client.putRole(domainName, roleName, AUDIT_REF, role);
+ }
+
+ for (int j = 40; j < 100; j++) {
+
+ String roleName = "Role" + j;
+ Role role = data.createRoleObject(client, domainName, roleName, null, -1, 1000);
+ client.putRole(domainName, roleName, AUDIT_REF, role);
+ }
+
+ for (int j = 0; j < 100; j++) {
+
+ String policyName = "Policy" + j;
+ String roleName = "Role" + j;
+ Policy policy = data.createPolicyObject(client, domainName, policyName, roleName,
+ "*", "*", AssertionEffect.ALLOW);
+ client.putPolicy(domainName, policyName, AUDIT_REF, policy);
+ }
+ }
+ }
+}
diff --git a/clients/java/zms/src/test/resources/athenz.conf b/clients/java/zms/src/test/resources/athenz.conf
new file mode 100644
index 00000000000..d6983863df3
--- /dev/null
+++ b/clients/java/zms/src/test/resources/athenz.conf
@@ -0,0 +1,16 @@
+{
+ "zmsUrl": "https://server-zms.athenzcompany.com:4443/",
+ "ztsUrl": "https://server-zts.athenzcompany.com:4443/",
+ "ztsPublicKeys": [
+ {
+ "id": "0",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ],
+ "zmsPublicKeys": [
+ {
+ "id": "0",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ]
+}
diff --git a/clients/java/zms/src/test/resources/logback.xml b/clients/java/zms/src/test/resources/logback.xml
new file mode 100644
index 00000000000..c4a0357b8d5
--- /dev/null
+++ b/clients/java/zms/src/test/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ System.out
+
+ %-4relative [%thread] %-5level %class - %msg%n
+
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/zpe/README.md b/clients/java/zpe/README.md
new file mode 100644
index 00000000000..03f6da37d2e
--- /dev/null
+++ b/clients/java/zpe/README.md
@@ -0,0 +1,71 @@
+# zpe_java_client
+
+AuthNG ZPE client lib to perform data plane authorization for client requests
+
+## Contents
+
+* [Summary](#summary)
+* [Details](#details)
+
+
+## Summary
+
+This is the ZPE(AuthZ Policy Engine) front-end API to perform client
+access authorization to resources.
+
+The implementation is thread safe.
+
+## Details
+
+This library will be used by service components to check client access
+authorization to resources supplied by the service component.
+
+The library will read the authorization policies from the file system.
+These policy files will be in JSON format as returned by the ZMS REST API:
+getSignedPolicies().
+The directory containing these policy files is by default /home/athenz/var/zpe
+but will be configurable.
+
+These authorization policies can be for several domains.
+
+ZPE will monitor the directory for updates to the files or new files added.
+As new files are deposited to the policy file directory, ZPE will read
+in the new policies to replace the old ones or add them for a new domain.
+Each policy file will be validated against its signature to ensure
+validity of the policy data.
+
+It is expected that each file contains all the policies for a domain.
+
+The policy files can be deposited there in several ways:
+1. Athenz Policy Updater
+2. Manually deposited
+
+
+System properties:
+
+ athenz.zpe.policy_dir
+ Default value: ROOT + /var/zpe
+ Should contain a valid directory path.
+
+ athenz.zpe.monitor_timeout_secs
+ Default value: 300
+ This time interval is used to check for changes to the policy files.
+
+ athenz.zpe.cleanup_tokens_secs
+ Default value: 600 (10 minutes)
+ This time interval is used to check for expired tokens in the cache.
+ It is dependent on the athenz.zpe.monitor_timeout_secs.
+ For intervals less than monitor_timeout_secs, the enforcement check
+ will take place every monitor_timeout_secs seconds.
+ For intervals greater than monitor_timeout_secs, enforcement checks (ec)
+ will take place every:
+ ec * monitor_timeout_secs >= cleanup_tokens_secs
+ where ec is the smallest integer such that ec * monitor_timeout_secs >= cleanup_tokens_secs
+ Ex: monitor_timeout_secs=300, cleanup_tokens_secs=500, ec = 600 seconds
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
+
diff --git a/clients/java/zpe/pom.xml b/clients/java/zpe/pom.xml
new file mode 100644
index 00000000000..b58824720f5
--- /dev/null
+++ b/clients/java/zpe/pom.xml
@@ -0,0 +1,205 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+ zpe_java_client
+ jar
+ zpe_java_client
+ ZPE Client Library (Java)
+
+
+ 1.9.1
+ benchmarks
+
+
+
+
+ ${project.groupId}
+ zts_core
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ auth_core
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ client_common
+ ${project.parent.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+
+ prepare-package
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+ com.fasterxml.jackson.core
+
+
+
+
+ com.fasterxml.jackson
+ athenz.shade.zpe.com.fasterxml.jackson
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.16
+
+
+ default-test
+
+ test
+
+
+ alphabetical
+
+ 1
+ 1
+ src/test/resources/pol_dir
+ src/test/resources/athenz.conf
+ src/test/resources/logback.xml
+
+
+
+
+
+
+
+
+
+
+
+
+ jmh-performance-test
+
+
+ src/main/java/com/yahoo/athenz/zpe/Performance.java
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
+
+ package
+
+ shade
+
+
+ ${uberjar.name}
+
+
+ org.openjdk.jmh.Main
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/AuthZpeClient.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/AuthZpeClient.java
new file mode 100644
index 00000000000..349825f5a08
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/AuthZpeClient.java
@@ -0,0 +1,797 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import com.yahoo.athenz.auth.impl.RoleAuthority;
+import com.yahoo.athenz.auth.token.RoleToken;
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+import com.yahoo.athenz.zpe.pkey.PublicKeyStore;
+import com.yahoo.athenz.zpe.pkey.PublicKeyStoreFactory;
+import com.yahoo.rdl.Struct;
+
+import java.security.PublicKey;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AuthZpeClient {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AuthZpeClient.class);
+
+ public static final String ZPE_UPDATER_CLASS = "com.yahoo.athenz.zpe.ZpeUpdater";
+ public static final String ZPE_PKEY_CLASS = "com.yahoo.athenz.zpe.pkey.file.FilePublicKeyStoreFactory";
+
+ public static final String ZPE_TOKEN_HDR = System.getProperty(RoleAuthority.ATHENZ_PROP_ROLE_HEADER, RoleAuthority.HTTP_HEADER);;
+
+ public static final String ZTS_PUBLIC_KEY = "zts_public_key";
+ public static final String ZMS_PUBLIC_KEY = "zms_public_key";
+
+ public static final String ZTS_PUBLIC_KEY_PREFIX = "zts.public_key.";
+ public static final String ZMS_PUBLIC_KEY_PREFIX = "zms.public_key.";
+
+ public static final String SYS_AUTH_DOMAIN = "sys.auth";
+ public static final String ZTS_SERVICE_NAME = "zts";
+ public static final String ZMS_SERVICE_NAME = "zms";
+
+ public static final String DEFAULT_DOMAIN = "sys.auth";
+ public static final String UNKNOWN_DOMAIN = "unknown";
+
+ public static ZpeMetric zpeMetric = new ZpeMetric();
+
+ private static String zpeClientImplName;
+ private static int allowedOffset = 300;
+
+ private static ZpeClient zpeClt = null;
+ private static PublicKeyStore publicKeyStore = null;
+
+ public enum AccessCheckStatus {
+ ALLOW {
+ public String toString() {
+ return "Access Check was explicitly allowed";
+ }
+ },
+ DENY {
+ public String toString() {
+ return "Access Check was explicitly denied";
+ }
+ },
+ DENY_NO_MATCH {
+ public String toString() {
+ return "Access denied due to no match to any of the assertions defined in domain policy file";
+ }
+ },
+ DENY_ROLETOKEN_EXPIRED {
+ public String toString() {
+ return "Access denied due to expired RoleToken";
+ }
+ },
+ DENY_ROLETOKEN_INVALID {
+ public String toString() {
+ return "Access denied due to invalid RoleToken";
+ }
+ },
+ DENY_DOMAIN_MISMATCH {
+ public String toString() {
+ return "Access denied due to domain mismatch between Resource and RoleToken";
+ }
+ },
+ DENY_DOMAIN_NOT_FOUND {
+ public String toString() {
+ return "Access denied due to domain not found in library cache";
+ }
+ },
+ DENY_DOMAIN_EXPIRED {
+ public String toString() {
+ return "Access denied due to expired domain policy file";
+ }
+ },
+ DENY_DOMAIN_EMPTY {
+ public String toString() {
+ return "Access denied due to no policies in the domain file";
+ }
+ },
+ DENY_INVALID_PARAMETERS {
+ public String toString() {
+ return "Access denied due to invalid/empty action/resource values";
+ };
+ }
+ }
+
+ static {
+
+ // instantiate implementation classes
+
+ zpeClientImplName = System.getProperty(ZpeConsts.ZPE_PROP_CLIENT_IMPL, ZPE_UPDATER_CLASS);
+ try {
+ zpeClt = getZpeClient();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException ex) {
+ LOG.error("Unable to instantiate zpe class: " + zpeClientImplName, ex);
+ throw new RuntimeException(ex);
+ }
+ zpeClt.init(null);
+
+ allowedOffset = Integer.parseInt(System.getProperty(ZpeConsts.ZPE_PROP_TOKEN_OFFSET, "300"));
+
+ // case of invalid value, we'll default back to 5 minutes
+
+ if (allowedOffset < 0) {
+ allowedOffset = 300;
+ }
+
+ String pkeyFactoryClass = System.getProperty(ZpeConsts.ZPE_PROP_PUBLIC_KEY_CLASS, ZPE_PKEY_CLASS);
+
+ PublicKeyStoreFactory publicKeyStoreFactory = null;
+ try {
+ publicKeyStoreFactory = (PublicKeyStoreFactory) Class.forName(pkeyFactoryClass).newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException ex) {
+ LOG.error("Invalid PublicKeyStore class: " + pkeyFactoryClass, ex);
+ throw new RuntimeException(ex);
+ }
+ publicKeyStore = publicKeyStoreFactory.create();
+ }
+
+ public static void init() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Init: load the ZPE");
+ }
+ }
+
+ public static PublicKey getZtsPublicKey(String keyId) {
+ return publicKeyStore.getZtsKey(keyId);
+ }
+
+ public static PublicKey getZmsPublicKey(String keyId) {
+ return publicKeyStore.getZmsKey(keyId);
+ }
+
+ /**
+ * Determine if access(action) is allowed against the specified resource by
+ * a user represented by the user (cltToken, cltTokenName).
+ * @param roleToken - value for the REST header: Athenz-Role-Auth
+ * ex: "v=Z1;d=angler;r=admin;a=aAkjbbDMhnLX;t=1431974053;e=1431974153;k=0"
+ * @param angResource is a domain qualified resource the calling service
+ * will check access for. ex: my_domain:my_resource
+ * ex: "angler:pondsKernCounty"
+ * ex: "sports:service.storage.tenant.Activator.ActionMap"
+ * @param action is the type of access attempted by a client
+ * ex: "read"
+ * ex: "scan"
+ * @return AccessCheckStatus if the user can access the resource via the specified action
+ * the result is ALLOW otherwise one of the DENY_* values specifies the exact
+ * reason why the access was denied
+ */
+ public static AccessCheckStatus allowAccess(String roleToken, String angResource, String action) {
+ StringBuilder matchRoleName = new StringBuilder(256);
+ return allowAccess(roleToken, angResource, action, matchRoleName);
+ }
+
+ /**
+ * Determine if access(action) is allowed against the specified resource by
+ * a user represented by the user (cltToken, cltTokenName).
+ * @param roleToken - value for the REST header: Athenz-Role-Auth
+ * ex: "v=Z1;d=angler;r=admin;a=aAkjbbDMhnLX;t=1431974053;e=1431974153;k=0"
+ * @param angResource is a domain qualified resource the calling service
+ * will check access for. ex: my_domain:my_resource
+ * ex: "angler:pondsKernCounty"
+ * ex: "sports:service.storage.tenant.Activator.ActionMap"
+ * @param action is the type of access attempted by a client
+ * ex: "read"
+ * ex: "scan"
+ * @param matchRoleName - [out] will include the role name that the result was based on
+ * it will be not be set if the failure is due to expired/invalid tokens or
+ * there were no matches thus a default value of DENY_NO_MATCH is returned
+ * @return AccessCheckStatus if the user can access the resource via the specified action
+ * the result is ALLOW otherwise one of the DENY_* values specifies the exact
+ * reason why the access was denied
+ */
+ public static AccessCheckStatus allowAccess(String roleToken, String angResource, String action,
+ StringBuilder matchRoleName) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("allowAccess: action=" + action + " resource=" + angResource);
+ }
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME, DEFAULT_DOMAIN);
+
+ RoleToken rToken = null;
+ Map tokenCache = null;
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ tokenCache = zpeclt.getRoleTokenCacheMap();
+ rToken = tokenCache.get(roleToken);
+ } catch (Exception exc) {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_CACHE_FAILURE, DEFAULT_DOMAIN);
+ LOG.error("allowAccess: token cache failure, exc: ", exc);
+ }
+
+ if (rToken == null) {
+
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_CACHE_NOT_FOUND, DEFAULT_DOMAIN);
+ rToken = new RoleToken(roleToken);
+
+ // validate the token
+ if (rToken.validate(getZtsPublicKey(rToken.getKeyId()), allowedOffset, null) == false) {
+ LOG.error("allowAccess: Authorization denied. Authentication of token failed for token="
+ + rToken.getSignedToken());
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_INVALID_TOKEN, rToken.getDomain());
+ return AccessCheckStatus.DENY_ROLETOKEN_INVALID;
+ }
+
+ if (tokenCache != null) {
+ tokenCache.put(roleToken, rToken);
+ }
+ } else {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_CACHE_SUCCESS, rToken.getDomain());
+ }
+
+ AccessCheckStatus status = allowAccess(rToken, angResource, action, matchRoleName);
+ return status;
+ }
+
+ /**
+ * Determine if access(action) is allowed against the specified resource by
+ * a user represented by the RoleToken.
+ * @param rToken represents the role token sent by the client that wants access to the resource
+ * @param angResource is a domain qualified resource the calling service
+ * will check access for. ex: my_domain:my_resource
+ * ex: "angler:pondsKernCounty"
+ * ex: "sports:service.storage.tenant.Activator.ActionMap"
+ * @param action is the type of access attempted by a client
+ * ex: "read"
+ * ex: "scan"
+ * @param matchRoleName - [out] will include the role name that the result was based on
+ * it will be not be set if the failure is due to expired/invalid tokens or
+ * there were no matches thus a default value of DENY_NO_MATCH is returned
+ * @return AccessCheckStatus if the user can access the resource via the specified action
+ * the result is ALLOW otherwise one of the DENY_* values specifies the exact
+ * reason why the access was denied
+ **/
+ public static AccessCheckStatus allowAccess(RoleToken rToken, String angResource, String action,
+ StringBuilder matchRoleName) {
+
+ // check the token expiration
+ if (rToken == null) {
+ LOG.error("allowAccess: Authorization denied. Token is null");
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_INVALID_TOKEN, UNKNOWN_DOMAIN);
+ return AccessCheckStatus.DENY_ROLETOKEN_INVALID;
+ }
+ long now = System.currentTimeMillis() / 1000;
+ long expiry = rToken.getExpiryTime();
+ if (expiry != 0 && expiry < now) {
+ String signedToken = rToken.getSignedToken();
+ LOG.error("allowAccess: Authorization denied. Token expired. now=" +
+ now + " expiry=" + expiry + " token=" + signedToken);
+ Map tokenCache = null;
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ tokenCache = zpeclt.getRoleTokenCacheMap();
+ tokenCache.remove(signedToken);
+ } catch (Exception exc) {
+ LOG.error("allowAccess: token cache failure, exc: ", exc);
+ }
+
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_EXPIRED_TOKEN, rToken.getDomain());
+ return AccessCheckStatus.DENY_ROLETOKEN_EXPIRED;
+ }
+
+ String tokenDomain = rToken.getDomain(); // ZToken contains the domain
+ List roles = rToken.getRoles(); // ZToken contains roles
+
+ if (LOG.isDebugEnabled()) {
+ if (roles != null) {
+ for (String role: roles) {
+ LOG.debug("allowAccess: token role=" + role);
+ }
+ }
+ }
+
+ return allowActionZPE(action, tokenDomain, angResource, roles, matchRoleName);
+ }
+
+ /**
+ * Determine if access(action) is allowed against the specified resource by
+ * a user represented by the list of role tokens.
+ * @param roleTokenList - values from the REST header(s): Athenz-Role-Auth
+ * ex: "v=Z1;d=angler;r=admin;a=aAkjbbDMhnLX;t=1431974053;e=1431974153;k=0"
+ * @param angResource is a domain qualified resource the calling service
+ * will check access for. ex: my_domain:my_resource
+ * ex: "angler:pondsKernCounty"
+ * ex: "sports:service.storage.tenant.Activator.ActionMap"
+ * @param action is the type of access attempted by a client
+ * ex: "read"
+ * ex: "scan"
+ * @param matchRoleName - [out] will include the role name that the result was based on
+ * it will be not be set if the failure is due to expired/invalid tokens or
+ * there were no matches thus a default value of DENY_NO_MATCH is returned
+ * @return AccessCheckStatus if the user can access the resource via the specified action
+ * the result is ALLOW otherwise one of the DENY_* values specifies the exact
+ * reason why the access was denied
+ */
+ public static AccessCheckStatus allowAccess(List roleTokenList,
+ String angResource, String action, StringBuilder matchRoleName) {
+
+ AccessCheckStatus retStatus = AccessCheckStatus.DENY_NO_MATCH;
+ StringBuilder roleName = null;
+ for (String roleToken: roleTokenList) {
+ StringBuilder rName = new StringBuilder(64);
+ AccessCheckStatus status = allowAccess(roleToken, angResource, action, rName);
+ if (status == AccessCheckStatus.DENY) {
+ matchRoleName.append(rName);
+ return status;
+ } else if (retStatus != AccessCheckStatus.ALLOW) { // only DENY over-rides ALLOW
+ retStatus = status;
+ roleName = rName;
+ }
+ }
+
+ if (roleName != null) {
+ matchRoleName.append(roleName.toString());
+ }
+
+ return retStatus;
+ }
+
+ /**
+ * Validate the RoleToken and return the parsed token object that
+ * could be used to extract all fields from the role token. If the role
+ * token is invalid, then null object is returned.
+ * @param roleToken - value for the REST header: Athenz-Role-Auth
+ * ex: "v=Z1;d=angler;r=admin;a=aAkjbbDMhnLX;t=1431974053;e=1431974153;k=0"
+ * @return RoleToken if the token is validated successfully otherwise null
+ */
+ public static RoleToken validateRoleToken(String roleToken) {
+
+ RoleToken rToken = null;
+
+ // first check in our cache in case we have already seen and successfully
+ // validated this role token (signature validation is expensive)
+
+ Map tokenCache = null;
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ tokenCache = zpeclt.getRoleTokenCacheMap();
+ rToken = tokenCache.get(roleToken);
+ } catch (Exception exc) {
+ }
+
+ // if the token is not in the cache then we need to
+ // validate the token now
+
+ if (rToken == null) {
+ rToken = new RoleToken(roleToken);
+
+ // validate the token
+
+ if (rToken.validate(getZtsPublicKey(rToken.getKeyId()), allowedOffset, null) == false) {
+ return null;
+ }
+
+ if (tokenCache != null) {
+ tokenCache.put(roleToken, rToken);
+ }
+ }
+
+ return rToken;
+ }
+
+ static ZpeClient getZpeClient() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+
+ if (zpeClt != null) {
+ return zpeClt;
+ }
+
+ return (ZpeClient) Class.forName(zpeClientImplName).newInstance();
+ }
+
+ /*
+ * Peel off domain name from the assertion string if it matches
+ * domain and return the string without the domain prefix.
+ * Else, return default value
+ */
+ static String stripDomainPrefix(String assertString, String domain, String defaultValue) {
+ int index = assertString.indexOf(':');
+ if (index == -1) {
+ return assertString;
+ }
+
+ if (assertString.substring(0, index).equals(domain) == false) {
+ return defaultValue;
+ }
+
+ return assertString.substring(index + 1);
+ }
+
+ static boolean isRegexMetaCharacter(char regexChar) {
+ switch (regexChar) {
+ case '^':
+ case '$':
+ case '.':
+ case '|':
+ case '[':
+ case '+':
+ case '\\':
+ case '(':
+ case ')':
+ case '{':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public static String patternFromGlob(String glob) {
+ StringBuilder sb = new StringBuilder("^");
+ int len = glob.length();
+ for (int i = 0; i < len; i++) {
+ char c = glob.charAt(i);
+ if (c == '*') {
+ sb.append(".*");
+ } else if (c == '?') {
+ sb.append('.');
+ } else {
+ if (isRegexMetaCharacter(c)) {
+ sb.append('\\');
+ }
+ sb.append(c);
+ }
+ }
+ sb.append("$");
+ return sb.toString();
+ }
+
+ // check action access in the domain to the resource with the given roles
+ //
+ static AccessCheckStatus allowActionZPE(String action, String tokenDomain, String angResource,
+ List roles, StringBuilder matchRoleName) {
+
+ StringBuilder sb = new StringBuilder("allowActionZPE: domain(");
+ sb.append(tokenDomain).append(") action(").append(action).
+ append(") resource(").append(angResource).append(")");
+ String msgPrefix = sb.toString();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + " STARTING");
+ }
+
+ if (roles == null || roles.size() == 0) {
+ LOG.error(msgPrefix + " ERROR: No roles so access denied");
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_INVALID_TOKEN, tokenDomain);
+ return AccessCheckStatus.DENY_ROLETOKEN_INVALID;
+ }
+
+ if (tokenDomain == null || tokenDomain.isEmpty() == true) {
+ LOG.error(msgPrefix + " ERROR: No domain so access denied");
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_INVALID_TOKEN, DEFAULT_DOMAIN);
+ return AccessCheckStatus.DENY_ROLETOKEN_INVALID;
+ }
+
+ if (action == null || action.isEmpty() == true) {
+ LOG.error(msgPrefix + " ERROR: No action so access denied");
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_ERROR, tokenDomain);
+ return AccessCheckStatus.DENY_INVALID_PARAMETERS;
+ }
+ action = action.toLowerCase();
+
+ if (angResource == null || angResource.isEmpty() == true) {
+ LOG.error(msgPrefix + " ERROR: No resource so access denied");
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_ERROR, tokenDomain);
+ return AccessCheckStatus.DENY_INVALID_PARAMETERS;
+ }
+ angResource = angResource.toLowerCase();
+ angResource = stripDomainPrefix(angResource, tokenDomain, null);
+
+ // Note: if domain in token doesn't match domain in resource then there
+ // will be no match of any resource in the assertions - so deny immediately
+
+ if (angResource == null) {
+ StringBuilder sbErr = new StringBuilder(512);
+ sbErr.append(msgPrefix).append(" ERROR: Domain mismatch in token(").
+ append(tokenDomain).append(") and resource so access denied");
+ LOG.error(sbErr.toString());
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DOMAIN_MISMATCH, tokenDomain);
+ return AccessCheckStatus.DENY_DOMAIN_MISMATCH;
+ }
+
+ // first hunt by role for deny assertions since deny takes precedence
+ // over allow assertions
+
+ AccessCheckStatus status = AccessCheckStatus.DENY_DOMAIN_NOT_FOUND;
+ Map> roleMap = getRoleSpecificDenyPolicies(tokenDomain);
+ if (roleMap != null && !roleMap.isEmpty()) {
+ if (actionByRole(action, tokenDomain, angResource, roles, roleMap, matchRoleName)) {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DENY, tokenDomain);
+ return AccessCheckStatus.DENY;
+ } else {
+ status = AccessCheckStatus.DENY_NO_MATCH;
+ }
+ } else if (roleMap != null) {
+ status = AccessCheckStatus.DENY_DOMAIN_EMPTY;
+ }
+
+ // if the check was not explicitly denied by a standard role, then
+ // let's process our wildcard roles for deny assertions
+
+ roleMap = getWildCardDenyPolicies(tokenDomain);
+ if (roleMap != null && !roleMap.isEmpty()) {
+ if (actionByWildCardRole(action, tokenDomain, angResource, roles, roleMap, matchRoleName)) {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DENY, tokenDomain);
+ return AccessCheckStatus.DENY;
+ } else {
+ status = AccessCheckStatus.DENY_NO_MATCH;
+ }
+ } else if (status != AccessCheckStatus.DENY_NO_MATCH && roleMap != null) {
+ status = AccessCheckStatus.DENY_DOMAIN_EMPTY;
+ }
+
+ // so far it did not match any deny assertions so now let's
+ // process our allow assertions
+
+ roleMap = getRoleSpecificAllowPolicies(tokenDomain);
+ if (roleMap != null && !roleMap.isEmpty()) {
+ if (actionByRole(action, tokenDomain, angResource, roles, roleMap, matchRoleName)) {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_ALLOW, tokenDomain);
+ return AccessCheckStatus.ALLOW;
+ } else {
+ status = AccessCheckStatus.DENY_NO_MATCH;
+ }
+ } else if (status != AccessCheckStatus.DENY_NO_MATCH && roleMap != null) {
+ status = AccessCheckStatus.DENY_DOMAIN_EMPTY;
+ }
+
+ // at this point we either got an allow or didn't match anything so we're
+ // going to try the wildcard roles
+
+ roleMap = getWildCardAllowPolicies(tokenDomain);
+ if (roleMap != null && !roleMap.isEmpty()) {
+ if (actionByWildCardRole(action, tokenDomain, angResource, roles, roleMap, matchRoleName)) {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_ALLOW, tokenDomain);
+ return AccessCheckStatus.ALLOW;
+ } else {
+ status = AccessCheckStatus.DENY_NO_MATCH;
+ }
+ } else if (status != AccessCheckStatus.DENY_NO_MATCH && roleMap != null) {
+ status = AccessCheckStatus.DENY_DOMAIN_EMPTY;
+ }
+
+ if (status == AccessCheckStatus.DENY_DOMAIN_NOT_FOUND) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": No role map found for domain=" + tokenDomain
+ + " so access denied");
+ }
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DOMAIN_NOT_FOUND, tokenDomain);
+ } else if (status == AccessCheckStatus.DENY_DOMAIN_EMPTY) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": No policy assertions for domain=" + tokenDomain
+ + " so access denied");
+ }
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DOMAIN_EMPTY, tokenDomain);
+ } else {
+ zpeMetric.increment(ZpeConsts.ZPE_METRIC_NAME_DENY_NO_MATCH, tokenDomain);
+ }
+
+ return status;
+ }
+
+ static boolean matchAssertions(List asserts, String role, String action,
+ String resource, StringBuilder matchRoleName, String msgPrefix) {
+
+ ZpeMatch matchStruct = null;
+ String passertAction = null;
+ String passertResource = null;
+ String passertRole = null;
+ String polName = null;
+
+ for (Struct strAssert: asserts) {
+
+ if (LOG.isDebugEnabled()) {
+
+ // this strings are only used for debug statements so we'll
+ // only retrieve them if debug option is enabled
+
+ passertAction = strAssert.getString(ZpeConsts.ZPE_FIELD_ACTION);
+ passertResource = strAssert.getString(ZpeConsts.ZPE_FIELD_RESOURCE);
+ passertRole = strAssert.getString(ZpeConsts.ZPE_FIELD_ROLE);
+ polName = strAssert.getString(ZpeConsts.ZPE_FIELD_POLICY_NAME);
+
+ LOG.debug(msgPrefix + ": Process Assertion: policy(" + polName +
+ ") assert-action=" + passertAction +
+ " assert-resource=" + passertResource + " assert-role=" + passertRole);
+ }
+
+ // ex: "mod*
+
+ matchStruct = (ZpeMatch) strAssert.get(ZpeConsts.ZPE_ACTION_MATCH_STRUCT);
+ if (!matchStruct.matches(action)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": policy(" + polName + ") regexpr-match: FAILed: assert-action("
+ + passertAction + ") doesn't match action(" + action + ")");
+ }
+ continue;
+ }
+
+ // ex: "weather:service.storage.tenant.sports.*"
+ matchStruct = (ZpeMatch) strAssert.get(ZpeConsts.ZPE_RESOURCE_MATCH_STRUCT);
+ if (!matchStruct.matches(resource)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": policy(" + polName + ") regexpr-match: FAILed: assert-resource("
+ + passertResource + ") doesn't match resource(" + resource + ")");
+ }
+ continue;
+ }
+
+ // update the match role name
+
+ matchRoleName.setLength(0);
+ matchRoleName.append(role);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ static boolean actionByRole(String action, String domain, String angResource,
+ List roles, Map> roleMap, StringBuilder matchRoleName) {
+
+ // msgPrefix is only used in our debug statements so we're only
+ // going to generate the value if debug is enabled
+
+ String msgPrefix = null;
+ if (LOG.isDebugEnabled()) {
+ StringBuilder sb = new StringBuilder("allowActionByRole: domain(");
+ sb.append(domain).append(") action(").append(action).
+ append(") resource(").append(angResource).append(")");
+ msgPrefix = sb.toString();
+ }
+
+ for (String role : roles) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": Process role (" + role + ")");
+ }
+
+ List asserts = roleMap.get(role);
+ if (asserts == null || asserts.isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": No policy assertions in domain=" + domain
+ + " for role=" + role + " so access denied");
+ }
+ continue;
+ }
+
+ // see if any of its assertions match the action and resource
+ // the assert action value does not have the domain prefix
+ // ex: "Modify"
+ // the assert resource value has the domain prefix
+ // ex: "angler:angler.stuff"
+
+ if (matchAssertions(asserts, role, action, angResource, matchRoleName, msgPrefix)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static boolean actionByWildCardRole(String action, String domain, String angResource,
+ List roles, Map> roleMap, StringBuilder matchRoleName) {
+
+ String msgPrefix = null;
+ if (LOG.isDebugEnabled()) {
+ StringBuilder sb = new StringBuilder("allowActionByWildCardRole: domain(");
+ sb.append(domain).append(") action(").append(action).
+ append(") resource(").append(angResource).append(")");
+ msgPrefix = sb.toString();
+ }
+
+ // find policy matching resource and action
+ // get assertions for given domain+role
+ // then cycle thru those assertions looking for matching action and resource
+
+ // we will visit each of the wildcard roles
+ //
+ Set keys = roleMap.keySet();
+
+ for (String role: roles) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": Process role (" + role + ")");
+ }
+
+ for (String roleName : keys) {
+ List asserts = roleMap.get(roleName);
+ if (asserts == null || asserts.isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(msgPrefix + ": No policy assertions in domain=" + domain
+ + " for role=" + role + " so access denied");
+ }
+ continue;
+ }
+
+ Struct structAssert = asserts.get(0);
+ ZpeMatch matchStruct = (ZpeMatch) structAssert.get(ZpeConsts.ZPE_ROLE_MATCH_STRUCT);
+ if (!matchStruct.matches(role)) {
+ if (LOG.isDebugEnabled()) {
+ String polName = structAssert.getString(ZpeConsts.ZPE_FIELD_POLICY_NAME);
+ LOG.debug(msgPrefix + ": policy(" + polName +
+ ") regexpr-match: FAILed: assert-role(" + roleName +
+ ") doesnt match role(" + role + ")");
+ }
+ continue;
+ }
+
+ // HAVE: matched the role with the wildcard
+
+ // see if any of its assertions match the action and resource
+ // the assert action value does not have the domain prefix
+ // ex: "Modify"
+ // the assert resource value has the domain prefix
+ // ex: "angler:angler.stuff"
+
+ if (matchAssertions(asserts, roleName, action, angResource, matchRoleName, msgPrefix)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ static Map> getWildCardAllowPolicies(String domain) {
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ Map> roleAsserts = zpeclt.getWildcardAllowAssertions(domain);
+ return roleAsserts;
+ } catch (Exception exc) {
+ LOG.error("getWildCardAllowPolicies: exc: ", exc);
+ }
+ return null;
+ }
+
+ static Map> getRoleSpecificAllowPolicies(String domain) {
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ Map> roleAsserts = zpeclt.getRoleAllowAssertions(domain);
+ return roleAsserts;
+ } catch (Exception exc) {
+ LOG.error("getRoleSpecificAllowPolicies: exc: ", exc);
+ }
+ return null;
+ }
+
+ static Map> getWildCardDenyPolicies(String domain) {
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ Map> roleAsserts = zpeclt.getWildcardDenyAssertions(domain);
+ return roleAsserts;
+ } catch (Exception exc) {
+ LOG.error("getWildCardDenyPolicies: exc: ", exc);
+ }
+ return null;
+ }
+
+ static Map> getRoleSpecificDenyPolicies(String domain) {
+ try {
+ ZpeClient zpeclt = getZpeClient();
+ Map> roleAsserts = zpeclt.getRoleDenyAssertions(domain);
+ return roleAsserts;
+ } catch (Exception exc) {
+ LOG.error("getRoleSpecificDenyPolicies: exc: ", exc);
+ }
+ return null;
+ }
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeClient.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeClient.java
new file mode 100644
index 00000000000..a869bab4213
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeClient.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.util.List;
+import java.util.Map;
+
+import com.yahoo.athenz.auth.token.RoleToken;
+import com.yahoo.rdl.Struct;
+
+
+public interface ZpeClient {
+
+ // @param domain can be null
+ public void init(String domain);
+
+ // return current cache of role tokens
+ public Map getRoleTokenCacheMap();
+
+ // return the role assertion map for the specified domain with allow effect
+ // key is role name, value is List of assertions for that role
+ public Map> getRoleAllowAssertions(String domain);
+
+ // return the wildcard role assertion map for the specified domain with allow effect
+ // key is role name, value is List of assertions for that role
+ public Map> getWildcardAllowAssertions(String domain);
+
+ // return the role assertion map for the specified domain with deny effect
+ // key is role name, value is List of assertions for that role
+ public Map> getRoleDenyAssertions(String domain);
+
+ // return the wildcard role assertion map for the specified domain with deny effect
+ // key is role name, value is List of assertions for that role
+ public Map> getWildcardDenyAssertions(String domain);
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeConsts.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeConsts.java
new file mode 100644
index 00000000000..6f962357ba5
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeConsts.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import com.yahoo.athenz.zts.DomainMetricType;
+
+public final class ZpeConsts {
+
+ public static final String ZPE_ACTION_MATCH_STRUCT = "actionMatchStruct";
+ public static final String ZPE_RESOURCE_MATCH_STRUCT = "resourceMatchStruct";
+ public static final String ZPE_ROLE_MATCH_STRUCT = "roleMatchStruct";
+
+ public static final String ZPE_FIELD_ACTION = "action";
+ public static final String ZPE_FIELD_RESOURCE = "resource";
+ public static final String ZPE_FIELD_ROLE = "role";
+ public static final String ZPE_FIELD_EFFECT = "effect";
+ public static final String ZPE_FIELD_POLICY_NAME = "polname";
+
+ public static final String ZPE_METRIC_SCOREBOARD_NAME = "athenz_zpe_java_client";
+ public static final String ZPE_METRIC_NAME = DomainMetricType.ACCESS_ALLOWED.toString();
+ public static final String ZPE_METRIC_NAME_DENY = DomainMetricType.ACCESS_ALLOWED_DENY.toString();
+ public static final String ZPE_METRIC_NAME_DENY_NO_MATCH = DomainMetricType.ACCESS_ALLOWED_DENY_NO_MATCH.toString();
+ public static final String ZPE_METRIC_NAME_ALLOW = DomainMetricType.ACCESS_ALLOWED_ALLOW.toString();
+ public static final String ZPE_METRIC_NAME_ERROR = DomainMetricType.ACCESS_ALLOWED_ERROR.toString();
+ public static final String ZPE_METRIC_NAME_INVALID_TOKEN = DomainMetricType.ACCESS_ALLOWED_TOKEN_INVALID.toString();
+ public static final String ZPE_METRIC_NAME_EXPIRED_TOKEN = DomainMetricType.ACCESS_Allowed_TOKEN_EXPIRED.toString();
+ public static final String ZPE_METRIC_NAME_DOMAIN_NOT_FOUND = DomainMetricType.ACCESS_ALLOWED_DOMAIN_NOT_FOUND.toString();
+ public static final String ZPE_METRIC_NAME_DOMAIN_MISMATCH = DomainMetricType.ACCESS_ALLOWED_DOMAIN_MISMATCH.toString();
+ public static final String ZPE_METRIC_NAME_DOMAIN_EXPIRED = DomainMetricType.ACCESS_ALLOWED_DOMAIN_EXPIRED.toString();
+ public static final String ZPE_METRIC_NAME_DOMAIN_EMPTY = DomainMetricType.ACCESS_ALLOWED_DOMAIN_EMPTY.toString();
+ public static final String ZPE_METRIC_NAME_CACHE_FAILURE = DomainMetricType.ACCESS_ALLOWED_TOKEN_CACHE_FAILURE.toString();
+ public static final String ZPE_METRIC_NAME_CACHE_NOT_FOUND = DomainMetricType.ACCESS_ALLOWED_TOKEN_CACHE_NOT_FOUND.toString();
+ public static final String ZPE_METRIC_NAME_CACHE_SUCCESS = DomainMetricType.ACCESS_ALLOWED_TOKEN_CACHE_SUCCESS.toString();
+ public static final String ZPE_METRIC_NAME_TOKEN_VALIDATE = DomainMetricType.ACCESS_ALLOWED_TOKEN_VALIDATE.toString();
+ public static final String ZPE_METRIC_LOAD_FILE_FAIL = DomainMetricType.LOAD_FILE_FAIL.toString();
+ public static final String ZPE_METRIC_LOAD_FILE_GOOD = DomainMetricType.LOAD_FILE_GOOD.toString();
+ public static final String ZPE_METRIC_LOAD_DOM_GOOD = DomainMetricType.LOAD_DOMAIN_GOOD.toString();
+
+ // properties
+ public static final String ZPE_PROP_ATHENZ_CONF = "athenz.athenz_conf";
+
+ public static final String ZPE_PROP_STATS_ENABLED = "athenz.zpe.enable_stats";
+ public static final String ZPE_PROP_METRIC_CLASS = "athenz.zpe.metric_factory_class";
+ public static final String ZPE_PROP_PUBLIC_KEY_CLASS = "athenz.zpe.public_key_class";
+ public static final String ZPE_PROP_CLIENT_IMPL = "athenz.zpe.updater_class";
+ public static final String ZPE_PROP_TOKEN_OFFSET = "athenz.zpe.token_allowed_offset";
+ public static final String ZPE_PROP_METRIC_WRITE_INTERVAL = "athenz.zpe.metric_write_interval";
+ public static final String ZPE_PROP_METRIC_FILE_PATH = "athenz.zpe.metric_file_path";
+ public static final String ZPE_PROP_MON_TIMEOUT = "athenz.zpe.monitor_timeout_secs";
+ public static final String ZPE_PROP_MON_CLEANUP_TOKENS = "athenz.zpe.cleanup_tokens_secs";
+ public static final String ZPE_PROP_POLICY_DIR = "athenz.zpe.policy_dir";
+
+ static final String ZPE_METRIC_FACTORY_CLASS = "com.yahoo.athenz.common.metrics.impl.NoOpMetricFactory";
+
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeMetric.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeMetric.java
new file mode 100644
index 00000000000..35717ccf339
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeMetric.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import com.yahoo.athenz.zts.DomainMetric;
+import com.yahoo.athenz.zts.DomainMetricType;
+import com.yahoo.athenz.zts.DomainMetrics;
+import com.yahoo.rdl.JSON;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.ArrayList;
+import java.util.Timer;
+
+public class ZpeMetric {
+
+ public static final String ZPE_METRIC_FILE_PATH = "/var/zpe_stat/";
+ public static final String ZPE_WRITE_INTERVAL = "3600000";
+
+ public ConcurrentHashMap counter = new ConcurrentHashMap<>();
+ private static Timer FETCH_TIMER;
+ private static final Object TIMER_LOCK = new Object();
+ static boolean statsEnabled = Boolean.parseBoolean(System.getProperty(ZpeConsts.ZPE_PROP_STATS_ENABLED, "false"));
+
+ //constructor
+ ZpeMetric() {
+ File directory = new File(String.valueOf(getFilePath()));
+ directory.mkdir();
+ //setting the timer to the interval specified in the system property
+ if (statsEnabled) {
+ Integer interval = Integer.parseInt(System.getProperty(ZpeConsts.ZPE_PROP_METRIC_WRITE_INTERVAL, ZPE_WRITE_INTERVAL));
+ if (FETCH_TIMER == null) {
+ synchronized (TIMER_LOCK) {
+ if (FETCH_TIMER == null) {
+ FETCH_TIMER = new Timer();
+ FETCH_TIMER.schedule(new SchedulerService(), interval, interval);
+ }
+ }
+ }
+ }
+ }
+
+ //scheduler service
+ class SchedulerService extends TimerTask {
+ @Override
+ public void run() {
+ writeToFile();
+ }
+ }
+
+ String getFilePath() {
+ String rootDir = System.getenv("ROOT");
+ if (rootDir == null) {
+ rootDir = "/home/athenz";
+ }
+ final String defaultPath = rootDir + ZPE_METRIC_FILE_PATH;
+ String filePath = System.getProperty(ZpeConsts.ZPE_PROP_METRIC_FILE_PATH, defaultPath);
+
+ // verify it ends with / and handle accordingly
+
+ if (!filePath.endsWith(File.separator)) {
+ filePath = filePath.concat(File.separator);
+ }
+ return filePath;
+ }
+
+ //to increment a metric counter by 1
+ public void increment(String metricName, String domainName) {
+ if (statsEnabled) {
+ if (!counter.contains(domainName)) {
+ counter.putIfAbsent(domainName, new AtomicIntegerArray(DomainMetricType.LOAD_DOMAIN_GOOD.ordinal() + 1));
+ }
+ Integer index = com.yahoo.athenz.zts.DomainMetricType.valueOf(metricName).ordinal();
+ counter.get(domainName).incrementAndGet(index);
+ }
+ }
+
+ //to convert the atomicIntegerArray to JSON object
+ public DomainMetrics getMetrics(String domainName) {
+ ArrayList metricList = new ArrayList<>();
+ for (DomainMetricType label : DomainMetricType.values()) {
+ DomainMetric domainMetric = new DomainMetric();
+ domainMetric.setMetricType(label);
+ domainMetric.setMetricVal(counter.get(domainName).getAndSet(label.ordinal(), 0));
+ metricList.add(domainMetric);
+ }
+ DomainMetrics domainMetrics = new DomainMetrics()
+ .setDomainName(domainName)
+ .setMetricList(metricList);
+ return domainMetrics;
+ }
+
+ //to write the JSON to file
+ public void writeToFile() {
+ final String dirPath = getFilePath();
+ for (String domainName : counter.keySet()) {
+ DomainMetrics domainMetrics = getMetrics(domainName);
+ Long epoch = System.currentTimeMillis();
+ String filepath = dirPath + domainName + "_" + Long.toString(epoch) + ".json";
+ try {
+ Path path = Paths.get(filepath);
+ Files.write(path, JSON.bytes(domainMetrics));
+ } catch (IOException e) {
+ e.printStackTrace();
+ counter.remove(domainName);
+ }
+ }
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeThreadFactory.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeThreadFactory.java
new file mode 100644
index 00000000000..9e9f1c7d4e5
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeThreadFactory.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+class ZpeThreadFactory implements ThreadFactory {
+ private static final AtomicInteger POOLNUMBER = new AtomicInteger(1);
+ private final ThreadGroup group;
+ private final AtomicInteger threadNumber = new AtomicInteger(1);
+ private final String namePrefix;
+
+ public ZpeThreadFactory(String name) {
+ SecurityManager s = System.getSecurityManager();
+ group = (s != null) ? s.getThreadGroup() : Thread.currentThread()
+ .getThreadGroup();
+ namePrefix = name + "-pool-" + POOLNUMBER.getAndIncrement()
+ + "-thread-";
+ }
+
+ public Thread newThread(Runnable target) {
+ Thread thrd = new Thread(group, target, namePrefix
+ + threadNumber.getAndIncrement(), 0);
+ thrd.setDaemon(true);
+ if (thrd.getPriority() != Thread.NORM_PRIORITY) {
+ thrd.setPriority(Thread.NORM_PRIORITY);
+ }
+ return thrd;
+ }
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdMonitor.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdMonitor.java
new file mode 100644
index 00000000000..570b2c5afe5
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdMonitor.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Used in monitoring the policy directory for file changes.
+ */
+public class ZpeUpdMonitor implements Runnable {
+ private static final Logger LOG = LoggerFactory.getLogger(ZpeUpdMonitor.class);
+
+ private final ZpeUpdPolLoader updLoader;
+ private volatile boolean shutdownThread = false;
+ private String dirName = null;
+ private boolean firstRun = true;
+
+ private java.io.FilenameFilter polFileNameFilter = new java.io.FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ if (name.endsWith(".pol")) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ ZpeUpdMonitor(final ZpeUpdPolLoader zpeUpdLoader) {
+ updLoader = zpeUpdLoader;
+ dirName = updLoader.getDirName();
+ }
+
+ public void cancel() {
+ shutdownThread = true;
+ }
+
+ public File[] loadFileStatus() {
+ // read all the file names in the policy directory and add to the list
+ File pdir = new File(dirName);
+ File [] files = pdir.listFiles(polFileNameFilter);
+ if (files == null || files.length == 0) {
+ if (pdir.exists()) {
+ LOG.error("loadFileStatus: the directory=" + dirName + " exists, but there are no policy files in it");
+ } else {
+ LOG.error("loadFileStatus: the directory=" + dirName + " does NOT exist");
+ }
+ }
+ return files;
+ }
+
+ private void logRunMsg(Exception exc) {
+ dirName = dirName == null ? "MISSING-POL-DIR-NAME" : dirName;
+ String msg = "Reload directory=" + dirName;
+
+ if (exc == null) {
+ LOG.debug(msg);
+ } else {
+ LOG.error(msg, exc);
+ }
+ }
+
+ @Override
+ public void run() {
+ if (updLoader == null) {
+ LOG.error("run: No ZpeUpdPolLoader to monitor");
+ return;
+ }
+
+ if (shutdownThread) {
+ LOG.warn("run: monitor told to shutdown");
+ return;
+ }
+
+ // perform cleanup of RoleTokens - expired ones will be removed
+ ZpeUpdPolLoader.cleanupRoleTokenCache();
+
+ try {
+ updLoader.loadDb(loadFileStatus());
+ if (firstRun) {
+ firstRun = false;
+ synchronized (updLoader) {
+ updLoader.notify();
+ }
+ }
+ } catch (Exception exc) {
+ logRunMsg(exc);
+ return;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ logRunMsg(null);
+ }
+ }
+
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdPolLoader.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdPolLoader.java
new file mode 100644
index 00000000000..8ee0a92bbbf
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdPolLoader.java
@@ -0,0 +1,486 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.io.Closeable;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.rdl.JSON;
+import com.yahoo.rdl.Struct;
+import com.yahoo.athenz.auth.token.RoleToken;
+import com.yahoo.athenz.auth.util.Crypto;
+import com.yahoo.athenz.common.utils.SignUtils;
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchAll;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchEqual;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchRegex;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchStartsWith;
+import com.yahoo.athenz.zts.Assertion;
+import com.yahoo.athenz.zts.AssertionEffect;
+import com.yahoo.athenz.zts.DomainSignedPolicyData;
+import com.yahoo.athenz.zts.Policy;
+import com.yahoo.athenz.zts.PolicyData;
+import com.yahoo.athenz.zts.SignedPolicyData;
+
+public class ZpeUpdPolLoader implements Closeable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ZpeUpdPolLoader.class);
+
+ static long _sleepTimeMillis = -1;
+ static long _cleanupTokenInterval = 600000; // 600 secs = 10 minutes
+ static long _lastTokenCleanup = System.currentTimeMillis();
+
+ static {
+
+ String timeoutSecs = System.getProperty(ZpeConsts.ZPE_PROP_MON_TIMEOUT, null);
+ if (timeoutSecs == null) {
+ // default to 5 minutes
+ _sleepTimeMillis = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
+ } else {
+ try {
+ long secs = Long.parseLong(timeoutSecs);
+ _sleepTimeMillis = TimeUnit.MILLISECONDS.convert(secs, TimeUnit.SECONDS);
+ } catch (NumberFormatException exc) {
+ String errMsg = "start: WARNING: Failed using system property("
+ + ZpeConsts.ZPE_PROP_MON_TIMEOUT
+ + ") Got property value=" + timeoutSecs;
+ LOG.warn(errMsg, exc);
+ }
+ }
+
+ timeoutSecs = System.getProperty(ZpeConsts.ZPE_PROP_MON_CLEANUP_TOKENS, null);
+ if (timeoutSecs != null) {
+ try {
+ long secs = Long.parseLong(timeoutSecs);
+ _cleanupTokenInterval = TimeUnit.MILLISECONDS.convert(secs, TimeUnit.SECONDS);
+ } catch (NumberFormatException exc) {
+ String errMsg = "start: WARNING: Failed using system property("
+ + ZpeConsts.ZPE_PROP_MON_CLEANUP_TOKENS
+ + ") Got property value=" + timeoutSecs;
+ LOG.warn(errMsg, exc);
+ }
+ }
+ }
+
+ // create thread or event handler to monitor changes to ZpePolFiles
+ // see JavaYnetDbWrapper for scheduled thread way to monitor
+ // find the java7 api for monitoring files
+ // see http://docs.oracle.com/javase/tutorial/essential/io/notification.html
+ private ScheduledThreadPoolExecutor scheduledExecutorSvc = new ScheduledThreadPoolExecutor(
+ 1, new ZpeThreadFactory("ZpeUpdPolLoader"));
+
+ private ZpeUpdMonitor updMonWorker;
+
+ // key is the domain name, value is a map keyed by role name with list of assertions
+ ConcurrentHashMap>> domStandardRoleAllowMap = new ConcurrentHashMap<>();
+
+ // wild card role map, keys and values same as domRoleMap above
+ ConcurrentHashMap>> domWildcardRoleAllowMap = new ConcurrentHashMap<>();
+
+ // key is the domain name, value is a map keyed by role name with list of assertions
+ ConcurrentHashMap>> domStandardRoleDenyMap = new ConcurrentHashMap<>();
+
+ // wild card role map, keys and values same as domRoleMap above
+ ConcurrentHashMap>> domWildcardRoleDenyMap = new ConcurrentHashMap<>();
+
+ // cache of active Role Tokens
+ static ConcurrentHashMap roleTokenCacheMap = new ConcurrentHashMap();
+
+ // array of file status objects
+ static class ZpeFileStatus {
+ String fname;
+ String domain;
+ long modifyTimeMillis;
+ boolean validPolFile;
+
+ ZpeFileStatus(String fname, long modTimeMillis) {
+ domain = null;
+ modifyTimeMillis = modTimeMillis;
+ validPolFile = false;
+ }
+ }
+ private Map fileStatusRef = new ConcurrentHashMap();
+
+ private String polDirName;
+
+
+ ZpeUpdPolLoader(String dirName) {
+
+ if (null != dirName) {
+ polDirName = dirName;
+ try {
+ loadDb();
+ } catch (Exception exc) {
+ LOG.error("loadDb Failed", exc);
+ }
+ }
+ }
+
+ String getDirName() {
+ return polDirName;
+ }
+
+ Map getFileStatusMap() {
+ return fileStatusRef;
+ }
+
+ // return map of wildcard role with assertion list with allow effect
+ //
+ public Map> getWildcardRoleAllowMap(String domainName) {
+ return domWildcardRoleAllowMap.get(domainName);
+ }
+
+ // return map of role-name with assertion list with allow effect
+ //
+ public Map> getStandardRoleAllowMap(String domainName) {
+ return domStandardRoleAllowMap.get(domainName);
+ }
+
+ // return map of wildcard role with assertion list with deny effect
+ //
+ public Map> getWildcardRoleDenyMap(String domainName) {
+ return domWildcardRoleDenyMap.get(domainName);
+ }
+
+ // return map of role-name with assertion list with deny effect
+ //
+ public Map> getStandardRoleDenyMap(String domainName) {
+ return domStandardRoleDenyMap.get(domainName);
+ }
+
+ static public Map getRoleTokenCacheMap() {
+ return roleTokenCacheMap;
+ }
+
+ public void start() throws Exception {
+ if (polDirName == null) {
+ String errMsg = "ERROR: start: no policy directory name, can't monitor data files";
+ throw new Exception(errMsg);
+ }
+
+ if (updMonWorker == null) {
+ updMonWorker = new ZpeUpdMonitor(this);
+ }
+ scheduledExecutorSvc.scheduleAtFixedRate(updMonWorker, 0,
+ _sleepTimeMillis, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void close() {
+ if (updMonWorker != null) {
+ updMonWorker.cancel();
+ }
+ scheduledExecutorSvc.shutdownNow();
+ }
+
+ static public void cleanupRoleTokenCache() {
+ // is it time to cleanup?
+ long now = System.currentTimeMillis();
+ if (now < (_cleanupTokenInterval + _lastTokenCleanup)) {
+ return;
+ }
+
+ List expired = new ArrayList();
+ long nowSecs = now / 1000;
+ for (java.util.Enumeration keys = roleTokenCacheMap.keys();
+ keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ RoleToken rToken = roleTokenCacheMap.get(key);
+ if (rToken == null) {
+ continue;
+ }
+ long expiry = rToken.getExpiryTime();
+ if (expiry != 0 && expiry < nowSecs) {
+ expired.add(key);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("cleanupRoleTokenCache: Remove expired token. now(secs)="
+ + nowSecs + " expiry=" + expiry + " token=" + key);
+ }
+ }
+ }
+ // HAVE: list of expired tokens
+ for (String key: expired) {
+ roleTokenCacheMap.remove(key);
+ }
+ _lastTokenCleanup = now; // reset time of last cleanup
+ }
+
+ void loadDb() {
+ if (updMonWorker == null) {
+ updMonWorker = new ZpeUpdMonitor(this);
+ }
+ File[] polFileNames = updMonWorker.loadFileStatus();
+ loadDb(polFileNames);
+ }
+
+ /**
+ * Process the given policy file list and determine if any of the
+ * policy domain files have been updated. New ones will be loaded
+ * into the policy domain map.
+ **/
+ void loadDb(File []polFileNames) {
+ if (polFileNames == null) {
+ LOG.error("loadDb: no policy files to load");
+ return;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadDb: START thrd=" + Thread.currentThread().getId() + " directory=" + polDirName);
+ }
+ for (File polFile: polFileNames) {
+
+ String fileName = polFile.getName();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadDb: START thrd=" + Thread.currentThread().getId() + " file name=" + fileName);
+ }
+ long lastModMilliSeconds = polFile.lastModified();
+ Map fsmap = getFileStatusMap();
+ ZpeFileStatus fstat = fsmap.get(fileName);
+ if (fstat != null) {
+
+ if (polFile.exists() == false) { // file was deleted
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadDb: file(" + fileName + " ) was deleted or doesn't exist");
+ }
+ fsmap.remove(fileName);
+
+ if (fstat.validPolFile == false || fstat.domain == null) {
+ continue;
+ }
+
+ // replace domain with empty data
+ //
+ domStandardRoleAllowMap.put(fstat.domain, new TreeMap>());
+ domWildcardRoleAllowMap.put(fstat.domain, new TreeMap>());
+ domStandardRoleDenyMap.put(fstat.domain, new TreeMap>());
+ domWildcardRoleDenyMap.put(fstat.domain, new TreeMap>());
+ continue;
+ }
+
+ // check if file was modified since last time it was loaded
+ //
+ if (lastModMilliSeconds <= fstat.modifyTimeMillis) {
+ // if valid and up to date return
+ // if not valid, may be due to timing issue for a new
+ // file not completely written - and file system timestamp
+ // only accurate up to the second - not millis
+ String timeMsg = " last-file-mod-time=" + lastModMilliSeconds;
+ if (fstat.validPolFile == true) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadDb: ignore reload file: " + fileName + " since up to date: " + timeMsg);
+ }
+ continue;
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("loadDb: retry load file: " + fileName + " since last load was bad: " + timeMsg);
+ }
+
+ }
+ } else {
+ fstat = new ZpeFileStatus(fileName, lastModMilliSeconds);
+ fsmap.put(fileName, fstat);
+ }
+ loadFile(polFile);
+ }
+ }
+
+ ZpeMatch getMatchObject(String value) {
+
+ ZpeMatch match = null;
+ if ("*".equals(value)) {
+ match = new ZpeMatchAll();
+ } else {
+ int anyCharMatch = value.indexOf('*');
+ int singleCharMatch = value.indexOf('?');
+
+ if (anyCharMatch == -1 && singleCharMatch == -1) {
+ match = new ZpeMatchEqual(value);
+ } else if (anyCharMatch == value.length() - 1 && singleCharMatch == -1) {
+ match = new ZpeMatchStartsWith(value.substring(0, value.length() - 1));
+ } else {
+ match = new ZpeMatchRegex(value);
+ }
+ }
+
+ return match;
+ }
+
+ /**
+ * Loads and parses the given file. It will create the domain assertion
+ * list per role and put it into the domain policy maps(domRoleMap, domWildcardRoleMap).
+ **/
+ private void loadFile(File polFile) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadFile: file(" + polFile.getName() + ")");
+ }
+
+ Path path = Paths.get(polDirName + File.separator + polFile.getName());
+ DomainSignedPolicyData spols = null;
+ try {
+ spols = JSON.fromBytes(Files.readAllBytes(path), DomainSignedPolicyData.class);
+ } catch (Exception ex) {
+ LOG.error("loadFile: unable to decode policy file=" + polFile.getName() + " error: " + ex.getMessage());
+ }
+ if (spols == null) {
+ LOG.error("loadFile: unable to decode domain file=" + polFile.getName());
+ // mark this as an invalid file
+ Map fsmap = getFileStatusMap();
+ ZpeFileStatus fstat = fsmap.get(polFile.getName());
+ if (fstat != null) {
+ fstat.validPolFile = false;
+ }
+ return;
+ }
+
+ SignedPolicyData signedPolicyData = spols.getSignedPolicyData();
+ String signature = spols.getSignature();
+ String keyId = spols.getKeyId();
+
+ // first let's verify the ZTS signature for our policy file
+
+ boolean verified = false;
+ if (signedPolicyData != null) {
+ java.security.PublicKey pubKey = AuthZpeClient.getZtsPublicKey(keyId);
+ verified = Crypto.verify(SignUtils.asCanonicalString(signedPolicyData), pubKey, signature);
+ }
+
+ PolicyData policyData = null;
+ if (verified) {
+ // now let's verify that the ZMS signature for our policy file
+ policyData = signedPolicyData.getPolicyData();
+ signature = signedPolicyData.getZmsSignature();
+ keyId = signedPolicyData.getZmsKeyId();
+
+ if (policyData != null) {
+ java.security.PublicKey pubKey = AuthZpeClient.getZmsPublicKey(keyId);
+ verified = Crypto.verify(SignUtils.asCanonicalString(policyData), pubKey, signature);
+ }
+ }
+
+ if (verified == false) {
+ LOG.error("loadFile: policy file=" + polFile.getName() + " is invalid");
+ // mark this as an invalid file
+ Map fsmap = getFileStatusMap();
+ ZpeFileStatus fstat = fsmap.get(polFile.getName());
+ if (fstat != null) {
+ fstat.validPolFile = false;
+ }
+ return;
+ }
+
+ // HAVE: valid policy file
+
+ String domainName = policyData.getDomain();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadFile: policy file(" + polFile.getName() + ") for domain(" + domainName + ") is valid");
+ }
+
+ // Process the policies into assertions, process the assertions: action, resource, role
+ // If there is a wildcard in the action or resource, compile the
+ // regexpr and place it into the assertion Struct.
+ // This is a performance enhancement for AuthZpeClient when it
+ // performs the authorization checks.
+ Map> roleStandardAllowMap = new TreeMap>();
+ Map> roleWildcardAllowMap = new TreeMap>();
+ Map> roleStandardDenyMap = new TreeMap>();
+ Map> roleWildcardDenyMap = new TreeMap>();
+ List policies = policyData.getPolicies();
+ for (Policy policy : policies) {
+ String pname = policy.getName();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("loadFile: domain(" + domainName + ") policy(" + pname + ")");
+ }
+ List assertions = policy.getAssertions();
+ if (assertions == null) {
+ continue;
+ }
+ for (Assertion assertion : assertions) {
+ com.yahoo.rdl.Struct strAssert = new Struct();
+ strAssert.put(ZpeConsts.ZPE_FIELD_POLICY_NAME, pname);
+
+ String passertAction = assertion.getAction();
+ ZpeMatch matchStruct = getMatchObject(passertAction);
+ strAssert.put(ZpeConsts.ZPE_ACTION_MATCH_STRUCT, matchStruct);
+
+ String passertResource = assertion.getResource();
+ String rsrc = AuthZpeClient.stripDomainPrefix(passertResource, domainName, passertResource);
+ strAssert.put(ZpeConsts.ZPE_FIELD_RESOURCE, rsrc);
+ matchStruct = getMatchObject(rsrc);
+ strAssert.put(ZpeConsts.ZPE_RESOURCE_MATCH_STRUCT, matchStruct);
+
+ String passertRole = assertion.getRole();
+ String pRoleName = AuthZpeClient.stripDomainPrefix(passertRole, domainName, passertRole);
+ // strip the prefix "role." too
+ pRoleName = pRoleName.replaceFirst("^role.", "");
+ strAssert.put(ZpeConsts.ZPE_FIELD_ROLE, pRoleName);
+
+ // based on the effect and role name determine what
+ // map we're going to use
+
+ Map> roleMap = null;
+ AssertionEffect passertEffect = assertion.getEffect();
+ matchStruct = getMatchObject(pRoleName);
+ strAssert.put(ZpeConsts.ZPE_ROLE_MATCH_STRUCT, matchStruct);
+
+ if (passertEffect != null && passertEffect.toString().compareTo("DENY") == 0) {
+ if (matchStruct instanceof ZpeMatchEqual) {
+ roleMap = roleStandardDenyMap;
+ } else {
+ roleMap = roleWildcardDenyMap;
+ }
+ } else {
+ if (matchStruct instanceof ZpeMatchEqual) {
+ roleMap = roleStandardAllowMap;
+ } else {
+ roleMap = roleWildcardAllowMap;
+ }
+ }
+
+ List assertList = roleMap.get(pRoleName);
+ if (assertList == null) {
+ assertList = new ArrayList();
+ roleMap.put(pRoleName, assertList);
+ }
+ assertList.add(strAssert);
+ }
+ }
+
+ Map fsmap = getFileStatusMap();
+ ZpeFileStatus fstat = fsmap.get(polFile.getName());
+ if (fstat != null) {
+ fstat.validPolFile = true;
+ fstat.domain = domainName;
+ }
+
+ domStandardRoleAllowMap.put(domainName, roleStandardAllowMap);
+ domWildcardRoleAllowMap.put(domainName, roleWildcardAllowMap);
+ domStandardRoleDenyMap.put(domainName, roleStandardDenyMap);
+ domWildcardRoleDenyMap.put(domainName, roleWildcardDenyMap);
+ }
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdater.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdater.java
new file mode 100644
index 00000000000..cd63898ca38
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeUpdater.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.token.RoleToken;
+import com.yahoo.rdl.Struct;
+
+public class ZpeUpdater implements ZpeClient {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ZpeUpdater.class);
+
+ // default policy directory "/home/athenz/var/zpe/"
+ private static final String ZPECLT_POLDIR_DEFAULT;
+ private static final ZpeUpdPolLoader POLICYLOADER;
+
+ static {
+ String rootDir = System.getenv("ROOT");
+
+ if (null == rootDir) {
+ rootDir = File.separator + "home" + File.separator + "athenz";
+ }
+
+ ZPECLT_POLDIR_DEFAULT = rootDir + File.separator + "var"
+ + File.separator + "zpe";
+
+ String dirName = System.getProperty(ZpeConsts.ZPE_PROP_POLICY_DIR, ZPECLT_POLDIR_DEFAULT);
+
+ try {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("static-init: start monitoring policy directory=" + dirName);
+ }
+ // load the file
+ POLICYLOADER = new ZpeUpdPolLoader(dirName);
+
+ // this will start monitoring policy directory for file mods
+ POLICYLOADER.start();
+
+ } catch (Exception exc) {
+ LOG.error("static-init: failed loading policy files. System property("
+ + ZpeConsts.ZPE_PROP_POLICY_DIR + ") Policy-directory(" + dirName + ")",
+ exc);
+ throw new RuntimeException(exc);
+ }
+ }
+
+ // @param domain can be null
+ public void init(String domain) {
+ try {
+ synchronized (POLICYLOADER) {
+ POLICYLOADER.wait(5000); // wait max of 5 seconds
+ }
+ } catch (InterruptedException exc) {
+ LOG.warn("init: waiting for policy loader to be ready, continuing...");
+ }
+ }
+
+ // return current cache of role tokens collected from the remote clients
+ //
+ public Map getRoleTokenCacheMap() {
+ return ZpeUpdPolLoader.getRoleTokenCacheMap();
+ }
+
+ public Map> getWildcardAllowAssertions(String domain) {
+ return POLICYLOADER.getWildcardRoleAllowMap(domain);
+ }
+
+ public Map> getRoleAllowAssertions(String domain) {
+ return POLICYLOADER.getStandardRoleAllowMap(domain);
+ }
+
+ public Map> getWildcardDenyAssertions(String domain) {
+ return POLICYLOADER.getWildcardRoleDenyMap(domain);
+ }
+
+ public Map> getRoleDenyAssertions(String domain) {
+ return POLICYLOADER.getStandardRoleDenyMap(domain);
+ }
+}
+
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeYcrKey.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeYcrKey.java
new file mode 100644
index 00000000000..fa7f27e44d1
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/ZpeYcrKey.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+public class ZpeYcrKey {
+
+ private String keyName;
+ private short version = 0;
+
+ String getKeyName() {
+ return keyName;
+ }
+ short getVersion() {
+ return version;
+ }
+ void setKeyName(String value) {
+ keyName = value;
+ }
+ void setVersion(short value) {
+ version = value;
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/ZpeMatch.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/ZpeMatch.java
new file mode 100644
index 00000000000..aa5d51c354e
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/ZpeMatch.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.match;
+
+public interface ZpeMatch {
+
+ /*
+ * @return boolean value if the given string matches for ZPE check
+ */
+ public boolean matches(String value);
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchAll.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchAll.java
new file mode 100644
index 00000000000..8df6c8120dd
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchAll.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.match.impl;
+
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+
+public class ZpeMatchAll implements ZpeMatch {
+
+ public ZpeMatchAll() {
+ }
+
+ public boolean matches(String value) {
+ return true;
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchEqual.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchEqual.java
new file mode 100644
index 00000000000..962a2600ca9
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchEqual.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.match.impl;
+
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+
+public class ZpeMatchEqual implements ZpeMatch {
+
+ private String matchValue;
+ public ZpeMatchEqual(String value) {
+ matchValue = value;
+ }
+
+ public boolean matches(String value) {
+ return matchValue.equals(value);
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchRegex.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchRegex.java
new file mode 100644
index 00000000000..2918713af1b
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchRegex.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.match.impl;
+
+import java.util.regex.Pattern;
+
+import com.yahoo.athenz.zpe.AuthZpeClient;
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+
+public class ZpeMatchRegex implements ZpeMatch {
+
+ private Pattern pattern;
+ public ZpeMatchRegex(String value) {
+ pattern = Pattern.compile(AuthZpeClient.patternFromGlob(value));
+ }
+
+ public boolean matches(String value) {
+ return pattern.matcher(value).matches();
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchStartsWith.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchStartsWith.java
new file mode 100644
index 00000000000..11c01b5e249
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/match/impl/ZpeMatchStartsWith.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.match.impl;
+
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+
+public class ZpeMatchStartsWith implements ZpeMatch {
+
+ private String prefix;
+ public ZpeMatchStartsWith(String value) {
+ prefix = value;
+ }
+
+ public boolean matches(String value) {
+ return value.startsWith(prefix);
+ }
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStore.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStore.java
new file mode 100644
index 00000000000..32729541b94
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStore.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.pkey;
+
+import java.security.PublicKey;
+
+public interface PublicKeyStore {
+
+ /**
+ * Returns the ZTS PublicKey object for the given identifier
+ * @param keyId key identifier
+ * @return PublicKey
+ */
+ public PublicKey getZtsKey(String keyId);
+
+ /**
+ * Returns the ZMS PublicKey object for the given identifier
+ * @param keyId key identifier
+ * @return PublicKey
+ */
+ public PublicKey getZmsKey(String keyId);
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStoreFactory.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStoreFactory.java
new file mode 100644
index 00000000000..1c110ad61cb
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/PublicKeyStoreFactory.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.pkey;
+
+public interface PublicKeyStoreFactory {
+
+ /**
+ * Create and return a new PublicKeyStore instance
+ * @return PublicKeyStore instance
+ */
+ public PublicKeyStore create();
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStore.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStore.java
new file mode 100644
index 00000000000..7707d63ee5c
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStore.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.pkey.file;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.util.Crypto;
+import com.yahoo.athenz.common.config.AthenzConfig;
+import com.yahoo.athenz.zms.PublicKeyEntry;
+import com.yahoo.athenz.zpe.ZpeConsts;
+import com.yahoo.athenz.zpe.pkey.PublicKeyStore;
+import com.yahoo.rdl.JSON;
+
+public class FilePublicKeyStore implements PublicKeyStore {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FilePublicKeyStore.class);
+
+ private static final String ZPE_ATHENZ_CONFIG = "/conf/athenz/athenz.conf";
+
+ private Map ztsPublicKeyMap = new ConcurrentHashMap<>();
+ private Map zmsPublicKeyMap = new ConcurrentHashMap<>();
+
+ public void init() {
+
+ String rootDir = System.getenv("ROOT");
+ if (rootDir == null) {
+ rootDir = "/home/athenz";
+ }
+
+ String confFileName = System.getProperty(ZpeConsts.ZPE_PROP_ATHENZ_CONF,
+ rootDir + ZPE_ATHENZ_CONFIG);
+ try {
+ Path path = Paths.get(confFileName);
+ AthenzConfig conf = JSON.fromBytes(Files.readAllBytes(path), AthenzConfig.class);
+
+ loadPublicKeys(conf.getZtsPublicKeys(), ztsPublicKeyMap);
+ loadPublicKeys(conf.getZmsPublicKeys(), zmsPublicKeyMap);
+
+ } catch (Exception ex) {
+ LOG.error("Unable to extract ZMS Url from {} exc: {}",
+ confFileName, ex.getMessage());
+ return;
+ }
+ }
+
+ void loadPublicKeys(ArrayList publicKeys, Map keyMap) {
+
+ if (publicKeys == null) {
+ return;
+ }
+
+ for (PublicKeyEntry publicKey : publicKeys) {
+ String id = publicKey.getId();
+ String key = publicKey.getKey();
+ if (key == null || id == null) {
+ continue;
+ }
+ PublicKey pubKey = null;
+ try {
+ pubKey = Crypto.loadPublicKey(Crypto.ybase64DecodeString(key));
+ } catch (Exception e) {
+ LOG.error("Invalid ZTS public key for id: " + id + " - " + e.getMessage());
+ continue;
+ }
+ keyMap.put(id, pubKey);
+ }
+ }
+
+ @Override
+ public PublicKey getZtsKey(String keyId) {
+ if (keyId == null) {
+ return null;
+ }
+ return ztsPublicKeyMap.get(keyId);
+ }
+
+ @Override
+ public PublicKey getZmsKey(String keyId) {
+ if (keyId == null) {
+ return null;
+ }
+ return zmsPublicKeyMap.get(keyId);
+ }
+
+}
diff --git a/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStoreFactory.java b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStoreFactory.java
new file mode 100644
index 00000000000..fb83a25f5f3
--- /dev/null
+++ b/clients/java/zpe/src/main/java/com/yahoo/athenz/zpe/pkey/file/FilePublicKeyStoreFactory.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe.pkey.file;
+
+import com.yahoo.athenz.zpe.pkey.PublicKeyStore;
+import com.yahoo.athenz.zpe.pkey.PublicKeyStoreFactory;
+
+public class FilePublicKeyStoreFactory implements PublicKeyStoreFactory {
+
+ @Override
+ public PublicKeyStore create() {
+ FilePublicKeyStore keyStore = new FilePublicKeyStore();
+ keyStore.init();
+ return keyStore;
+ }
+}
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/MockMetricFactory.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/MockMetricFactory.java
new file mode 100644
index 00000000000..2448c644f24
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/MockMetricFactory.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.util.Map;
+
+import com.yahoo.athenz.common.metrics.Metric;
+import com.yahoo.athenz.common.metrics.MetricFactory;
+
+import java.util.HashMap;
+
+public class MockMetricFactory implements MetricFactory {
+
+ @Override
+ public Metric create() {
+ return new MockMetric();
+ }
+
+ public static class MockMetric implements Metric {
+
+ Map metricMap = new HashMap<>();
+
+ public void increment(String metric, int count) {
+ Integer mcnt = metricMap.get(metric);
+ if (mcnt == null) {
+ metricMap.put(metric, new Integer(count));
+ System.out.println("MockMetric:increment: " + metric + "=1");
+ } else {
+ int cnt = mcnt.intValue() + count;
+ metricMap.put(metric, new Integer(cnt));
+ System.out.println("MockMetric:increment: " + metric + "=" + cnt);
+ }
+ }
+
+ @Override
+ public void increment(String metric) {
+ increment(metric, 1);
+ }
+
+ @Override
+ public void increment(String metric, String domainName) {
+ increment(metric + domainName, 1);
+ }
+
+ @Override
+ public void increment(String metric, String domainName, int count) {
+ increment(metric + domainName, count);
+ }
+
+ public int metricCount(String metric) {
+ Integer icnt = metricMap.get(metric);
+ if (icnt == null) {
+ return -1;
+ }
+ return icnt.intValue();
+ }
+ public int metricCount(String metric, String domainName) {
+ return metricCount(metric + domainName);
+ }
+
+ @Override
+ public Object startTiming(String metric, String domainName) {
+ return null;
+ }
+
+ @Override
+ public void stopTiming(Object timerMetric) {
+ }
+
+ @Override
+ public void flush() {
+ metricMap.clear();
+ }
+
+ @Override
+ public void quit() {
+ metricMap.clear();
+ }
+ }
+}
+
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestAuthZpe.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestAuthZpe.java
new file mode 100644
index 00000000000..f1fde18a277
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestAuthZpe.java
@@ -0,0 +1,1016 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.yahoo.athenz.auth.token.RoleToken;
+import com.yahoo.athenz.auth.util.Crypto;
+import com.yahoo.athenz.common.utils.SignUtils;
+import com.yahoo.athenz.zpe.AuthZpeClient;
+import com.yahoo.athenz.zpe.ZpeUpdPolLoader;
+import com.yahoo.athenz.zpe.AuthZpeClient.AccessCheckStatus;
+import com.yahoo.athenz.zts.DomainSignedPolicyData;
+import com.yahoo.athenz.zts.SignedPolicyData;
+import com.yahoo.rdl.JSON;
+
+/**
+ * These tests are dependent on a policy file in a local dir.
+ */
+public class TestAuthZpe {
+
+ private PrivateKey ztsPrivateKeyK0;
+ private PrivateKey ztsPrivateKeyK1;
+ private PrivateKey ztsPrivateKeyK17;
+ private PrivateKey ztsPrivateKeyK99;
+ private PrivateKey zmsPrivateKeyK0;
+
+ private final String roleVersion = "Z1";
+ private final long expirationTime = 100; // 100 seconds
+ private final String salt = "aAkjbbDMhnLX";
+
+ private RoleToken rToken0AnglerPublic = null;
+ private RoleToken rToken0AnglerExpirePublic = null;
+ private RoleToken rToken0AnglerAdmin = null;
+ private RoleToken rToken0SportsAdmin = null;
+ private RoleToken rToken1SportsAdmin = null;
+ private RoleToken rToken0AnglerPachinko = null;
+ private RoleToken rToken0CoreTechPublic = null;
+ private RoleToken rToken0EmptyPublic = null;
+ private RoleToken rToken0AnglerRegex = null;
+
+ private static boolean sleepCompleted = false;
+
+ @BeforeClass
+ public void beforeClass() throws IOException {
+
+ Path path = Paths.get("./src/test/resources/zts_private_k0.pem");
+ ztsPrivateKeyK0 = Crypto.loadPrivateKey(new String((Files.readAllBytes(path))));
+
+ path = Paths.get("./src/test/resources/zms_private_k0.pem");
+ zmsPrivateKeyK0 = Crypto.loadPrivateKey(new String((Files.readAllBytes(path))));
+
+ path = Paths.get("./src/test/resources/zts_private_k1.pem");
+ ztsPrivateKeyK1 = Crypto.loadPrivateKey(new String((Files.readAllBytes(path))));
+
+ path = Paths.get("./src/test/resources/zts_private_k17.pem");
+ ztsPrivateKeyK17 = Crypto.loadPrivateKey(new String((Files.readAllBytes(path))));
+
+ path = Paths.get("./src/test/resources/zts_private_k99.pem");
+ ztsPrivateKeyK99 = Crypto.loadPrivateKey(new String((Files.readAllBytes(path))));
+
+ List roles = new ArrayList();
+ roles.add("public");
+ rToken0AnglerPublic = createRoleToken("angler", roles, "0");
+ rToken0AnglerExpirePublic = createRoleToken("angler", roles, "0", 3);
+ rToken0CoreTechPublic = createRoleToken("coretech", roles, "0");
+ rToken0EmptyPublic = createRoleToken("empty", roles, "0");
+ roles = new ArrayList();
+ roles.add("admin");
+ rToken0AnglerAdmin = createRoleToken("angler", roles, "0");
+ rToken0SportsAdmin = createRoleToken("sports", roles, "0");
+ rToken1SportsAdmin = createRoleToken("sports", roles, "1");
+
+ roles = new ArrayList();
+ roles.add("pachinko");
+ rToken0AnglerPachinko = createRoleToken("angler", roles, "0");
+
+ roles = new ArrayList();
+ roles.add("full_regex");
+ roles.add("matchall");
+ roles.add("matchstarts");
+ roles.add("matchcompare");
+ roles.add("matchregex");
+ rToken0AnglerRegex = createRoleToken("angler", roles, "0");
+
+ // NOTE: we will create file with different suffix so as not to confuse
+ // ZPE update-load thread due to possible timing issue.
+ // Then rename it with ".pol" suffix afterwards.
+ // Issue: file is created, but file is empty because it has not
+ // been written out yet - thus zpe thinks its a bad file and will
+ // wait for it to get updated before trying to reload.
+ // Ouch, but the file doesnt get a change in modified timestamp so zpe
+ // never reloads.
+
+ path = Paths.get("./src/test/resources/angler.pol");
+ DomainSignedPolicyData domainSignedPolicyData = JSON.fromBytes(Files.readAllBytes(path),
+ DomainSignedPolicyData.class);
+ SignedPolicyData signedPolicyData = domainSignedPolicyData.getSignedPolicyData();
+ String signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData.getPolicyData()), zmsPrivateKeyK0);
+ signedPolicyData.setZmsSignature(signature).setZmsKeyId("0");
+ signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData), ztsPrivateKeyK0);
+ domainSignedPolicyData.setSignature(signature).setKeyId("0");
+ File file = new File("./src/test/resources/pol_dir/angler.gen");
+ file.createNewFile();
+ Files.write(file.toPath(), JSON.bytes(domainSignedPolicyData));
+ File renamedFile = new File("./src/test/resources/pol_dir/angler.pol");
+ file.renameTo(renamedFile);
+
+ path = Paths.get("./src/test/resources/sports.pol");
+ domainSignedPolicyData = JSON.fromBytes(Files.readAllBytes(path), DomainSignedPolicyData.class);
+ signedPolicyData = domainSignedPolicyData.getSignedPolicyData();
+ signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData.getPolicyData()), zmsPrivateKeyK0);
+ signedPolicyData.setZmsSignature(signature).setZmsKeyId("0");
+ signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData), ztsPrivateKeyK1);
+ domainSignedPolicyData.setSignature(signature).setKeyId("1");
+ file = new File("./src/test/resources/pol_dir/sports.gen");
+ file.createNewFile();
+ Files.write(file.toPath(), JSON.bytes(domainSignedPolicyData));
+ renamedFile = new File("./src/test/resources/pol_dir/sports.pol");
+ file.renameTo(renamedFile);
+
+ path = Paths.get("./src/test/resources/empty.pol");
+ domainSignedPolicyData = JSON.fromBytes(Files.readAllBytes(path), DomainSignedPolicyData.class);
+ signedPolicyData = domainSignedPolicyData.getSignedPolicyData();
+ signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData.getPolicyData()), zmsPrivateKeyK0);
+ signedPolicyData.setZmsSignature(signature).setZmsKeyId("0");
+ signature = Crypto.sign(SignUtils.asCanonicalString(signedPolicyData), ztsPrivateKeyK0);
+ domainSignedPolicyData.setSignature(signature).setKeyId("0");
+ file = new File("./src/test/resources/pol_dir/empty.gen");
+ file.createNewFile();
+ Files.write(file.toPath(), JSON.bytes(domainSignedPolicyData));
+
+ renamedFile = new File("./src/test/resources/pol_dir/empty.pol");
+ file.renameTo(renamedFile);
+ }
+
+ @BeforeMethod
+ private void loadFiles() {
+
+ if (sleepCompleted) {
+ return;
+ }
+ // sleep for a short period of time so the library has a chance
+ // to load all the policy files since that's done by a background
+ // thread
+
+ AuthZpeClient.init();
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ }
+
+ sleepCompleted = true;
+ }
+
+ private RoleToken createRoleToken(String svcDomain, List roles, String keyId, long expiry) {
+ RoleToken token = new RoleToken.Builder(roleVersion, svcDomain, roles)
+ .salt(salt).expirationWindow(expiry).keyId(keyId).build();
+
+ PrivateKey key = null;
+ if ("1".equals(keyId)) {
+ key = ztsPrivateKeyK1;
+ } else if ("0".equals(keyId)) {
+ key = ztsPrivateKeyK0;
+ } else if ("17".equals(keyId)) {
+ key = ztsPrivateKeyK17;
+ } else if ("99".equals(keyId)) {
+ key = ztsPrivateKeyK99;
+ }
+
+ token.sign(key);
+ return token;
+ }
+
+ private RoleToken createRoleToken(String svcDomain, List roles, String keyId) {
+ return createRoleToken(svcDomain, roles, keyId, expirationTime);
+ }
+
+ @Test
+ public void testKeyIds() {
+ String action = "read";
+ StringBuilder roleName = new StringBuilder();
+
+ //Test key id 0 on Angler domain
+ String angResource = "angler:stuff";
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW, "rsrc=" + angResource + " act=" + action);
+ Assert.assertEquals(roleName.toString(), "public");
+
+ //Test key id 1 on Sports domain
+ roleName.setLength(0);
+ String resource = "sports.NFL_DB";
+ status = AuthZpeClient.allowAccess(rToken1SportsAdmin, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW, "rsrc=" + resource + " act=" + action);
+ Assert.assertEquals(roleName.toString(), "admin");
+ }
+
+ @Test
+ public void testWrongKeyId() {
+ String action = "REad";
+ StringBuilder roleName = new StringBuilder();
+
+ //Test key id 0 on Sports domain - should fail because its signed with key id 1
+ String resource = "sports.NFL_DB";
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0SportsAdmin, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "admin");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0SportsAdmin.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "admin");
+
+ // multi tokens test with duplicate tokens
+ tokenList = new ArrayList();
+ tokenList.add(rToken0SportsAdmin.getSignedToken());
+ tokenList.add(rToken0SportsAdmin.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "admin");
+ }
+
+ @Test
+ public void testPublicReadAllowedMixCaseActionResource() {
+
+ String action = "REad";
+ String angResource = "ANGler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testTokenExpired() {
+ String action = "REad";
+ String angResource = "ANGler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ RoleToken tokenMock = Mockito.mock(RoleToken.class);
+ Mockito.when(tokenMock.getExpiryTime()).thenReturn(1L); // too old
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(tokenMock, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_ROLETOKEN_EXPIRED);
+ }
+
+ @Test
+ public void testPublicReadAllowed() {
+ String action = "read";
+ String angResource = "angler:stuff";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testPublicReadMismatchDomain() {
+ String action = "read";
+ String angResource = "anglerTest:stuff";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_MISMATCH);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_MISMATCH);
+ Assert.assertEquals(roleName.toString(), "");
+ }
+
+ @Test
+ public void testPublicReadDomainNotFound() {
+ String action = "read";
+ String angResource = "CoreTech:stuff";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0CoreTechPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_NOT_FOUND);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_NOT_FOUND);
+ Assert.assertEquals(roleName.toString(), "");
+ }
+
+ @Test
+ public void testPublicReadDomainEmpty() {
+ String action = "read";
+ String angResource = "empty:stuff";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0EmptyPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_EMPTY);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0EmptyPublic.getSignedToken());
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_EMPTY);
+ Assert.assertEquals(roleName.toString(), "");
+ }
+
+ @Test
+ public void testPublicReadInvalidRoleToken() {
+ String action = "read";
+ String angResource = "angler:stuff";
+
+ // make the token invalid by adding chars to the signature
+ String roleToken = rToken0AnglerPublic.getSignedToken();
+ roleToken = roleToken.replace(";s=", ";s=ab");
+ AccessCheckStatus status = AuthZpeClient.allowAccess(roleToken, angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_ROLETOKEN_INVALID);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(roleToken); // add the bad one in
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "public");
+ }
+
+ @Test
+ public void testPublicReadExpiredRoleToken() {
+ String action = "read";
+ String angResource = "angler:stuff";
+
+ // sleep 3 seconds so our token gets expired
+
+ try {
+ Thread.sleep(3000);
+ } catch (Exception exc) {
+ }
+
+ // the roletoken validate return false regardless if the token is
+ // invalid due to expiry or invalid signature. So we'll only
+ // the expired roletoken if we add it to the cache and then
+ // try to use it again, but the cache clear test case sets
+ // the timeout to 1secs so as soon as it's added, within a
+ // second it's removed so we can't wait until it's expired to
+ // test again. so for know we'll just get invalid token
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerExpirePublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_ROLETOKEN_INVALID);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken()); // add the expired one in
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "public");
+ }
+
+ @Test
+ public void testPublicReadInvalidParameters() {
+ String action = "read";
+ String angResource = "anglerTest:stuff";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), "", action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_INVALID_PARAMETERS);
+
+ status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), angResource, "");
+ Assert.assertEquals(status, AccessCheckStatus.DENY_INVALID_PARAMETERS);
+ }
+
+ @Test
+ public void testPublicWriteAllowed() {
+ String action = "write";
+ String angResource = "angler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "public");
+ }
+
+ @Test
+ public void testPublicWriteAllowedMixCaseActionResource() {
+ String action = "WRite";
+ String angResource = "angLEr:STUff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testPublicUknActDenied() {
+ String action = "WRiteREad";
+ String angResource = "angler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testPublicThrowDenied() {
+ String action = "THrow";
+ String angResource = "angler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY);
+ }
+
+ @Test
+ public void testAdminThrowAllowed() {
+ String action = "THrow";
+ String angResource = "angler:stuff";
+ StringBuilder roleName = new StringBuilder();
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerAdmin, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testValidAccessResource() {
+ String action = "ACCESS";
+ String angResource = "angler:tables.blah";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPachinko, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "pachinko");
+ }
+
+ @Test
+ public void testInvalidAccessResource() {
+ String action = "ACCESS";
+ String angResource = "angler:tables.blahblah";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPachinko, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ Assert.assertEquals(roleName.toString(), "");
+ }
+
+ @Test
+ public void testPublicFishingDenied() {
+ String action = "fish";
+ String angResource = "angler:spawningpondLittleBassLake";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY);
+ Assert.assertEquals(roleName.toString(), "public");
+ }
+
+ @Test
+ public void testPublicFishingAllowed() {
+ String action = "fish";
+ String angResource = "angler:stockedpondBigBassLake";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "public");
+ }
+
+ @Test
+ public void testPublicFishingAllowedTokenString() {
+ String action = "fish";
+ String angResource = "angler:stockedpondBigBassLake";
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerPublic.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testCleanupOfToken() {
+ // perform an allowed access check
+ String action = "fish";
+ String angResource = "angler:stockedpondBigBassLake";
+ List roles = new ArrayList();
+ roles.add("public");
+ roles.add("admin");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1); // 1 sec expiry
+ String signedToken = rtoken.getSignedToken();
+ AccessCheckStatus status = AuthZpeClient.allowAccess(signedToken, angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+
+ Map roleMap = ZpeUpdPolLoader.getRoleTokenCacheMap();
+ RoleToken mapToken = roleMap.get(signedToken);
+ Assert.assertEquals(signedToken.equals(mapToken.getSignedToken()), true);
+ // then in a loop, check for existence of the token in the token map
+ // increase the timeout to 30 secs. in sd sometimes it takes a while
+ // before the entry is expired.
+ for (int cnt = 0; mapToken != null && cnt < 30; ++cnt) {
+ System.out.println("testCleanupOfToken: in loop, cnt=" + cnt + " token=" + signedToken);
+ // -Dyahoo.zpeclient.updater.monitor_timeout_secs=1
+ // -Dyahoo.zpeclient.updater.cleanup_tokens_secs=1
+ try {
+ Thread.sleep(1000); // test has timeout set to 1 second
+ } catch (Exception exc) {
+ System.out.println("testCleanupOfToken: sleep was interrupted: in loop, cnt=" + cnt + " token=" + signedToken);
+ }
+
+ mapToken = roleMap.get(signedToken);
+ if (mapToken != null) {
+ Assert.assertEquals(signedToken.equals(mapToken.getSignedToken()), true);
+ }
+ }
+ // assert token is not in the map outside of the loop
+ Assert.assertNull(mapToken);
+ }
+
+ @Test
+ public void testCleanupOfTokenNotCleaned() {
+ // perform an allowed access check
+ String action = "fish";
+ String angResource = "angler:stockedpondBigBassLake";
+ List roles = new ArrayList();
+ roles.add("public");
+ roles.add("admin");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 10); // 10 sec expiry
+ String signedToken = rtoken.getSignedToken();
+ AccessCheckStatus status = AuthZpeClient.allowAccess(signedToken, angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+
+ Map roleMap = ZpeUpdPolLoader.getRoleTokenCacheMap();
+ RoleToken mapToken = roleMap.get(signedToken);
+ Assert.assertEquals(signedToken.equals(mapToken.getSignedToken()), true);
+ // then in a loop, check for existence of the token in the token map
+ for (int cnt = 0; mapToken != null && cnt < 5; ++cnt) {
+ System.out.println("testCleanupOfToken: in loop, cnt=" + cnt + " token=" + signedToken);
+ // -Dyahoo.zpeclient.updater.monitor_timeout_secs=1
+ // -Dyahoo.zpeclient.updater.cleanup_tokens_secs=1
+ try {
+ Thread.sleep(1000); // test has timeout set to 1 second
+ } catch (Exception exc) {
+ System.out.println("testCleanupOfToken: sleep was interrupted: in loop, cnt=" + cnt + " token=" + signedToken);
+ }
+
+ mapToken = roleMap.get(signedToken);
+ Assert.assertNotNull(mapToken);
+ Assert.assertEquals(signedToken.equals(mapToken.getSignedToken()), true);
+ }
+ // assert token is not in the map outside of the loop
+ Assert.assertNotNull(mapToken);
+ Assert.assertEquals(signedToken.equals(mapToken.getSignedToken()), true);
+ }
+
+ @Test
+ public void testWildcardManagePondsKernDenied() {
+ String action = "manage";
+ String angResource = "angler:pondsVenturaCounty";
+ List roles = new ArrayList();
+ roles.add("managerkernco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Kern county manager not allowed to manage Ventura county ponds
+ Assert.assertEquals(status, AccessCheckStatus.DENY);
+ }
+
+ @Test
+ public void testWildcardManagePondsKernAllowed() {
+ String action = "manage";
+ String angResource = "angler:pondsKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerkernco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Ventura county manager is allowed to manage Kern county ponds
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "manager*");
+ }
+
+ @Test
+ public void testWildcardManageRiversKernAllowed() {
+ String action = "manage";
+ String angResource = "angler:RiversKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerkernco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Ventura county manager is allowed to manage Kern county ponds
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "manager*");
+ }
+
+ @Test
+ public void testWildcardManagePondsVenturaAllowed() {
+ String action = "manage";
+ String angResource = "angler:pondsKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerventuraco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Ventura county manager is allowed to manage Kern county ponds
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "manager*");
+ }
+
+ @Test
+ public void testWildcardManageRiversVenturaAllowed() {
+ String action = "manage";
+ String angResource = "angler:RiversVenturaCounty";
+ List roles = new ArrayList();
+ roles.add("managerventuraco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Ventura county manager is allowed to manage Kern county ponds
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testWildcardManageRiversVenturaDenied() {
+ String action = "manage";
+ String angResource = "angler:RiversKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerventuraco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+ StringBuilder roleName = new StringBuilder(256);
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken, angResource, action, roleName);
+ // Ventura county manager is allowed to manage Kern county ponds
+ Assert.assertEquals(status, AccessCheckStatus.DENY);
+ Assert.assertEquals(roleName.toString(), "managerventura*");
+ }
+
+ @Test
+ public void testWildcardManagePondsAllowedTokenString() {
+ String action = "manage";
+ String angResource = "angler:pondsKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerkernco");
+ roles.add("managerventuraco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ }
+
+ @Test
+ public void testWildcardManageRiversDeniedTokenString() {
+ String action = "manage";
+ String angResource = "angler:riversKernCounty";
+ List roles = new ArrayList();
+ roles.add("managerkernco");
+ roles.add("managerventuraco");
+ RoleToken rtoken = createRoleToken("angler", roles, "0", 1000); // 1000 sec expiry
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rtoken.getSignedToken(), angResource, action);
+ Assert.assertEquals(status, AccessCheckStatus.DENY);
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerAdmin.getSignedToken()); // add an ALLOW role
+ tokenList.add(rtoken.getSignedToken()); // add the DENY role token in
+ StringBuilder roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY); // DENY over-rides ALLOW
+ Assert.assertEquals(roleName.toString(), "managerventura*");
+
+ tokenList = new ArrayList();
+ tokenList.add(rToken0CoreTechPublic.getSignedToken()); // add a DENY_DOMAIN_MISMATCH
+ tokenList.add(rToken0AnglerAdmin.getSignedToken()); // add an ALLOW role
+ tokenList.add(rtoken.getSignedToken()); // add the DENY role token in
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY); // DENY over-rides everything else
+ Assert.assertEquals(roleName.toString(), "managerventura*");
+
+ // order wont matter
+ tokenList = new ArrayList();
+ tokenList.add(rtoken.getSignedToken()); // add the DENY role token in
+ tokenList.add(rToken0CoreTechPublic.getSignedToken()); // add a DENY_DOMAIN_MISMATCH
+ tokenList.add(rToken0AnglerAdmin.getSignedToken()); // add an ALLOW role
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, angResource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY); // DENY over-rides everything else
+ Assert.assertEquals(roleName.toString(), "managerventura*");
+ }
+
+ @Test
+ public void testAllowAccessMatchAll() {
+
+ String action = "all";
+ String resource = "angler:stuff";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchall");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchall");
+ }
+
+ @Test
+ public void testAllowAccessMatchStartsWithAllowed() {
+
+ String action = "startswith";
+ String resource = "angler:startswithgreat";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchstarts");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchstarts");
+ }
+
+ @Test
+ public void testAllowAccessMatchEqualAllowed() {
+
+ String action = "compare";
+ String resource = "angler:compare";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchcompare");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchcompare");
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexAllowed() {
+
+ String action = "regex";
+ String resource = "angler:nhllosangeleskings";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchregex");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.ALLOW);
+ Assert.assertEquals(roleName.toString(), "matchregex");
+ }
+
+ @Test
+ public void testAllowAccessMatchStartsWithDenied() {
+
+ String action = "startswith";
+ String resource = "angler:startswitgreat"; /* missing h from startswith */
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ Assert.assertEquals(roleName.toString(), "");
+
+ // multi tokens test
+ List tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ // last token was for domain coretech
+ Assert.assertEquals(status, AccessCheckStatus.DENY_DOMAIN_MISMATCH);
+ Assert.assertEquals(roleName.toString(), "");
+
+ tokenList = new ArrayList();
+ tokenList.add(rToken0AnglerExpirePublic.getSignedToken());
+ tokenList.add(rToken0AnglerPublic.getSignedToken());
+ tokenList.add(rToken0CoreTechPublic.getSignedToken());
+ tokenList.add(rToken0AnglerRegex.getSignedToken());
+ roleName = new StringBuilder();
+ status = AuthZpeClient.allowAccess(tokenList, resource, action, roleName);
+ // last token was for domain angler with regex token
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ Assert.assertEquals(roleName.toString(), "");
+
+ }
+
+ @Test
+ public void testAllowAccessMatchEqualDenied() {
+
+ String action = "compare";
+ String resource = "angler:compares"; /* extra s after compare */
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexDenied() {
+
+ String action = "regex";
+ String resource = "angler:nhllosangeleskingsA"; /* extra A after kings */
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexInvalidOr1() {
+
+ String action = "full_regex";
+ String resource = "angler:coretech";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexInvalidOr2() {
+
+ String action = "full_regex";
+ String resource = "angler:corecommit";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexInvalidRange1() {
+
+ String action = "full_regex";
+ String resource = "angler:corea";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexInvalidRange2() {
+
+ String action = "full_regex";
+ String resource = "angler:coreb";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testAllowAccessMatchRegexInvalidRange3() {
+
+ String action = "full_regex";
+ String resource = "angler:coref";
+ StringBuilder roleName = new StringBuilder();
+
+ AccessCheckStatus status = AuthZpeClient.allowAccess(rToken0AnglerRegex, resource, action, roleName);
+ Assert.assertEquals(status, AccessCheckStatus.DENY_NO_MATCH);
+ }
+
+ @Test
+ public void testPatternFromGlob() {
+ assertEquals("^abc$", AuthZpeClient.patternFromGlob("abc"));
+ assertEquals("^abc.*$", AuthZpeClient.patternFromGlob("abc*"));
+ assertEquals("^abc.$", AuthZpeClient.patternFromGlob("abc?"));
+ assertEquals("^.*abc.$", AuthZpeClient.patternFromGlob("*abc?"));
+ assertEquals("^abc\\.abc:.*$", AuthZpeClient.patternFromGlob("abc.abc:*"));
+ assertEquals("^ab\\[a-c]c$", AuthZpeClient.patternFromGlob("ab[a-c]c"));
+ assertEquals("^ab.*\\.\\(\\)\\^\\$c$", AuthZpeClient.patternFromGlob("ab*.()^$c"));
+ assertEquals("^abc\\\\test\\\\$", AuthZpeClient.patternFromGlob("abc\\test\\"));
+ assertEquals("^ab\\{\\|c\\+$", AuthZpeClient.patternFromGlob("ab{|c+"));
+ assertEquals("^\\^\\$\\[\\(\\)\\\\\\+\\{\\..*.\\|$", AuthZpeClient.patternFromGlob("^$[()\\+{.*?|"));
+ }
+
+ @Test
+ public void testValidateRoleToken() {
+
+ List roles = new ArrayList();
+ roles.add("public_role");
+ RoleToken rToken = createRoleToken("coretech", roles, "0");
+
+ RoleToken validatedToken = AuthZpeClient.validateRoleToken(rToken.getSignedToken());
+ assertNotNull(validatedToken);
+ assertEquals(validatedToken.getRoles().size(), 1);
+ assertEquals(validatedToken.getRoles().get(0), "public_role");
+ assertEquals(validatedToken.getDomain(), "coretech");
+
+ // asking for the same token should return the data from our cache
+
+ validatedToken = AuthZpeClient.validateRoleToken(rToken.getSignedToken());
+ assertNotNull(validatedToken);
+ assertEquals(validatedToken.getRoles().size(), 1);
+ assertEquals(validatedToken.getRoles().get(0), "public_role");
+ assertEquals(validatedToken.getDomain(), "coretech");
+ }
+
+ @Test
+ public void testValidateRoleTokenInvalidKeyVersion() {
+
+ List roles = new ArrayList();
+ roles.add("public_role");
+ RoleToken rToken = createRoleToken("coretech", roles, "0");
+
+ String tamperedToken = rToken.getSignedToken().replace(";k=0;", ";k=zone1.invalid");
+ RoleToken validatedToken = AuthZpeClient.validateRoleToken(tamperedToken);
+ assertNull(validatedToken);
+ }
+
+ @Test
+ public void testValidateRoleTokenInvalidSignature() {
+
+ List roles = new ArrayList();
+ roles.add("public_role");
+ RoleToken rToken = createRoleToken("coretech", roles, "0");
+
+ String tamperedToken = rToken.getSignedToken().replace(";s=", ";s=siginvalid");
+ RoleToken validatedToken = AuthZpeClient.validateRoleToken(tamperedToken);
+ assertNull(validatedToken);
+ }
+
+ @Test
+ public void testAccessCheckStatus() {
+ for (AccessCheckStatus stat : AccessCheckStatus.values()) {
+ assertNotNull(stat.toString());
+ System.out.println("Debug for AccessCheckStatus()");
+ System.out.println(stat.toString());
+ }
+ }
+
+ @Test
+ public void testInit() {
+ AuthZpeClient.init();
+ }
+
+ @Test
+ public void testgetZtsPublicKeyNull() throws Exception {
+ PublicKey key = AuthZpeClient.getZtsPublicKey("notexist");
+ assertNull(key);
+ }
+}
+
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMatch.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMatch.java
new file mode 100644
index 00000000000..21413888a42
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMatch.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import org.testng.annotations.Test;
+
+import com.yahoo.athenz.zpe.ZpeUpdPolLoader;
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchAll;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchEqual;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchRegex;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchStartsWith;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+public class TestZpeMatch {
+
+ @Test
+ public void testGetMatchAll() {
+
+ try (ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null)) {
+
+ ZpeMatch matchObject = loader.getMatchObject("*");
+ assertTrue(matchObject instanceof ZpeMatchAll);
+
+ assertTrue(matchObject.matches("abc"));
+ assertTrue(matchObject.matches("false"));
+ assertTrue(matchObject.matches("whatever"));
+ }
+ }
+
+ @Test
+ public void testGetMatchRegex() {
+
+ try (ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null)) {
+
+ ZpeMatch matchObject = loader.getMatchObject("coretech?test*");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ assertTrue(matchObject.matches("coretechAtest"));
+ assertTrue(matchObject.matches("coretechbtestgreat"));
+
+ // failures
+
+ assertFalse(matchObject.matches("whatever")); // random data
+ assertFalse(matchObject.matches("coretechtestgreat")); // missing ?
+ }
+ }
+
+ @Test
+ public void testGetMatchEqual() {
+
+ try (ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null)) {
+
+ ZpeMatch matchObject = loader.getMatchObject("coretech");
+ assertTrue(matchObject instanceof ZpeMatchEqual);
+
+ assertTrue(matchObject.matches("coretech"));
+
+ // failures
+
+ assertFalse(matchObject.matches("whatever")); // random data
+ assertFalse(matchObject.matches("coretechA")); // extra A
+ assertFalse(matchObject.matches("coretec")); // missing h
+ }
+ }
+
+ @Test
+ public void testGetMatchStartsWith() {
+
+ try (ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null)) {
+
+ ZpeMatch matchObject = loader.getMatchObject("coretech*");
+ assertTrue(matchObject instanceof ZpeMatchStartsWith);
+
+ assertTrue(matchObject.matches("coretech"));
+ assertTrue(matchObject.matches("coretechtest"));
+ assertTrue(matchObject.matches("coretechtesttest"));
+
+ // failures
+
+ assertFalse(matchObject.matches("whatever")); // random data
+ assertFalse(matchObject.matches("coretec")); // missing h
+ assertFalse(matchObject.matches("coretecA")); // missing h + extra A
+ }
+ }
+}
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMetric.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMetric.java
new file mode 100644
index 00000000000..a1f861886eb
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeMetric.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.io.File;
+import org.testng.annotations.Test;
+
+import com.yahoo.athenz.zpe.AuthZpeClient;
+import com.yahoo.athenz.zpe.ZpeConsts;
+import com.yahoo.athenz.zpe.ZpeMetric;
+import com.yahoo.athenz.zts.DomainMetric;
+import com.yahoo.athenz.zts.DomainMetrics;
+import com.yahoo.rdl.JSON;
+
+public class TestZpeMetric extends TestCase {
+
+ @Test
+ public void testZpeMetric() throws IOException {
+
+ // setting the system property to write in file every 5 secs
+ System.setProperty(ZpeConsts.ZPE_PROP_METRIC_WRITE_INTERVAL, "5000");
+
+ final String metricDirPath = "/tmp/zpe-metrics";
+ File metricsDir = new File(metricDirPath);
+ metricsDir.mkdirs();
+ System.setProperty(ZpeConsts.ZPE_PROP_METRIC_FILE_PATH, metricDirPath);
+
+ final String TEST_DOMAIN = "test";
+ ZpeMetric.statsEnabled = true;
+ ZpeMetric test = new ZpeMetric();
+
+ // cleaning the directory
+ File dir = new File(test.getFilePath());
+ System.out.println(test.getFilePath());
+ if (dir.exists()) {
+ for (File file: dir.listFiles()) {
+ if (!file.isDirectory()) {
+ file.delete();
+ }
+ }
+ } else {
+ dir.mkdirs();
+ }
+
+ // incrementing metrics for testing
+ Integer index = com.yahoo.athenz.zts.DomainMetricType.valueOf(ZpeConsts.ZPE_METRIC_NAME).ordinal();
+ System.out.println("Metric is now " + test.counter.get(index));
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ System.out.println("Metric is now " + test.counter.get(index));
+
+ System.out.println("testZpeMetric Sleep Millisecs= 4000");
+ try {
+ Thread.sleep(4000);
+ } catch (InterruptedException e) {
+ }
+ System.out.println("testZpeMetric: Nap over");
+
+ System.out.println("Metric is now " + test.counter.get(index));
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, TEST_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, TEST_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ test.increment(ZpeConsts.ZPE_METRIC_NAME, AuthZpeClient.DEFAULT_DOMAIN);
+ System.out.println("Metric is now " + test.counter.get(index));
+
+ System.out.println("testZpeMetric Sleep Millisecs= 2000");
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ }
+ System.out.println("testZpeMetric: Nap over");
+
+ // Reading from the json file generated
+ File[] filenames = dir.listFiles();
+
+ String filepath = test.getFilePath() + filenames[0].getName();
+ Path path = Paths.get(filepath);
+ DomainMetrics domainMetrics = JSON.fromBytes(Files.readAllBytes(path), DomainMetrics.class);
+ // verifying the value of the metric
+ List metricList = domainMetrics.getMetricList();
+ boolean metricVerified = false;
+ for (DomainMetric metric : metricList) {
+ if (metric.getMetricType().toString().equals(ZpeConsts.ZPE_METRIC_NAME)) {
+ assertEquals(10, metric.getMetricVal());
+ metricVerified = true;
+ }
+ }
+ assertTrue(metricVerified);
+
+ filepath = test.getFilePath() + filenames[1].getName();
+ path = Paths.get(filepath);
+ domainMetrics = JSON.fromBytes(Files.readAllBytes(path), DomainMetrics.class);
+ // verifying the value of the metric
+ metricList = domainMetrics.getMetricList();
+ metricVerified = false;
+ for (DomainMetric metric : metricList) {
+ if (metric.getMetricType().toString().equals(ZpeConsts.ZPE_METRIC_NAME)) {
+ assertEquals(2, metric.getMetricVal());
+ metricVerified = true;
+ }
+ }
+ assertTrue(metricVerified);
+
+ // unsetting the system property
+ System.clearProperty(ZpeConsts.ZPE_PROP_METRIC_WRITE_INTERVAL);
+ }
+
+}
\ No newline at end of file
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeUpdPolLoader.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeUpdPolLoader.java
new file mode 100644
index 00000000000..5da685cc777
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeUpdPolLoader.java
@@ -0,0 +1,165 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import org.mockito.Mockito;
+import org.testng.annotations.Test;
+
+import com.yahoo.athenz.zpe.match.ZpeMatch;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchAll;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchEqual;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchRegex;
+import com.yahoo.athenz.zpe.match.impl.ZpeMatchStartsWith;
+
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+public class TestZpeUpdPolLoader {
+
+ static String TEST_POL_DIR = "./src/test/resources/upd_pol_dir/";
+ static String TEST_POL_FILE = "angler.pol";
+ static String TEST_POL_GOOD_FILE = "./src/test/resources/pol_dir/angler.pol";
+
+ static String TEST_POL_FILE_EMPTY = "empty.pol";
+ static String TEST_POL_GOOD_FILE_EMPTY = "./src/test/resources/pol_dir/empty.pol";
+
+ @Test
+ public void testGetMatchObject() {
+
+ try (ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null)) {
+
+ ZpeMatch matchObject = loader.getMatchObject("*");
+ assertTrue(matchObject instanceof ZpeMatchAll);
+
+ matchObject = loader.getMatchObject("**");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ matchObject = loader.getMatchObject("?*");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ matchObject = loader.getMatchObject("?");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ matchObject = loader.getMatchObject("test?again*");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ matchObject = loader.getMatchObject("*test");
+ assertTrue(matchObject instanceof ZpeMatchRegex);
+
+ matchObject = loader.getMatchObject("test");
+ assertTrue(matchObject instanceof ZpeMatchEqual);
+
+ matchObject = loader.getMatchObject("(test|again)");
+ assertTrue(matchObject instanceof ZpeMatchEqual);
+
+ matchObject = loader.getMatchObject("test*");
+ assertTrue(matchObject instanceof ZpeMatchStartsWith);
+ }
+ }
+
+ @Test
+ public void testLoadDb() throws Exception {
+
+ System.out.println("TestZpeUpdPolLoader: testLoadDb: dir=" + TEST_POL_DIR);
+
+ java.nio.file.Path dirPath = java.nio.file.Paths.get(TEST_POL_DIR);
+ try {
+ java.nio.file.Files.createDirectory(dirPath);
+ } catch (java.nio.file.FileAlreadyExistsException exc) {
+ }
+
+ ZpeUpdPolLoader loader = new ZpeUpdPolLoader(TEST_POL_DIR);
+
+ java.nio.file.Path badFile = java.nio.file.Paths.get(TEST_POL_DIR, TEST_POL_FILE);
+ java.nio.file.Files.deleteIfExists(badFile);
+ java.io.File polFile = new java.io.File(TEST_POL_DIR, TEST_POL_FILE);
+ polFile.createNewFile();
+ java.io.File [] files = { polFile };
+ loader.loadDb(files);
+
+ long lastModMilliSeconds = polFile.lastModified();
+ java.util.Map fsmap = loader.getFileStatusMap();
+ ZpeUpdPolLoader.ZpeFileStatus fstat = fsmap.get(polFile.getName());
+ assertTrue(fstat.validPolFile == false);
+
+ // move good policy file over the bad one
+ java.nio.file.Path goodFile = java.nio.file.Paths.get(TEST_POL_GOOD_FILE);
+ java.nio.file.Files.copy(goodFile, badFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
+
+ loader.loadDb(files);
+ long lastModMilliSeconds2 = polFile.lastModified();
+ fsmap = loader.getFileStatusMap();
+ fstat = fsmap.get(polFile.getName());
+ assertTrue(fstat.validPolFile == true);
+ loader.close();
+ System.out.println("TestZpeUpdPolLoader: testLoadDb: timestamp1=" + lastModMilliSeconds + " timestamp2=" + lastModMilliSeconds2);
+ }
+
+ @Test
+ public void testLoadDBNull() {
+ ZpeUpdPolLoader loader = new ZpeUpdPolLoader(TEST_POL_DIR);
+ loader.loadDb(null);
+
+ loader.close();
+ }
+
+ @Test
+ public void testLoadDBNotExist() throws Exception {
+ ZpeUpdPolLoader loader = new ZpeUpdPolLoader(TEST_POL_DIR);
+ File fileMock = Mockito.mock(File.class);
+ java.io.File [] files = { fileMock };
+
+ // delete file
+ Mockito.when(fileMock.exists()).thenReturn(false);
+
+ try {
+ loader.loadDb(files);
+ } catch(Exception ex) {
+ loader.close();
+ }
+
+ loader.close();
+ }
+
+ @Test(expectedExceptions = {java.lang.Exception.class})
+ public void testStartNullDir() throws Exception {
+ ZpeUpdPolLoader loader = new ZpeUpdPolLoader(null);
+ loader.start();
+ loader.close();
+ }
+
+ @Test
+ public void testLoadFileStatusNull() {
+ ZpeUpdPolLoader loader = new ZpeUpdPolLoader("./noexist");
+ ZpeUpdMonitor monitor = new ZpeUpdMonitor(loader);
+ File[] files = monitor.loadFileStatus();
+ assertTrue(files == null);
+ loader.close();
+ }
+
+ @Test
+ public void testUpdLoaderInvalid() {
+ ZpeUpdPolLoader loaderMock = Mockito.mock(ZpeUpdPolLoader.class);
+ Mockito.when(loaderMock.getDirName()).thenReturn(null);
+ ZpeUpdMonitor monitor = new ZpeUpdMonitor(loaderMock);
+
+ // TODO: validate log message
+ monitor.run();
+ monitor.cancel();
+ monitor.run();
+ }
+}
diff --git a/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeYcrKey.java b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeYcrKey.java
new file mode 100644
index 00000000000..ba570d43300
--- /dev/null
+++ b/clients/java/zpe/src/test/java/com/yahoo/athenz/zpe/TestZpeYcrKey.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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.zpe;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class TestZpeYcrKey {
+
+ @Test
+ public void testGetSetYcrKey() {
+
+ ZpeYcrKey ycrkey = new ZpeYcrKey();
+
+ ycrkey.setKeyName("key1");
+ ycrkey.setVersion((short) 0);
+
+ assertEquals(ycrkey.getKeyName(), "key1");
+ assertEquals(ycrkey.getVersion(), (short) 0);
+ }
+}
diff --git a/clients/java/zpe/src/test/resources/angler.pol b/clients/java/zpe/src/test/resources/angler.pol
new file mode 100644
index 00000000000..414453c316e
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/angler.pol
@@ -0,0 +1,162 @@
+{
+ "signedPolicyData": {
+ "expires": "2014-05-31T00:35:44.535Z",
+ "modified": "2014-05-24T00:34:45.922Z",
+ "policyData": {
+ "domain": "angler",
+ "policies": [
+ {
+ "assertions": [
+ {
+ "action": "*",
+ "role": "angler:role.admin",
+ "resource": "angler:*"
+ }
+ ],
+ "modified": "2014-05-24T00:34:45.922Z",
+ "name": "angler:policy.admin"
+ },
+ {
+ "assertions": [
+ {
+ "action": "read",
+ "role": "angler:role.public",
+ "resource": "angler:stuff"
+ },
+ {
+ "effect": "ALLOW",
+ "action": "write",
+ "role": "angler:role.public",
+ "resource": "angler:stuff"
+ },
+ {
+ "effect": "DENY",
+ "action": "throw",
+ "role": "angler:role.public",
+ "resource": "angler:stuff"
+ },
+ {
+ "effect": "DENY",
+ "action": "fish",
+ "role": "angler:role.public",
+ "resource": "angler:spawningpond*"
+ },
+ {
+ "effect": "ALLOW",
+ "action": "fish",
+ "role": "angler:role.public",
+ "resource": "angler:stockedpond*"
+ },
+ {
+ "role": "angler:role.pachinko",
+ "action": "access",
+ "effect": "ALLOW",
+ "resource": "angler:tables.blah"
+ }
+ ],
+ "modified": "2014-05-24T00:35:11.387Z",
+ "name": "angler:policy.public"
+ },
+ {
+ "assertions": [
+ {
+ "action": "direct",
+ "role": "angler:role.director",
+ "resource": "angler:ponds*"
+ },
+ {
+ "action": "oversee",
+ "role": "angler:role.foreman",
+ "resource": "angler:ponds*"
+ },
+ {
+ "action": "manage",
+ "role": "angler:role.manager*",
+ "resource": "angler:ponds*"
+ },
+ {
+ "effect": "DENY",
+ "action": "manage",
+ "role": "angler:role.managerkern*",
+ "resource": "angler:pondsventura*"
+ },
+ {
+ "action": "direct",
+ "role": "angler:role.director",
+ "resource": "angler:rivers*"
+ },
+ {
+ "action": "oversee",
+ "role": "angler:role.foreman",
+ "resource": "angler:rivers*"
+ },
+ {
+ "action": "manage",
+ "role": "angler:role.manager*",
+ "resource": "angler:rivers*"
+ },
+ {
+ "effect": "DENY",
+ "action": "manage",
+ "role": "angler:role.managerventura*",
+ "resource": "angler:riverskern*"
+ }
+ ],
+ "modified": "2014-05-24T00:34:45.922Z",
+ "name": "angler:policy.wildcardgamewardens"
+ },
+ {
+ "assertions": [
+ {
+ "action": "all",
+ "role": "angler:role.matchall",
+ "resource": "angler:*"
+ },
+ {
+ "action": "startswith",
+ "role": "angler:role.matchstarts",
+ "resource": "angler:startswith*"
+ },
+ {
+ "action": "compare",
+ "role": "angler:role.matchcompare",
+ "resource": "angler:compare"
+ },
+ {
+ "action": "regex",
+ "role": "angler:role.matchregex",
+ "resource": "angler:nhl*kings"
+ }
+ ],
+ "modified": "2014-05-24T00:35:11.387Z",
+ "name": "angler:policy.matchtypes"
+ },
+ {
+ "assertions": [
+ {
+ "action": "full_regex",
+ "role": "angler:role.full_regex",
+ "resource": "angler:?ore(tech|commit)"
+ },
+ {
+ "action": "full_regex",
+ "role": "angler:role.full_regex",
+ "resource": "angler:?ore[a-c]"
+ },
+ {
+ "action": "full_regex",
+ "role": "angler:role.full_regex",
+ "resource": "angler:?ore[def]"
+ }
+ ],
+ "modified": "2014-05-24T00:35:11.387Z",
+ "name": "angler:policy.full_regex"
+ }
+ ]
+ },
+ "zmsSignature": "eN5aZiqCof3HjHctjkYB2itNvI.90u.bq6zzLoXG8CJ8hSwG6IBMaIQ0yf.Q_SR5HTFi7Tmrc1quQuH17H0PJg--",
+ "zmsKeyId": "0"
+ },
+ "signature": "o6G6eXPifUvvE87ElgpquAaSQGr0L0v_6HkcXJ972.v62eaedhMkJO5fPLS0RbmhQfiy_GPZsZNPB_gkULI4eFSsqfWb4hTtKgo1uqS6QoPc2KZDeXrGc_ocAqpB4l1qsj4y_o9vj8ICtHgLqRxIvmdajSPmy4xo0p8Us7q0pZ2_td8xN3ZsjMZDES78_grhRexcwnI_3a25jAWg_BzUZh5ynGUh221wAZZ3FzqL7CijKzHv.V7iUqOaqb4yziCtxEuWIkcpyQ8U77BA8jCxvwxoIEBbGXE_BM0Hp8G7sfFFxV6WojoY4YwHfVIPCOlG5C0fcH5gf0NzsvlUb7oOew--",
+ "keyId": "0"
+}
diff --git a/clients/java/zpe/src/test/resources/athenz.conf b/clients/java/zpe/src/test/resources/athenz.conf
new file mode 100755
index 00000000000..3a1ec2da776
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/athenz.conf
@@ -0,0 +1,24 @@
+{
+ "zmsUrl": "https://dev.zms.athenzcompany.com:4443/",
+ "ztsUrl": "https://dev.zts.athenzcompany.com:4443/",
+ "ztsPublicKeys": [
+ {
+ "id": "0",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FERmQzSjJWOFdDUy9nTkUyR1BCY3R1T1J5awpqZ1FtTGZXclRRRkVGYld4TU1mVUdtUm8vSnFHQ0h1SjE0TWU5aXJjSU5CcTdvZkxFdXhrQ3dZc3dsNE8zd3BPCnRyQTFmekdTRFo4RGpmWUxDbThjWUovWml4WG1FbW1yVk01UGxVYVlRNkJ6U0FRdnFuZzdXSjJZYkIySEZmU2EKZEJqNUN6YXJvVGRVMXdPNEV3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ },
+ {
+ "id": "1",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FETGlLY1hjUDlrMWRJcGU4bm1OS3pBaWpGcApuY0VWbEFveS8xcHordE5ETjExcDQ0MTJEREhXejhFSUNiVkE0RE16Wm1ta09URFdlUDBQSWdnNTg0RlF1SGpsCmsyOWU4VjJXT3pqQWZybGlad0dKbm1mdlBhb3FOQkNhZDI3cWFubm1MOVU3cTcvSEdRWmpMeGdoaXhGa0FtczEKaHFlbnlkb2JSVkhheHV3cDB3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ],
+ "zmsPublicKeys": [
+ {
+ "id": "0",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ },
+ {
+ "id": "1",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ]
+}
diff --git a/clients/java/zpe/src/test/resources/athenz_no_0.conf b/clients/java/zpe/src/test/resources/athenz_no_0.conf
new file mode 100755
index 00000000000..19132fc2b7c
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/athenz_no_0.conf
@@ -0,0 +1,24 @@
+{
+ "zmsUrl": "https://dev.zms.athenzcompany.com:4443/",
+ "ztsUrl": "https://dev.zts.athenzcompany.com:4443/",
+ "ztsPublicKeys": [
+ {
+ "id": "unused",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDZVUvZ0pKODA0MmN6QVUwQk1ub3N6bS9BdgpabGFzVUY2U0FhOGVXQkhSVmFCOTJ3Ty9ZZHBTZ3BDalVnUXdGN3RzTCtSd3ZCVGVpOEJKRDhhTUE2MmFaNDhOCjZYWjc4ams2Sm53bHN4aWFsUXNkNXdDNkhWUUlTclVvSEM1UkxtdUFyRHlrSWo1dWVuVDhqcTA3Ky9sNWdMQnUKQkpMSlNrSlpJa3lzcVRqRmZRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ },
+ {
+ "id": "1",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FETGlLY1hjUDlrMWRJcGU4bm1OS3pBaWpGcApuY0VWbEFveS8xcHordE5ETjExcDQ0MTJEREhXejhFSUNiVkE0RE16Wm1ta09URFdlUDBQSWdnNTg0RlF1SGpsCmsyOWU4VjJXT3pqQWZybGlad0dKbm1mdlBhb3FOQkNhZDI3cWFubm1MOVU3cTcvSEdRWmpMeGdoaXhGa0FtczEKaHFlbnlkb2JSVkhheHV3cDB3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ],
+ "zmsPublicKeys": [
+ {
+ "id": "0",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ },
+ {
+ "id": "1",
+ "key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZ3d0RRWUpLb1pJaHZjTkFRRUJCUUFEU3dBd1NBSkJBTHpmU09UUUpmRW0xZW00TDNza3lOVlEvYngwTU9UcQphK1J3T0gzWmNNS3lvR3hPSm85QXllUmE2RlhNbXZKSkdZczVQMzRZc3pGcG5qMnVBYmkyNG5FQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo-"
+ }
+ ]
+}
diff --git a/clients/java/zpe/src/test/resources/empty.pol b/clients/java/zpe/src/test/resources/empty.pol
new file mode 100644
index 00000000000..fbf0105553a
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/empty.pol
@@ -0,0 +1,15 @@
+{
+ "signedPolicyData": {
+ "modified": "2015-01-13T19:13:18.601Z",
+ "policyData": {
+ "domain": "empty",
+ "policies": [
+ ]
+ },
+ "zmsSignature": "eN5aZiqCof3HjHctjkYB2itNvI.90u.bq6zzLoXG8CJ8hSwG6IBMaIQ0yf.Q_SR5HTFi7Tmrc1quQuH17H0PJg--",
+ "zmsKeyId": "0",
+ "expires": "2015-01-20T19:13:18.599Z"
+ },
+ "signature": "qJXtTXPI0aQcxUgerT9X4BM6HoKVM1pNClt86UViintmC5.IK9uYoFhtdMfDLq7Kzc8jdyT1iCqv_OmEyMHLCA--",
+ "keyId": "0"
+}
diff --git a/clients/java/zpe/src/test/resources/logback.xml b/clients/java/zpe/src/test/resources/logback.xml
new file mode 100644
index 00000000000..0343d82c9e9
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ System.out
+
+ %-4relative [%thread] %-5level %class - %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/zpe/src/test/resources/logback_perf.xml b/clients/java/zpe/src/test/resources/logback_perf.xml
new file mode 100644
index 00000000000..476b077502a
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/logback_perf.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ System.out
+
+ %-4relative [%thread] %-5level %class - %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/clients/java/zpe/src/test/resources/pol_dir/.keepme b/clients/java/zpe/src/test/resources/pol_dir/.keepme
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/clients/java/zpe/src/test/resources/sports.pol b/clients/java/zpe/src/test/resources/sports.pol
new file mode 100644
index 00000000000..3ee12813eab
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/sports.pol
@@ -0,0 +1,32 @@
+{
+ "signedPolicyData": {
+ "modified": "2015-01-13T19:13:18.601Z",
+ "policyData": {
+ "domain": "sports",
+ "policies": [
+ {
+ "name": "sports:policy.admin",
+ "assertions": [
+ {
+ "resource": "*",
+ "role": "sports:role.admin",
+ "action": "*",
+ "effect": "ALLOW"
+ },
+ {
+ "resource": "*",
+ "role": "sports:role.non-admin",
+ "action": "*",
+ "effect": "DENY"
+ }
+ ]
+ }
+ ]
+ },
+ "expires": "2015-01-20T19:13:18.599Z",
+ "zmsSignature": "eN5aZiqCof3HjHctjkYB2itNvI.90u.bq6zzLoXG8CJ8hSwG6IBMaIQ0yf.Q_SR5HTFi7Tmrc1quQuH17H0PJg--",
+ "zmsKeyId": "0"
+ },
+ "signature": "qJXtTXPI0aQcxUgerT9X4BM6HoKVM1pNClt86UViintmC5.IK9uYoFhtdMfDLq7Kzc8jdyT1iCqv_OmEyMHLCA--",
+ "keyId": "0"
+}
diff --git a/clients/java/zpe/src/test/resources/sys.auth.pol b/clients/java/zpe/src/test/resources/sys.auth.pol
new file mode 100644
index 00000000000..a9d1d898219
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/sys.auth.pol
@@ -0,0 +1,32 @@
+{
+ "signedPolicyData": {
+ "modified": "2015-01-13T19:13:37.745Z",
+ "policyData": {
+ "domain": "sys.auth",
+ "policies": [
+ {
+ "name": "sys.auth:policy.admin",
+ "assertions": [
+ {
+ "resource": "*",
+ "role": "sys.auth:role.admin",
+ "action": "*",
+ "effect": "ALLOW"
+ },
+ {
+ "resource": "*",
+ "role": "sys.auth:role.non-admin",
+ "action": "*",
+ "effect": "DENY"
+ }
+ ]
+ }
+ ]
+ },
+ "expires": "2015-01-20T19:13:37.744Z",
+ "zmsSignature": "eN5aZiqCof3HjHctjkYB2itNvI.90u.bq6zzLoXG8CJ8hSwG6IBMaIQ0yf.Q_SR5HTFi7Tmrc1quQuH17H0PJg--",
+ "zmsKeyId": "0"
+ },
+ "signature": "eN5aZiqCof3HjHctjkYB2itNvI.90u.bq6zzLoXG8CJ8hSwG6IBMaIQ0yf.Q_SR5HTFi7Tmrc1quQuH17H0PJg--",
+ "keyId": "0"
+}
diff --git a/clients/java/zpe/src/test/resources/zms_private_k0.pem b/clients/java/zpe/src/test/resources/zms_private_k0.pem
new file mode 100644
index 00000000000..356e1edf8bd
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zms_private_k0.pem
@@ -0,0 +1,9 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBALzfSOTQJfEm1em4L3skyNVQ/bx0MOTqa+RwOH3ZcMKyoGxOJo9A
+yeRa6FXMmvJJGYs5P34YszFpnj2uAbi24nECAwEAAQJARpQBv09w/j6O7TmgtJm4
+Ws5bIxMgOkrHaqPs2Epq8rX8FUyaYSHBL4yYhqWlno4j1TrLzWneni8kJCUNJydU
+AQIhAPXBXPQ3UzzNeQC5gbcweMMIQOYHyF7W/NAEILSKgy6hAiEAxL7hOjpdYGtj
+hjG1nVIs+HW6z5TnRig7JjTwqA8RMdECIQC4oPCIuRfb0jJaDQQa8FuJiqXXK3mp
+ZrLARJmdiYJMgQIgZxpAnWsIlAay2RgjvJXbyzim9TFrIXDjzlnf47JBqIECIBue
+3ht9BnawOQqGzFjD89dFQ6nZtbiAaqORj276/SzZ
+-----END RSA PRIVATE KEY-----
diff --git a/clients/java/zpe/src/test/resources/zms_public_k0.pem b/clients/java/zpe/src/test/resources/zms_public_k0.pem
new file mode 100644
index 00000000000..727c3c67f22
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zms_public_k0.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALzfSOTQJfEm1em4L3skyNVQ/bx0MOTq
+a+RwOH3ZcMKyoGxOJo9AyeRa6FXMmvJJGYs5P34YszFpnj2uAbi24nECAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_private_k0.pem b/clients/java/zpe/src/test/resources/zts_private_k0.pem
new file mode 100644
index 00000000000..0f4e4f68ebc
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_private_k0.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDFd3J2V8WCS/gNE2GPBctuORykjgQmLfWrTQFEFbWxMMfUGmRo
+/JqGCHuJ14Me9ircINBq7ofLEuxkCwYswl4O3wpOtrA1fzGSDZ8DjfYLCm8cYJ/Z
+ixXmEmmrVM5PlUaYQ6BzSAQvqng7WJ2YbB2HFfSadBj5CzaroTdU1wO4EwIDAQAB
+AoGAIH4nN5H5zhbyGjS2OPKbJuf+7pTv2dh2NFnXe3yXCTEdsKknHJ90TdnXejcc
+PFwFcXN02COn9KKIg23M9lCFaWLhv/DtxW/pHMNPUmV26j8+mgFX7JsWdPLlobB0
+yTUjbv7RMk4UY+iHS4wsy1VtlPJtGWV96qyQW1BV3UgLxwECQQDwTuFOnsqTO+RL
+Km9zXh0YnWWAADig53qTwtlJjY+siqccg2B111gF19DQJezoitrmgqDrfhbe9AeO
+bwqHkHanAkEA0lxnpUYP0clRjDvZf2ey7Q0geCBv2KMGPXNvhoqV5KLGjy4jjON9
+UY86NpuTJxCG9mxgZ2MLtFrDM8yGXzAMtQJAPnAAUnEnqUGye2U3N/6ICNE8ghmM
+nSIH00SZOGczoV0VNm9cLMIa+MmuU6bG+1S4s5PVQ9qrDprRK8zmK3r5mQJBAJto
+uwWmAg/pnD5vBNsUIGLy3LcCt76jifuiKZWLEvwLqYej/Y2bjzzPBKHNQ+SLWDn7
+jSk0SjRfDXFaOzddhzUCQEI+I+tvOB0Vz7XdP9qr2hcSY1aL2YMCEA0sarZgPy81
+yWVgJcMwDR3MWGhz0AR0ao4WrKmg9JjtSUxvNbV82IU=
+-----END RSA PRIVATE KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_private_k1.pem b/clients/java/zpe/src/test/resources/zts_private_k1.pem
new file mode 100644
index 00000000000..efbf892ebb6
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_private_k1.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXwIBAAKBgQDLiKcXcP9k1dIpe8nmNKzAijFpncEVlAoy/1pz+tNDN11p4412
+DDHWz8EICbVA4DMzZmmkOTDWeP0PIgg584FQuHjlk29e8V2WOzjAfrliZwGJnmfv
+PaoqNBCad27qannmL9U7q7/HGQZjLxghixFkAms1hqenydobRVHaxuwp0wIDAQAB
+AoGBAI4mpuzMUtNOMzYd6ukJKQ5gdhpZv50eg/ESP055hEuRw4BNGWO1KKnq99px
+TVI+RARGJso311AzuCp1jmFLHKjQwSeqBdO3a7dt3d6YUTkQg3bV+LuS0ruYstOb
+moyDQ/pLRaFvK31Gd6t91Js1ZMm9XWyUZQBw3M9qdA0NaJYBAkEA7s2bgY9i8Vgh
+n9qpDlv6+qgbZfEZK/maVJPH7mKWfT6AP0CBuHcLKv89506rYeyK+Vc2vAcQIkDu
+82mVl1QlEwJBANow2KwHxiTwGM6GRMY00FwD1wB4WU3mzMtiWtrwaEChlWq1c8m8
+DtnX4rGVGxizYhKisZ8EEy5b2b/6tRTOQEECQQDoZMsq4IFnYV8Hk+HliXnLqQFQ
+ybq3Yubf3Bk7UlIlfEeORpZ3D9Kce1yg15xNZccxM8CeZzk6PHrOAziC1m5lAkEA
+kTdlXcmmxLrPp9SRPWG1MyiTFgsDVOfBcbO6SHEs0ac5bNXrhF6Xe8FFbW+RozTw
+lvqVQQJTSc1z9WQE1R4YgQJBAK8PtvWSmMVUlwVa/np3vQCoeILI1ugjicCOLiq7
+b3Wj1aQoi3gXa746cxnG4Y8lzKdIm1ukCCdBc47/Y8ayIgY=
+-----END RSA PRIVATE KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_private_k17.pem b/clients/java/zpe/src/test/resources/zts_private_k17.pem
new file mode 100644
index 00000000000..9e8891ce042
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_private_k17.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQC2fHq0j2Rs4FK6XQ7EM485H4suikgJOgkXX0p9efUU8vQpHvwD
+iiJh1rmfBqAcxYjr1vXA5N0e0LV//qfxog6KPnDrbZ99FrkLYAtEL21riuyPrDhQ
+pDnG+fpkI6jjL0XPXIML8Tg3n+6vusbnKF9PeO9to0UU6s76z3Gof8FhOwIDAQAB
+AoGAFmSMAiAeaKXWQPwuVbEmABJ418ssL8WpW+7biy4t/tYZU/pzXlPTCEJ7IKKF
+f0JWHOqR2Yu7/o4J15z+Ks6CDgto1VwDTFuz7Cwwx/L4QFLAAzZNBl1JDV7XrMMU
+Vf1MSBiqIwLYm4sHSPmfW726PUqwF7oZOiGpbeFsWPgno/ECQQDwFAr4BwsGvAOD
+oNL1NFVl24p35OW2U54kIW14tn3lFo03QrJG/EYPezYwrYzKeIl6mPyK9gqwUQ+x
+m8ajzNIPAkEAwpapK6ia1yA96N0p3bXUiYU2J0ROx3ao7yc4qkZ2zzzGWWLeDvcs
+Fa1YyU761WcXVC2/BAhdF87aJ4Fio5d6FQJBAKc0jl8oKJnMIHZwb/yvMjr6qHnQ
+RdyyaBWp4mCMWSpQhpHSNfASi4kEuz0z4jaxtK5aFqmBqvgZvOBqKfKzGCkCQEvK
+Tr3Yf+bGghaO/d2DEvM1VXBZ5K1ABHCRwDpiE6iILWFnZsJBd4RB7lEKWByCeM2q
+u7mgYFIDmWjFtluthjkCQAz4rdNBmBnbte8dWpbEqxEiWfbnx1eLsiYnKVroNION
+fQyEagDRqyo/nI9EWeQnEv+hTEJPY9JHJymlHWK9qXU=
+-----END RSA PRIVATE KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_private_k99.pem b/clients/java/zpe/src/test/resources/zts_private_k99.pem
new file mode 100644
index 00000000000..1fe548c63db
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_private_k99.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC+xl5AphtG0NnPbheJl0/6hcKFN0NP0q61zzSW3IQ8W5Q1bEJl
+5IhjqK7+S5oG6MoHxqQf1MINL5hj8y0ej9tP06DGSBrHH3eclTbaEABJ4+y1fWG7
+DFoJLWaSJkcnTcchcKKajPwhzLGWef+Ukitr6OybnhiyMRjMerraAfwbeQIDAQAB
+AoGAewdCUT7N6GVXkcXVuA20rkMEpxR0fE3KDcWKjJ+5R5NniOxABaXTrzFhaO0o
+b7xATbN0tHJokkhXZl20gzkSnNI8gQAKQSaA2Est8n4BHsWTVMiKYjOxnQ1cjkf+
+jQIyUEdS2e8F/B0CPYyGKopT2tByu1aQ0+x+3TfzmoMDFuECQQDwSMATi8QC5zDi
+Tv2ZqXW5YfsfwRyFsQfOoQ8rmFZZrHRfoU1uJqO+LszTsDZTWJ0E4J+wlcLO8QPG
++52BA8iPAkEAy0Cl8Qmy6P5URQPiNGpUASWI6nMNgUIgPmRt+DsR4b40WW4IJ4Ig
+d6xZPHTtoKsjkXEj2UePTwvcuODmNa6PdwJBANgte7GaI0VBXrecvYiL74BT6K0O
+/mxBc3axbIaaTcXr499Nre4WEWc/j8Q8WwPtS4dh2An1Ewk/yVgyc+fo0X0CQQDF
+9Jfp841JeXLvqMGmVSyt1TXNSfMMQjAPNFcancVjvJFVzGGqwQUIKVbcF/HcOvIw
+VCYbF6QO07nMYlY0UGgvAkBnAqUUVUI59BOR3bAnG8kx75V77PZ7pA8uqoDq38Xp
+xAVmrm8u8hLsiE9iROhCofhHj/r40hcHiyzwu3B/DSO3
+-----END RSA PRIVATE KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_public_k0.pem b/clients/java/zpe/src/test/resources/zts_public_k0.pem
new file mode 100644
index 00000000000..58b8bb295fd
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_public_k0.pem
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFd3J2V8WCS/gNE2GPBctuORyk
+jgQmLfWrTQFEFbWxMMfUGmRo/JqGCHuJ14Me9ircINBq7ofLEuxkCwYswl4O3wpO
+trA1fzGSDZ8DjfYLCm8cYJ/ZixXmEmmrVM5PlUaYQ6BzSAQvqng7WJ2YbB2HFfSa
+dBj5CzaroTdU1wO4EwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_public_k1.pem b/clients/java/zpe/src/test/resources/zts_public_k1.pem
new file mode 100644
index 00000000000..5c229adc4c1
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_public_k1.pem
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLiKcXcP9k1dIpe8nmNKzAijFp
+ncEVlAoy/1pz+tNDN11p4412DDHWz8EICbVA4DMzZmmkOTDWeP0PIgg584FQuHjl
+k29e8V2WOzjAfrliZwGJnmfvPaoqNBCad27qannmL9U7q7/HGQZjLxghixFkAms1
+hqenydobRVHaxuwp0wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_public_k17.pem b/clients/java/zpe/src/test/resources/zts_public_k17.pem
new file mode 100644
index 00000000000..fd57e88f91b
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_public_k17.pem
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2fHq0j2Rs4FK6XQ7EM485H4su
+ikgJOgkXX0p9efUU8vQpHvwDiiJh1rmfBqAcxYjr1vXA5N0e0LV//qfxog6KPnDr
+bZ99FrkLYAtEL21riuyPrDhQpDnG+fpkI6jjL0XPXIML8Tg3n+6vusbnKF9PeO9t
+o0UU6s76z3Gof8FhOwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/clients/java/zpe/src/test/resources/zts_public_k99.pem b/clients/java/zpe/src/test/resources/zts_public_k99.pem
new file mode 100644
index 00000000000..2e1ec2d6823
--- /dev/null
+++ b/clients/java/zpe/src/test/resources/zts_public_k99.pem
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+xl5AphtG0NnPbheJl0/6hcKF
+N0NP0q61zzSW3IQ8W5Q1bEJl5IhjqK7+S5oG6MoHxqQf1MINL5hj8y0ej9tP06DG
+SBrHH3eclTbaEABJ4+y1fWG7DFoJLWaSJkcnTcchcKKajPwhzLGWef+Ukitr6Oyb
+nhiyMRjMerraAfwbeQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/clients/java/zts/README.md b/clients/java/zts/README.md
new file mode 100644
index 00000000000..659ec0ef52f
--- /dev/null
+++ b/clients/java/zts/README.md
@@ -0,0 +1,27 @@
+zts-java-client
+===============
+
+A Java client library to access ZTS. This client library is generated
+from the RDL, and includes zts-core and all other dependencies.
+
+--- Connection Timeouts ---
+
+Default read and connect timeout values for ZTS Client connections
+are 30000ms (30sec). The application can change these values by using
+the following system properties:
+
+ * athenz.zts.client.read_timeout
+ * athenz.zts.client.connect_timeout
+
+The values specified for timeouts must be in milliseconds.
+
+--- Prefetch Settings ---
+
+ * athenz.zts.client.prefetch_auto_enable : true or false, default is false
+
+## License
+
+Copyright 2016 Yahoo Inc.
+
+Licensed under the Apache License, Version 2.0: [http://www.apache.org/licenses/LICENSE-2.0]()
+
diff --git a/clients/java/zts/pom.xml b/clients/java/zts/pom.xml
new file mode 100644
index 00000000000..22f2003e33e
--- /dev/null
+++ b/clients/java/zts/pom.xml
@@ -0,0 +1,235 @@
+
+
+
+ 4.0.0
+
+
+ com.yahoo.athenz
+ athenz
+ 1.0-SNAPSHOT
+ ../../../pom.xml
+
+
+ zts_java_client
+ jar
+ zts-java-client
+ ZTS Java Client Library
+
+
+
+ ${project.groupId}
+ zts_core
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ sia_java_client
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ client_common
+ ${project.parent.version}
+
+
+ ${project.groupId}
+ auth_core
+ ${project.parent.version}
+
+
+ org.glassfish.jersey.media
+ jersey-media-json-jackson
+ ${jersey.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.1.1
+
+
+
+ exec
+
+ generate-sources
+
+
+
+ bash
+
+ scripts/make_stubs.sh
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+
+ prepare-package
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+ org.glassfish.hk2
+ org.glassfish.hk2.external
+ org.glassfish.jersey
+ org.glassfish.jersey.ext
+ org.glassfish.jersey.core
+ org.glassfish.jersey.media
+ org.glassfish.jersey.bundles.repackaged
+ com.fasterxml.jackson.core
+ com.fasterxml.jackson.jaxrs
+ com.fasterxml.jackson.module
+ javax.ws.rs
+ javax.annotation
+ javax.inject
+ jersey.repackaged.com.google.common
+ org.aopalliance
+ com.yahoo.athenz:sia_java_client
+ com.kohlschutter.junixsocket
+
+
+
+
+ javax.inject
+ athenz.shade.zts.javax.inject
+
+
+ org.aopalliance
+ athenz.shade.zts.org.aopalliance
+
+
+ jersey.repackaged.com.google.common
+ athenz.shade.zts.jersey.repackaged.com.google.common
+
+
+ javax.ws.rs
+ athenz.shade.zts.javax.ws.rs
+
+
+ javax.annotation
+ athenz.shade.zts.javax.annotation
+
+
+ org.glassfish.jersey
+ athenz.shade.zts.org.glassfish.jersey
+
+
+ org.glassfish.hk2
+ athenz.shade.zts.org.glassfish.hk2
+
+
+ org.glassfish.hk2.external
+ athenz.shade.zts.org.glassfish.hk2.external
+
+
+ org.jvnet.hk2
+ athenz.shade.zts.org.jvnet.hk2
+
+
+ org.jvnet.tiger_types
+ athenz.shade.zts.org.jvnet.tiger_types
+
+
+ com.fasterxml.jackson
+ athenz.shade.zts.com.fasterxml.jackson
+
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+
+
+ coverage
+
+
+
+
+
+ com.atlassian.maven.plugins
+ maven-clover2-plugin
+ 4.0.4
+
+ 1.8
+
+
+ **/ZTSRDLGeneratedClient.java
+ **/*Mock.java
+
+ ${HOME}/license/clover.license
+
+
+
+
+
+
+
diff --git a/clients/java/zts/scripts/make_stubs.sh b/clients/java/zts/scripts/make_stubs.sh
new file mode 100755
index 00000000000..e046ac7f6c6
--- /dev/null
+++ b/clients/java/zts/scripts/make_stubs.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# If the zts_core dependency has been updated, then this script should be run
+# manually to pick up the latest rdl to generate the appropriate client library
+
+# Note this script is dependent on the rdl utility.
+# go get github.com/ardielle/ardielle-tools/...
+
+command -v rdl >/dev/null 2>&1 || {
+ echo >&2 "------------------------------------------------------------------------";
+ echo >&2 "SOURCE WARNING";
+ echo >&2 "------------------------------------------------------------------------";
+ echo >&2 "Please install rdl utility: go get github.com/ardielle/ardielle-tools/...";
+ echo >&2 "Skipping source generation...";
+ exit 0;
+}
+
+RDL_FILE=../../../core/zts/src/main/rdl/ZTS.rdl
+
+echo "Generate the client library..."
+rdl -s generate -o src/main/java -x clientclass=ZTSRDLGenerated java-client $RDL_FILE
diff --git a/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceError.java b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceError.java
new file mode 100644
index 00000000000..ddd96536251
--- /dev/null
+++ b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceError.java
@@ -0,0 +1,24 @@
+//
+// This file generated by rdl 1.4.8. Do not modify!
+//
+package com.yahoo.athenz.zts;
+
+public class ResourceError {
+
+ public int code;
+ public String message;
+
+ public ResourceError code(int code) {
+ this.code = code;
+ return this;
+ }
+ public ResourceError message(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public String toString() {
+ return "{code: " + code + ", message: \"" + message + "\"}";
+ }
+
+}
diff --git a/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceException.java b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceException.java
new file mode 100644
index 00000000000..4d094b4ee5c
--- /dev/null
+++ b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ResourceException.java
@@ -0,0 +1,79 @@
+//
+// This file generated by rdl 1.4.8. Do not modify!
+//
+package com.yahoo.athenz.zts;
+
+public class ResourceException extends RuntimeException {
+ public final static int OK = 200;
+ public final static int CREATED = 201;
+ public final static int ACCEPTED = 202;
+ public final static int NO_CONTENT = 204;
+ public final static int MOVED_PERMANENTLY = 301;
+ public final static int FOUND = 302;
+ public final static int SEE_OTHER = 303;
+ public final static int NOT_MODIFIED = 304;
+ public final static int TEMPORARY_REDIRECT = 307;
+ public final static int BAD_REQUEST = 400;
+ public final static int UNAUTHORIZED = 401;
+ public final static int FORBIDDEN = 403;
+ public final static int NOT_FOUND = 404;
+ public final static int CONFLICT = 409;
+ public final static int GONE = 410;
+ public final static int PRECONDITION_FAILED = 412;
+ public final static int UNSUPPORTED_MEDIA_TYPE = 415;
+ public final static int INTERNAL_SERVER_ERROR = 500;
+ public final static int NOT_IMPLEMENTED = 501;
+
+ public final static int SERVICE_UNAVAILABLE = 503;
+
+ public static String codeToString(int code) {
+ switch (code) {
+ case OK: return "OK";
+ case CREATED: return "Created";
+ case ACCEPTED: return "Accepted";
+ case NO_CONTENT: return "No Content";
+ case MOVED_PERMANENTLY: return "Moved Permanently";
+ case FOUND: return "Found";
+ case SEE_OTHER: return "See Other";
+ case NOT_MODIFIED: return "Not Modified";
+ case TEMPORARY_REDIRECT: return "Temporary Redirect";
+ case BAD_REQUEST: return "Bad Request";
+ case UNAUTHORIZED: return "Unauthorized";
+ case FORBIDDEN: return "Forbidden";
+ case NOT_FOUND: return "Not Found";
+ case CONFLICT: return "Conflict";
+ case GONE: return "Gone";
+ case PRECONDITION_FAILED: return "Precondition Failed";
+ case UNSUPPORTED_MEDIA_TYPE: return "Unsupported Media Type";
+ case INTERNAL_SERVER_ERROR: return "Internal Server Error";
+ case NOT_IMPLEMENTED: return "Not Implemented";
+ default: return "" + code;
+ }
+ }
+
+ int code;
+ Object data;
+
+ public ResourceException(int code) {
+ this(code, new ResourceError().code(code).message(codeToString(code)));
+ }
+
+ public ResourceException(int code, Object data) {
+ super("ResourceException (" + code + "): " + data);
+ this.code = code;
+ this.data = data;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public T getData(Class cl) {
+ return cl.cast(data);
+ }
+
+}
diff --git a/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ZTSClient.java b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ZTSClient.java
new file mode 100644
index 00000000000..6dbf44205ca
--- /dev/null
+++ b/clients/java/zts/src/main/java/com/yahoo/athenz/zts/ZTSClient.java
@@ -0,0 +1,1533 @@
+/**
+ * Copyright 2016 Yahoo Inc.
+ *
+ * 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 java.io.Closeable;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yahoo.athenz.auth.Principal;
+import com.yahoo.athenz.auth.impl.RoleAuthority;
+import com.yahoo.athenz.common.config.AthenzConfig;
+import com.yahoo.athenz.sia.SIA;
+import com.yahoo.athenz.sia.impl.SIAClient;
+import com.yahoo.rdl.JSON;
+
+public class ZTSClient implements Closeable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ZTSClient.class);
+
+ private String ztsUrl = null;
+ private String domain = null;
+ private String service = null;
+ protected ZTSRDLGeneratedClient ztsClient;
+ protected SIA siaClient = null;
+
+ // configurable fields
+ //
+ static private boolean cacheDisabled = false;
+ static private int tokenMinExpiryTime = 900;
+ static private int siaTokenMinExpiryTime = 300;
+ static private int siaTokenMaxExpiryTime = 3600;
+ static private long prefetchInterval = 60; // seconds
+ static private boolean prefetchAutoEnable = false;
+
+ @SuppressWarnings("unused")
+ static private boolean initialized = initConfigValues();
+
+ private boolean enablePrefetch = true;
+ Principal principal = null;
+
+ // system properties
+
+ public static final String ZTS_CLIENT_PROP_ATHENZ_CONF = "athenz.athenz_conf";
+
+ public static final String ZTS_CLIENT_PROP_TOKEN_MIN_EXPIRY_TIME = "athenz.zts.client.token_min_expiry_time";
+ public static final String ZTS_CLIENT_PROP_TOKEN_SIA_MIN_EXPIRY_TIME = "athenz.zts.client.sia_token_min_expiry_time";
+ public static final String ZTS_CLIENT_PROP_TOKEN_SIA_MAX_EXPIRY_TIME = "athenz.zts.client.sia_token_max_expiry_time";
+ public static final String ZTS_CLIENT_PROP_READ_TIMEOUT = "athenz.zts.client.read_timeout";
+ public static final String ZTS_CLIENT_PROP_CONNECT_TIMEOUT = "athenz.zts.client.connect_timeout";
+ public static final String ZTS_CLIENT_PROP_PREFETCH_SLEEP_INTERVAL = "athenz.zts.client.prefetch_sleep_interval";
+ public static final String ZTS_CLIENT_PROP_PREFETCH_AUTO_ENABLE = "athenz.zts.client.prefetch_auto_enable";
+ public static final String ZTS_CLIENT_PROP_X509CERT_DNS_NAME = "athenz.zts.client.x509cert_dns_name";
+ public static final String ZTS_CLIENT_PROP_DISABLE_CACHE = "athenz.zts.client.disable_cache";
+
+ public static final String ROLE_TOKEN_HEADER = System.getProperty(RoleAuthority.ATHENZ_PROP_ROLE_HEADER,
+ RoleAuthority.HTTP_HEADER);
+
+ final static ConcurrentHashMap ROLE_TOKEN_CACHE = new ConcurrentHashMap<>();
+ static ConcurrentHashMap awsCredCache = new ConcurrentHashMap<>();
+
+ private static final long FETCH_EPSILON = 60; // if cache expires in the next minute, fetch it.
+ private static final Queue PREFETCH_SCHEDULED_ITEMS = new ConcurrentLinkedQueue<>();
+ private static Timer FETCH_TIMER;
+ private static final Object TIMER_LOCK = new Object();
+ static AtomicLong FETCHER_LAST_RUN_AT = new AtomicLong(-1);
+
+ // allows outside implementations to get role tokens for special environments - ex. hadoop
+
+ private static final ServiceLoader ZTS_TOKEN_PROVIDERS = ServiceLoader.load(ZTSClientService.class);
+ private static final AtomicReference> SVC_LOADER_CACHE_KEYS = new AtomicReference<>();
+ static {
+ loadSvcProviderTokens();
+ }
+
+ static boolean initConfigValues() {
+
+ /* The minimum token expiry time by default is 15 minutes (900). By default the
+ * server gives out role tokens for 2 hours and with this setting we'll be able
+ * to cache tokens for 1hr45mins before requesting a new one from ZTS */
+
+ tokenMinExpiryTime = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_TOKEN_MIN_EXPIRY_TIME, "900"));
+ if (tokenMinExpiryTime < 0) {
+ tokenMinExpiryTime = 900;
+ }
+
+ /* We're going to cache Service Principal Tokens as long as possible so by default
+ * we're going to request tokens with a minimum timeout of 5 mins and max default
+ * value of 1hr. SIA Client Library provides the caching support so we'll just
+ * make the call for every request and let the SIA client library to return the
+ * cached token back to us */
+
+ siaTokenMinExpiryTime = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_TOKEN_SIA_MIN_EXPIRY_TIME, "300"));
+ if (siaTokenMinExpiryTime < 0) {
+ siaTokenMinExpiryTime = 300;
+ }
+ siaTokenMaxExpiryTime = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_TOKEN_SIA_MAX_EXPIRY_TIME, "3600"));
+ if (siaTokenMaxExpiryTime < 0) {
+ siaTokenMaxExpiryTime = 3600;
+ }
+
+ prefetchInterval = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_PREFETCH_SLEEP_INTERVAL, "60"));
+ if (prefetchInterval >= tokenMinExpiryTime) {
+ prefetchInterval = 60;
+ }
+
+ prefetchAutoEnable = Boolean.parseBoolean(System.getProperty(ZTS_CLIENT_PROP_PREFETCH_AUTO_ENABLE, "false"));
+ cacheDisabled = Boolean.parseBoolean(System.getProperty(ZTS_CLIENT_PROP_DISABLE_CACHE, "false"));
+ return true;
+ }
+
+ /**
+ * Constructs a new ZTSClient object with the given principal identity
+ * and media type set to application/json. The url for ZTS Server is
+ * automatically retrieved from the athenz_config package's configuration
+ * file (zts_url field).
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zts_java_client.read_timeout and
+ * yahoo.zts_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ * @param identity Principal identity for authenticating requests
+ */
+ public ZTSClient(Principal identity) {
+ initClient(null, identity, null, null);
+ enablePrefetch = false; // cant use this domain and service for prefetch
+ }
+
+ /**
+ * Constructs a new ZTSClient object with the given principal identity
+ * and ZTS Server URL and media type set to application/json.
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zts_java_client.read_timeout and
+ * yahoo.zts_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ * @param url ZTS Server's URL
+ * @param identity Principal identity for authenticating requests
+ */
+ public ZTSClient(String url, Principal identity) {
+ initClient(url, identity, null, null);
+ enablePrefetch = false; // cant use this domain and service for prefetch
+ }
+
+ /**
+ * Constructs a new ZTSClient object with the given service identity
+ * and media type set to application/json. The url for ZTS Server is
+ * automatically retrieved from the athenz_config package's configuration
+ * file (zts_url field). The service's principal token will be retrieved
+ * from the SIA Client.
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zts_java_client.read_timeout and
+ * yahoo.zts_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ */
+ public ZTSClient(String domainName, String serviceName) {
+ initClient(null, null, domainName, serviceName);
+ }
+
+ /**
+ * Constructs a new ZTSClient object with the given service identity
+ * and media type set to application/json. The service's principal
+ * token will be retrieved from the SIA Client.
+ * Default read and connect timeout values are 30000ms (30sec). The application can
+ * change these values by using the yahoo.zts_java_client.read_timeout and
+ * yahoo.zts_java_client.connect_timeout system properties. The values specified
+ * for timeouts must be in milliseconds.
+ * @param url ZTS Server's URL
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ */
+ public ZTSClient(String url, String domainName, String serviceName) {
+ initClient(url, null, domainName, serviceName);
+ }
+
+ /**
+ * Close the ZTSClient object and release any allocated resources.
+ */
+ @Override
+ public void close() {
+ ztsClient.close();
+ }
+
+ void removePrefetcher() {
+ PREFETCH_SCHEDULED_ITEMS.clear();
+ if (FETCH_TIMER != null) {
+ FETCH_TIMER.purge();
+ FETCH_TIMER.cancel();
+ FETCH_TIMER = null;
+ }
+ }
+
+ /**
+ * Returns the locally configured ZTS Server's URL value
+ * @return ZTS Server URL
+ */
+ public String getZTSUrl() {
+ return ztsUrl;
+ }
+
+ public void setZTSRDLGeneratedClient(ZTSRDLGeneratedClient client) {
+ this.ztsClient = client;
+ }
+
+ public void setSIAClient(SIA client) {
+ this.siaClient = client;
+ }
+
+ String lookupZTSUrl() {
+
+ String rootDir = System.getenv("ROOT");
+ if (rootDir == null) {
+ rootDir = "/home/athenz";
+ }
+
+ String confFileName = System.getProperty(ZTS_CLIENT_PROP_ATHENZ_CONF,
+ rootDir + "/conf/athenz/athenz.conf");
+ String url = null;
+ try {
+ Path path = Paths.get(confFileName);
+ AthenzConfig conf = JSON.fromBytes(Files.readAllBytes(path), AthenzConfig.class);
+ url = conf.getZtsUrl();
+ } catch (Exception ex) {
+ LOG.error("Unable to extract ZTS Url from {} exc: {}",
+ confFileName, ex.getMessage());
+ }
+
+ return url;
+ }
+
+ void initClient(String url, Principal identity, String domainName, String serviceName) {
+
+ if (url == null) {
+ ztsUrl = lookupZTSUrl();
+ } else {
+ ztsUrl = url;
+ }
+
+ /* verify if the url is ending with /zts/v1 and if it's
+ * not we'll automatically append it */
+
+ if (ztsUrl != null && !ztsUrl.isEmpty()) {
+ if (!ztsUrl.endsWith("/zts/v1")) {
+ if (ztsUrl.charAt(ztsUrl.length() - 1) != '/') {
+ ztsUrl += '/';
+ }
+ ztsUrl += "zts/v1";
+ }
+ }
+
+ /* determine our read and connect timeouts */
+
+ int readTimeout = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_READ_TIMEOUT, "30000"));
+ int connectTimeout = Integer.parseInt(System.getProperty(ZTS_CLIENT_PROP_CONNECT_TIMEOUT, "30000"));
+ String x509CertDNSName = System.getProperty(ZTS_CLIENT_PROP_X509CERT_DNS_NAME);
+ HostnameVerifier hostnameVerifier = null;
+ if (x509CertDNSName != null && !x509CertDNSName.isEmpty()) {
+ hostnameVerifier = new AWSHostNameVerifier(x509CertDNSName);
+ }
+
+ ztsClient = new ZTSRDLGeneratedClient(ztsUrl, hostnameVerifier)
+ .setProperty(ClientProperties.CONNECT_TIMEOUT, connectTimeout)
+ .setProperty(ClientProperties.READ_TIMEOUT, readTimeout);
+
+ principal = identity;
+ if (principal != null && principal.getAuthority() != null) {
+ domain = principal.getDomain();
+ service = principal.getName();
+ ztsClient.addCredentials(identity.getAuthority().getHeader(), identity.getCredentials());
+ } else if (domainName != null && serviceName != null) {
+ domain = domainName;
+ service = serviceName;
+ siaClient = new SIAClient();
+ }
+ }
+
+ void setPrefetchInterval(long interval) {
+ prefetchInterval = interval;
+ }
+
+ long getPrefetchInterval() {
+ return prefetchInterval;
+ }
+
+ /**
+ * Returns the header name that the client needs to use to pass
+ * the received RoleToken to the Athenz protected service.
+ * @return HTTP header name
+ */
+ public String getHeader() {
+ return ROLE_TOKEN_HEADER;
+ }
+
+ /**
+ * Clear the principal identity set for the client. Unless a new principal is set
+ * using the addCredentials method, the client can only be used to requests data
+ * from the ZTS Server that doesn't require any authentication.
+ * @param identity Principal identity for authenticating requests
+ * @return self ZTSClient object
+ */
+ public ZTSClient addCredentials(Principal identity) {
+ return addPrincipalCredentials(identity, true);
+ }
+
+ /**
+ * Clear the principal identity set for the client. Unless a new principal is set
+ * using the addCredentials method, the client can only be used to requests data
+ * from the ZTS Server that doesn't require any authentication.
+ * @return self ZTSClient object
+ */
+ public ZTSClient clearCredentials() {
+
+ if (principal != null) {
+ ztsClient.addCredentials(principal.getAuthority().getHeader(), null);
+ principal = null;
+ }
+ return this;
+ }
+
+ ZTSClient addPrincipalCredentials(Principal identity, boolean resetServiceDetails) {
+
+ if (identity != null && identity.getAuthority() != null) {
+ ztsClient.addCredentials(identity.getAuthority().getHeader(), identity.getCredentials());
+ }
+
+ // if the client is adding new principal identity then we have to
+ // clear out the SIA client object reference so that we don't try
+ // to get a service token since we already have one given to us
+
+ if (resetServiceDetails) {
+ siaClient = null;
+ }
+
+ principal = identity;
+ return this;
+ }
+
+ boolean sameCredentialsAsBefore(Principal svcPrincipal) {
+
+ // if we don't have a principal or no credentials
+ // then the principal has changed
+
+ if (principal == null) {
+ return false;
+ }
+
+ String creds = principal.getCredentials();
+ if (creds == null) {
+ return false;
+ }
+
+ return creds.equals(svcPrincipal.getCredentials());
+ }
+
+ boolean updateServicePrincipal() {
+
+ /* if we have a service principal then we need to keep updating
+ * our PrincipalToken otherwise it might expire. */
+
+ if (siaClient == null) {
+ return false;
+ }
+
+ try {
+ Principal svcPrincipal = siaClient.getServicePrincipal(domain, service,
+ siaTokenMinExpiryTime, siaTokenMaxExpiryTime, false);
+
+ // if the principal has the same credentials as before
+ // then we don't need to update anything
+
+ if (sameCredentialsAsBefore(svcPrincipal)) {
+ return false;
+ }
+
+ addPrincipalCredentials(svcPrincipal, false);
+
+ } catch (IOException ex) {
+
+ // we should log and throw an IllegalArgumentException otherwise the
+ // client doesn't know that something bad has happened - in this case
+ // illegal domain/service was passed to the constructor -
+ // and the ZTS Server just rejects the request with 401
+
+ String msg = "UpdateServicePrincipal: Unable to get PrincipalToken from SIA Server for "
+ + domain + "." + service + ": " + ex.getMessage();
+ LOG.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+
+ return true;
+ }
+
+ /**
+ * Retrieve list of services that have been configured to run on the specified host
+ * @param host name of the host
+ * @return list of service names on success. ZTSClientException will be thrown in case of failure
+ */
+ public HostServices getHostServices(String host) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getHostServices(host);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * For the specified requester(user/service) return the corresponding Role Token that
+ * includes the list of roles that the principal has access to in the specified domain.
+ * The client will automatically fulfill the request from the cache, if possible.
+ * The default minimum expiry time is 900 secs (15 mins).
+ * @param domainName name of the domain
+ * @return ZTS generated Role Token. ZTSClientException will be thrown in case of failure
+ */
+ public RoleToken getRoleToken(String domainName) {
+ return getRoleToken(domainName, null, null, null, false, null);
+ }
+
+ /**
+ * For the specified requester(user/service) return the corresponding Role Token that
+ * includes the list of roles that the principal has access to in the specified domain
+ * and filtered to include only those that end with the specified suffix.
+ * The client will automatically fulfill the request from the cache, if possible.
+ * The default minimum expiry time is 900 secs (15 mins).
+ * @param domainName name of the domain
+ * @param roleName only interested in roles with this name
+ * @return ZTS generated Role Token. ZTSClientException will be thrown in case of failure
+ */
+ public RoleToken getRoleToken(String domainName, String roleName) {
+ if (roleName == null || roleName.isEmpty()) {
+ throw new IllegalArgumentException("RoleName cannot be null or empty");
+ }
+ return getRoleToken(domainName, roleName, null, null, false, null);
+ }
+
+ /**
+ * For the specified requester(user/service) return the corresponding Role Token that
+ * includes the list of roles that the principal has access to in the specified domain
+ * @param domainName name of the domain
+ * @param roleName (optional) only interested in roles with this name
+ * @param minExpiryTime (optional) specifies that the returned RoleToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned RoleToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @param ignoreCache ignore the cache and retrieve the token from ZTS Server
+ * @return ZTS generated Role Token. ZTSClientException will be thrown in case of failure
+ */
+ public RoleToken getRoleToken(String domainName, String roleName, Integer minExpiryTime,
+ Integer maxExpiryTime, boolean ignoreCache) {
+ return getRoleToken(domainName, roleName, minExpiryTime, maxExpiryTime,
+ ignoreCache, null);
+ }
+
+ /**
+ * For the specified requester(user/service) return the corresponding Role Token that
+ * includes the list of roles that the principal has access to in the specified domain
+ * @param domainName name of the domain
+ * @param roleName (optional) only interested in roles with this name
+ * @param minExpiryTime (optional) specifies that the returned RoleToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned RoleToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @param ignoreCache ignore the cache and retrieve the token from ZTS Server
+ * @param proxyForPrincipal (optional) this request is proxy for this principal
+ * @return ZTS generated Role Token. ZTSClientException will be thrown in case of failure
+ */
+ public RoleToken getRoleToken(String domainName, String roleName, Integer minExpiryTime,
+ Integer maxExpiryTime, boolean ignoreCache, String proxyForPrincipal) {
+
+ RoleToken roleToken = null;
+
+ // first lookup in our cache to see if it can be satisfied
+ // only if we're not asked to ignore the cache
+
+ String cacheKey = null;
+ if (!cacheDisabled) {
+ cacheKey = getRoleTokenCacheKey(domainName, roleName, proxyForPrincipal);
+ if (cacheKey != null && !ignoreCache) {
+ roleToken = lookupRoleTokenInCache(cacheKey, minExpiryTime, maxExpiryTime);
+ if (roleToken != null) {
+ return roleToken;
+ }
+ // start prefetch for this token if prefetch is enabled
+ if (enablePrefetch && prefetchAutoEnable) {
+ if (prefetchRoleToken(domainName, roleName, minExpiryTime, maxExpiryTime, proxyForPrincipal)) {
+ roleToken = lookupRoleTokenInCache(cacheKey, minExpiryTime, maxExpiryTime);
+ }
+ if (roleToken != null) {
+ return roleToken;
+ }
+ LOG.error("GetRoleToken: cache prefetch and lookup error");
+ }
+ }
+ }
+
+ // 2nd look in service providers
+ //
+ for (ZTSClientService provider: ZTS_TOKEN_PROVIDERS) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("getRoleToken: found service provider=" + provider);
+ }
+
+ // provider needs to know who the client is so we'll be passing
+ // the client's domain and service names as the first two fields
+
+ roleToken = provider.fetchToken(domain, service, domainName, roleName,
+ minExpiryTime, maxExpiryTime, proxyForPrincipal);
+ if (roleToken != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("getRoleToken: service provider=" + provider + " returns token");
+ }
+ return roleToken;
+ }
+ }
+
+ // if no hit then we need to request a new token from ZTS
+
+ updateServicePrincipal();
+ try {
+ roleToken = ztsClient.getRoleToken(domainName, roleName,
+ minExpiryTime, maxExpiryTime, proxyForPrincipal);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+
+ // need to add the token to our cache. If our principal was
+ // updated then we need to retrieve a new cache key
+
+ if (!cacheDisabled) {
+ if (cacheKey == null) {
+ cacheKey = getRoleTokenCacheKey(domainName, roleName, proxyForPrincipal);
+ }
+ if (cacheKey != null) {
+ ROLE_TOKEN_CACHE.put(cacheKey, roleToken);
+ }
+ }
+ return roleToken;
+ }
+
+ private static class RolePrefetchTask extends TimerTask {
+
+ @Override
+ public void run() {
+ long currentTime = System.currentTimeMillis() / 1000;
+ FETCHER_LAST_RUN_AT.set(currentTime);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RolePrefetchTask: Fetching role token from the scheduled queue. Size=" + PREFETCH_SCHEDULED_ITEMS.size());
+ }
+ if (PREFETCH_SCHEDULED_ITEMS.isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RolePrefetchTask: No items to fetch. Queue is empty");
+ }
+ return;
+ }
+
+ List toFetch = new ArrayList<>(PREFETCH_SCHEDULED_ITEMS.size());
+ synchronized (PREFETCH_SCHEDULED_ITEMS) {
+ // if this item is to be fetched now, add it to collection
+ for (PrefetchRoleTokenScheduledItem item : PREFETCH_SCHEDULED_ITEMS) {
+ // see if item expires within next two minutes
+ long expiryTime = item.expiresAtUTC - (currentTime + FETCH_EPSILON + prefetchInterval);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RolePrefetchTask: item=" + item.identityDomain + "." + item.identityName
+ + " domain=" + item.domainName + " suffix=" + item.roleName
+ + ": to be expired at " + expiryTime);
+ }
+ if (isExpiredToken(expiryTime, item.minDuration, item.maxDuration, item.tokenMinExpiryTime)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RolePrefetchTask: item=" + item.identityDomain + "."
+ + item.identityName + " domain=" + item.domainName
+ + " roleName=" + item.roleName + ": expired. Fetch this item. " + expiryTime);
+ }
+ toFetch.add(item);
+ }
+ }
+ }
+
+ // if toFetch is not empty, fetch those tokens, and add refreshed scheduled items back to the queue
+ if (!toFetch.isEmpty()) {
+ Set oldSvcLoaderCache = SVC_LOADER_CACHE_KEYS.get();
+ Set newSvcLoaderCache = null;
+ // fetch items
+ for (PrefetchRoleTokenScheduledItem item : toFetch) {
+ // create ZTS Client for this particular item
+ try (ZTSClient itemZtsClient = new ZTSClient(item.identityDomain, item.identityName)) {
+
+ if (item.siaClient != null) {
+ itemZtsClient.siaClient = item.siaClient;
+ }
+ if (item.ztsClient != null) {
+ itemZtsClient.ztsClient = item.ztsClient;
+ }
+ if (item.isRoleToken()) {
+ // check if this came from service provider
+ //
+ String key = itemZtsClient.getRoleTokenCacheKey(item.domainName, item.roleName,
+ item.proxyForPrincipal);
+ if (oldSvcLoaderCache.contains(key)) {
+ // if haven't gotten the new list of service
+ // loader tokens then get it now
+ if (newSvcLoaderCache == null) {
+ newSvcLoaderCache = loadSvcProviderTokens();
+ }
+ // check if the key is in the new key set
+ // - if not, mark the item as invalid
+ if (!newSvcLoaderCache.contains(key)) {
+ item.invalid(true);
+ }
+ } else {
+ RoleToken token = itemZtsClient.getRoleToken(item.domainName, item.roleName,
+ item.minDuration, item.maxDuration, true, item.proxyForPrincipal);
+ // update the expire time
+ item.expiresAtUTC(token.getExpiryTime());
+ }
+ } else {
+ AWSTemporaryCredentials awsCred = itemZtsClient.getAWSTemporaryCredentials(item.domainName,
+ item.roleName, true);
+ item.expiresAtUTC(awsCred.getExpiration().millis() / 1000);
+ }
+ } catch (Exception ex) {
+ // any exception should remove this item from fetch queue
+ item.invalid(true);
+ PREFETCH_SCHEDULED_ITEMS.remove(item);
+ LOG.error("RolePrefetchTask: Error while trying to prefetch token, msg="
+ + ex.getMessage(), ex);
+ }
+ }
+
+ // remove all invalid items.
+ toFetch.removeIf(p -> p.invalid);
+
+ // now, add items back.
+ if (!toFetch.isEmpty()) {
+ synchronized (PREFETCH_SCHEDULED_ITEMS) {
+ // make sure there are no items of common
+ PREFETCH_SCHEDULED_ITEMS.removeAll(toFetch);
+ // add them back
+ PREFETCH_SCHEDULED_ITEMS.addAll(toFetch);
+ }
+ }
+ }
+ }
+ }
+
+ // method useful for test purposes only
+ int getScheduledItemsSize() {
+ synchronized (PREFETCH_SCHEDULED_ITEMS) {
+ // ConcurrentLinkedQueue.size() method is typically not very useful in concurrent applications
+ return PREFETCH_SCHEDULED_ITEMS.size();
+ }
+ }
+
+ /**
+ * Pre-fetches role tokens so that the client does not take the hit of
+ * contacting ZTS Server for its first request (avg ~75ms). The client
+ * library will automatically try to keep the cache up to date such
+ * that the tokens are never expired and regular getRoleToken requests
+ * are fulfilled from the cache instead of contacting ZTS Server.
+ * @param domainName name of the domain
+ * @param roleName (optional) only interested in roles with this name
+ * @param minExpiryTime (optional) specifies that the returned RoleToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned RoleToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @return true if all is well, else false
+ */
+ boolean prefetchRoleToken(String domainName, String roleName,
+ Integer minExpiryTime, Integer maxExpiryTime) {
+
+ return prefetchRoleToken(domainName, roleName, minExpiryTime, maxExpiryTime, null);
+ }
+
+ /**
+ * Pre-fetches role tokens so that the client does not take the hit of
+ * contacting ZTS Server for its first request (avg ~75ms). The client
+ * library will automatically try to keep the cache up to date such
+ * that the tokens are never expired and regular getRoleToken requests
+ * are fulfilled from the cache instead of contacting ZTS Server.
+ * @param domainName name of the domain
+ * @param roleName (optional) only interested in roles with this name
+ * @param minExpiryTime (optional) specifies that the returned RoleToken must be
+ * at least valid (min/lower bound) for specified number of seconds,
+ * @param maxExpiryTime (optional) specifies that the returned RoleToken must be
+ * at most valid (max/upper bound) for specified number of seconds.
+ * @param proxyForPrincipal (optional) request is proxy for this principal
+ * @return true if all is well, else false
+ */
+ boolean prefetchRoleToken(String domainName, String roleName,
+ Integer minExpiryTime, Integer maxExpiryTime, String proxyForPrincipal) {
+ return prefetchToken(domainName, roleName, minExpiryTime, maxExpiryTime, proxyForPrincipal, true);
+ }
+
+ boolean prefetchAwsCred(String domainName, String roleName, Integer minExpiryTime, Integer maxExpiryTime) {
+ return prefetchToken(domainName, roleName, minExpiryTime, maxExpiryTime, null, false);
+ }
+
+ boolean prefetchToken(String domainName, String roleName, Integer minExpiryTime,
+ Integer maxExpiryTime, String proxyForPrincipal, boolean isRoleToken) {
+
+ if (domainName == null || domainName.trim().isEmpty()) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, "Domain Name cannot be empty");
+ }
+
+ long expiryTimeUTC = 0;
+ if (isRoleToken) {
+ RoleToken token = getRoleToken(domainName, roleName, minExpiryTime, maxExpiryTime, true, proxyForPrincipal);
+ if (token == null) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("PrefetchToken: No token fetchable using given params, domain=" + domainName
+ + ", roleSuffix=" + roleName);
+ }
+ return false;
+ }
+ expiryTimeUTC = token.getExpiryTime();
+ } else {
+ AWSTemporaryCredentials awsCred = getAWSTemporaryCredentials(domainName, roleName, true);
+ if (awsCred == null) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("PrefetchToken: No aws credential fetchable using given params, domain=" + domainName
+ + ", roleName=" + roleName);
+ }
+ return false;
+ }
+ expiryTimeUTC = awsCred.getExpiration().millis() / 1000;
+ }
+
+ if (enablePrefetch == false || domain == null || domain.isEmpty() || service == null || service.isEmpty()) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("PrefetchToken: Failure to setup ongoing prefetch of tokens. Both domain("
+ + domain + ") and service(" + service + ") is required");
+ }
+ return false;
+ }
+ PrefetchRoleTokenScheduledItem item = new PrefetchRoleTokenScheduledItem()
+ .isRoleToken(isRoleToken)
+ .domainName(domainName)
+ .roleName(roleName)
+ .proxyForPrincipal(proxyForPrincipal)
+ .minDuration(minExpiryTime)
+ .maxDuration(maxExpiryTime)
+ .expiresAtUTC(expiryTimeUTC)
+ .identityDomain(domain)
+ .identityName(service)
+ .tokenMinExpiryTime(ZTSClient.tokenMinExpiryTime)
+ .providedZTSUrl(this.ztsUrl)
+ .ztsClient(this.ztsClient)
+ .siaClient(this.siaClient);
+
+ if (!PREFETCH_SCHEDULED_ITEMS.contains(item)) {
+ PREFETCH_SCHEDULED_ITEMS.add(item);
+ } else {
+ // contains item based on these 6 fields:
+ // domainName identityDomain identityName suffix trustDomain isRoleToken
+ //
+ // So need to remove and append since the new token expiry has changed
+ // .expiresAtUTC(token.getExpiryTime())
+ //
+ PREFETCH_SCHEDULED_ITEMS.remove(item);
+ PREFETCH_SCHEDULED_ITEMS.add(item);
+ }
+
+ if (FETCH_TIMER == null) {
+ synchronized (TIMER_LOCK) {
+ if (FETCH_TIMER == null) {
+ FETCH_TIMER = new Timer();
+ // check the fetch items every prefetchInterval seconds.
+ FETCH_TIMER.schedule(new RolePrefetchTask(), 0, prefetchInterval * 1000);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ String getRoleTokenCacheKey(String domainName, String roleName) {
+ return getRoleTokenCacheKey(domainName, roleName, null);
+ }
+
+ String getRoleTokenCacheKey(String domainName, String roleName, String proxyForPrincipal) {
+
+ // before we generate a cache key we need to have a valid domain
+
+ if (domain == null) {
+ return null;
+ }
+
+ StringBuilder cacheKey = new StringBuilder(256);
+ cacheKey.append("p=");
+ cacheKey.append(domain);
+ if (service != null) {
+ cacheKey.append(".").append(service);
+ }
+
+ cacheKey.append(";d=");
+ cacheKey.append(domainName);
+
+ if (roleName != null && !roleName.isEmpty()) {
+ cacheKey.append(";r=");
+ cacheKey.append(roleName);
+ }
+ if (proxyForPrincipal != null && !proxyForPrincipal.isEmpty()) {
+ cacheKey.append(";u=");
+ cacheKey.append(proxyForPrincipal);
+ }
+
+ return cacheKey.toString();
+ }
+
+ boolean isExpiredToken(long expiryTime, Integer minExpiryTime, Integer maxExpiryTime) {
+ return isExpiredToken(expiryTime, minExpiryTime, maxExpiryTime, ZTSClient.tokenMinExpiryTime);
+ }
+
+ static boolean isExpiredToken(long expiryTime, Integer minExpiryTime, Integer maxExpiryTime, int tokenMinExpiryTime) {
+
+ // we'll first make sure if we're given both min and max expiry
+ // times then both conditions are satisfied
+ if (minExpiryTime != null && expiryTime < minExpiryTime) {
+ return true;
+ }
+
+ if (maxExpiryTime != null && expiryTime > maxExpiryTime) {
+ return true;
+ }
+
+ // if both limits were null then we need to make sure
+ // that our token is valid for based on our min configured value
+
+ if (minExpiryTime == null && maxExpiryTime == null && expiryTime < tokenMinExpiryTime) {
+ return true;
+ }
+
+ return false;
+ }
+
+ RoleToken lookupRoleTokenInCache(String cacheKey, Integer minExpiryTime, Integer maxExpiryTime) {
+
+ RoleToken roleToken = ROLE_TOKEN_CACHE.get(cacheKey);
+ if (roleToken == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("LookupRoleTokenInCache: cache-lookup key: " + cacheKey + " result: not found");
+ }
+ return null;
+ }
+
+ // before returning our cache hit we need to make sure it
+ // satisfies the time requirements as specified by the client
+
+ long expiryTime = roleToken.getExpiryTime() - (System.currentTimeMillis() / 1000);
+
+ if (isExpiredToken(expiryTime, minExpiryTime, maxExpiryTime, tokenMinExpiryTime)) {
+
+ if (LOG.isInfoEnabled()) {
+ LOG.info("LookupRoleTokenInCache: role-cache-lookup key: " + cacheKey + " token-expiry: " + expiryTime
+ + " req-min-expiry: " + minExpiryTime + " req-max-expiry: " + maxExpiryTime
+ + " client-min-expiry: " + tokenMinExpiryTime + " result: expired");
+ }
+
+ ROLE_TOKEN_CACHE.remove(cacheKey);
+ return null;
+ }
+
+ return roleToken;
+ }
+
+ AWSTemporaryCredentials lookupAwsCredInCache(String cacheKey, Integer minExpiryTime, Integer maxExpiryTime) {
+
+ AWSTemporaryCredentials awsCred = awsCredCache.get(cacheKey);
+ if (awsCred == null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("LookupAwsCredInCache: aws-cache-lookup key: " + cacheKey + " result: not found");
+ }
+ return null;
+ }
+
+ // before returning our cache hit we need to make sure it
+ // satisfies the time requirements as specified by the client
+
+ long expiryTime = awsCred.getExpiration().millis() - System.currentTimeMillis();
+ expiryTime /= 1000; // expiry time is in seconds
+
+ if (isExpiredToken(expiryTime, minExpiryTime, maxExpiryTime, tokenMinExpiryTime)) {
+
+ if (LOG.isInfoEnabled()) {
+ LOG.info("LookupAwsCredInCache: aws-cache-lookup key: " + cacheKey + " token-expiry: " + expiryTime
+ + " req-min-expiry: " + minExpiryTime + " req-max-expiry: " + maxExpiryTime
+ + " client-min-expiry: " + tokenMinExpiryTime + " result: expired");
+ }
+
+ awsCredCache.remove(cacheKey);
+ return null;
+ }
+
+ return awsCred;
+ }
+
+ /**
+ * Retrieve the list of roles that the given principal has access to in the domain
+ * @param domainName name of the domain
+ * @param principal name of the principal
+ * @return RoleAccess object on success. ZTSClientException will be thrown in case of failure
+ */
+ public RoleAccess getRoleAccess(String domainName, String principal) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getRoleAccess(domainName, principal);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getMessage());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified service object from a domain
+ * @param domainName name of the domain
+ * @param serviceName name of the service to be retrieved
+ * @return ServiceIdentity object on success. ZTSClientException will be thrown in case of failure
+ */
+ public ServiceIdentity getServiceIdentity(String domainName, String serviceName) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getServiceIdentity(domainName, serviceName);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the specified public key from the given service object
+ * @param domainName name of the domain
+ * @param serviceName name of the service
+ * @param keyId the identifier of the public key to be retrieved
+ * @return PublicKeyEntry object or ZTSClientException will be thrown in case of failure
+ */
+ public PublicKeyEntry getPublicKeyEntry(String domainName, String serviceName, String keyId) {
+ try {
+ return ztsClient.getPublicKeyEntry(domainName, serviceName, keyId);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Retrieve the full list of services defined in a domain
+ * @param domainName name of the domain
+ * @return list of all service names on success. ZTSClientException will be thrown in case of failure
+ */
+ public ServiceIdentityList getServiceIdentityList(String domainName) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getServiceIdentityList(domainName);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * For a given provider domain get a list of tenant domain names that the user is a member of
+ * @param providerDomainName name of the provider domain
+ * @param userName is the name of the user to search for in the tenant domains of the provider
+ * @param roleName is the name of the role to filter on when searching through the list of tenants with
+ * the specified role name.
+ * @param serviceName is the name of the service to filter on that the tenant has on-boarded to
+ * @return TenantDomains object which contains a list of tenant domain names for a given provider
+ * domain, that the user is a member of
+ */
+ public TenantDomains getTenantDomains(String providerDomainName, String userName,
+ String roleName, String serviceName) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getTenantDomains(providerDomainName, userName, roleName, serviceName);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Request by a service to refresh its NToken. The original NToken must have been
+ * obtained by an authorized service by calling the postInstanceTenantRequest
+ * method.
+ * @param domain Name of the domain
+ * @param service Name of the service
+ * @param req InstanceRefreshRequest object for th request
+ * @return Identity object that includes a refreshed NToken for the service
+ */
+ public Identity postInstanceRefreshRequest(String domain, String service, InstanceRefreshRequest req) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.postInstanceRefreshRequest(domain, service, req);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * For a given domain and role return AWS temporary credentials
+ * @param domainName name of the domain
+ * @param roleName is the name of the role
+ * @return AWSTemporaryCredentials AWS credentials
+ */
+ public AWSTemporaryCredentials getAWSTemporaryCredentials(String domainName, String roleName) {
+
+ return getAWSTemporaryCredentials(domainName, roleName, false);
+ }
+
+ public AWSTemporaryCredentials getAWSTemporaryCredentials(String domainName, String roleName, boolean ignoreCache) {
+
+ // first lookup in our cache to see if it can be satisfied
+ // only if we're not asked to ignore the cache
+
+ AWSTemporaryCredentials awsCred = null;
+ String cacheKey = getRoleTokenCacheKey(domainName, roleName, null);
+ if (cacheKey != null && !ignoreCache) {
+ awsCred = lookupAwsCredInCache(cacheKey, null, null);
+ if (awsCred != null) {
+ return awsCred;
+ }
+ // start prefetch for this token if prefetch is enabled
+ if (enablePrefetch && prefetchAutoEnable) {
+ if (prefetchAwsCred(domainName, roleName, null, null)) {
+ awsCred = lookupAwsCredInCache(cacheKey, null, null);
+ }
+ if (awsCred != null) {
+ return awsCred;
+ }
+ LOG.error("GetAWSTemporaryCredentials: cache prefetch and lookup error");
+ }
+ }
+
+ // if no hit then we need to request a new token from ZTS
+
+ updateServicePrincipal();
+
+ try {
+ awsCred = ztsClient.getAWSTemporaryCredentials(domainName, roleName);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+
+ // need to add the token to our cache. If our principal was
+ // updated then we need to retrieve a new cache key
+
+ if (cacheKey == null) {
+ cacheKey = getRoleTokenCacheKey(domainName, roleName, null);
+ }
+ if (cacheKey != null) {
+ awsCredCache.put(cacheKey, awsCred);
+ }
+ return awsCred;
+ }
+
+ /**
+ * Retrieve the list of all policies (not just names) from the ZTS Server that
+ * is signed with both ZTS's and ZMS's private keys. It will pass an option matchingTag
+ * so that ZTS can skip returning signed policies if no changes have taken
+ * place since that tag was issued.
+ * @param domainName name of the domain
+ * @param matchingTag name of the tag issued with last request
+ * @param responseHeaders contains the "tag" returned for modification
+ * time of the policies, map key = "tag", List should contain a single value
+ * @return list of policies signed by ZTS Server. ZTSClientException will be thrown in case of failure
+ */
+ public DomainSignedPolicyData getDomainSignedPolicyData(String domainName, String matchingTag,
+ Map> responseHeaders) {
+ try {
+ DomainSignedPolicyData sp = ztsClient.getDomainSignedPolicyData(domainName, matchingTag, responseHeaders);
+ return sp;
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Verify if the given principal has access to the specified role in the
+ * domain or not.
+ * @param domainName name of the domain
+ * @param roleName name of the role
+ * @param principal name of the principal to check for
+ * @return Access object with grant true/false response. ZTSClientException will be thrown in case of failure
+ */
+ public Access getAccess(String domainName, String roleName, String principal) {
+ updateServicePrincipal();
+ try {
+ return ztsClient.getAccess(domainName, roleName, principal);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ /**
+ * Caller may post set of domain metric attributes for monitoring and logging.
+ * ZTSClientException will be thrown in case of failure
+ * @param domainName name of the domain
+ * @param req list of domain metrics with their values
+ */
+ public void postDomainMetrics(String domainName, DomainMetrics req) {
+ updateServicePrincipal();
+ try {
+ ztsClient.postDomainMetrics(domainName, req);
+ } catch (ResourceException ex) {
+ throw new ZTSClientException(ex.getCode(), ex.getData());
+ } catch (Exception ex) {
+ throw new ZTSClientException(ZTSClientException.BAD_REQUEST, ex.getMessage());
+ }
+ }
+
+ static class PrefetchRoleTokenScheduledItem {
+
+ boolean isRoleToken = true;
+ PrefetchRoleTokenScheduledItem isRoleToken(boolean isRole) {
+ isRoleToken = isRole;
+ return this;
+ }
+ boolean isRoleToken() {
+ return isRoleToken;
+ }
+
+ String providedZTSUrl;
+ PrefetchRoleTokenScheduledItem providedZTSUrl(String u) {
+ providedZTSUrl = u;
+ return this;
+ }
+
+ SIA siaClient;
+ PrefetchRoleTokenScheduledItem siaClient(SIA s) {
+ siaClient = s;
+ return this;
+ }
+
+ ZTSRDLGeneratedClient ztsClient;
+ PrefetchRoleTokenScheduledItem ztsClient(ZTSRDLGeneratedClient z) {
+ ztsClient = z;
+ return this;
+ }
+
+ boolean invalid;
+ PrefetchRoleTokenScheduledItem invalid(boolean i) {
+ invalid = i;
+ return this;
+ }
+
+ String identityDomain;
+ PrefetchRoleTokenScheduledItem identityDomain(String d) {
+ identityDomain = d;
+ return this;
+ }
+
+ String identityName;
+ PrefetchRoleTokenScheduledItem identityName(String d) {
+ identityName = d;
+ return this;
+ }
+
+ String domainName;
+ PrefetchRoleTokenScheduledItem domainName(String d) {
+ domainName = d;
+ return this;
+ }
+
+ String roleName;
+ PrefetchRoleTokenScheduledItem roleName(String s) {
+ roleName = s;
+ return this;
+ }
+
+ String proxyForPrincipal;
+ PrefetchRoleTokenScheduledItem proxyForPrincipal(String u) {
+ proxyForPrincipal = u;
+ return this;
+ }
+
+ Integer minDuration;
+ PrefetchRoleTokenScheduledItem minDuration(Integer min) {
+ minDuration = min;
+ return this;
+ }
+
+ Integer maxDuration;
+ PrefetchRoleTokenScheduledItem maxDuration(Integer max) {
+ maxDuration = max;
+ return this;
+ }
+
+ long expiresAtUTC;
+ PrefetchRoleTokenScheduledItem expiresAtUTC(long e) {
+ expiresAtUTC = e;
+ return this;
+ }
+
+ int tokenMinExpiryTime;
+ PrefetchRoleTokenScheduledItem tokenMinExpiryTime(int t) {
+ tokenMinExpiryTime = t;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((domainName == null) ? 0 : domainName.hashCode());
+ result = prime * result + ((identityDomain == null) ? 0 : identityDomain.hashCode());
+ result = prime * result + ((identityName == null) ? 0 : identityName.hashCode());
+ result = prime * result + ((roleName == null) ? 0 : roleName.hashCode());
+ result = prime * result + ((proxyForPrincipal == null) ? 0 : proxyForPrincipal.hashCode());
+ result = prime * result + Boolean.hashCode(isRoleToken);
+
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ PrefetchRoleTokenScheduledItem other = (PrefetchRoleTokenScheduledItem) obj;
+ if (domainName == null) {
+ if (other.domainName != null) {
+ return false;
+ }
+ } else if (!domainName.equals(other.domainName)) {
+ return false;
+ }
+ if (identityDomain == null) {
+ if (other.identityDomain != null) {
+ return false;
+ }
+ } else if (!identityDomain.equals(other.identityDomain)) {
+ return false;
+ }
+ if (identityName == null) {
+ if (other.identityName != null) {
+ return false;
+ }
+ } else if (!identityName.equals(other.identityName)) {
+ return false;
+ }
+ if (roleName == null) {
+ if (other.roleName != null) {
+ return false;
+ }
+ } else if (!roleName.equals(other.roleName)) {
+ return false;
+ }
+ if (proxyForPrincipal == null) {
+ if (other.proxyForPrincipal != null) {
+ return false;
+ }
+ } else if (!proxyForPrincipal.equals(other.proxyForPrincipal)) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ public class AWSHostNameVerifier implements HostnameVerifier {
+
+ String dnsHostname = null;
+
+ public AWSHostNameVerifier(String hostname) {
+ dnsHostname = hostname;
+ }
+
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+
+ Certificate[] certs = null;
+ try {
+ certs = session.getPeerCertificates();
+ } catch (SSLPeerUnverifiedException e) {
+ }
+ if (certs == null) {
+ return false;
+ }
+
+ for (Certificate cert : certs) {
+ try {
+ X509Certificate x509Cert = (X509Certificate) cert;
+ if (matchDnsHostname(x509Cert.getSubjectAlternativeNames())) {
+ return true;
+ }
+ } catch (CertificateParsingException e) {
+ }
+ }
+ return false;
+ }
+
+ boolean matchDnsHostname(Collection> altNames) {
+
+ if (altNames == null) {
+ return false;
+ }
+
+ // GeneralName ::= CHOICE {
+ // otherName [0] OtherName,
+ // rfc822Name [1] IA5String,
+ // dNSName [2] IA5String,
+ // x400Address [3] ORAddress,
+ // directoryName [4] Name,
+ // ediPartyName [5] EDIPartyName,
+ // uniformResourceIdentifier [6] IA5String,
+ // iPAddress [7] OCTET STRING,
+ // registeredID [8] OBJECT IDENTIFIER}
+
+ for (@SuppressWarnings("rawtypes") List item : altNames) {
+ Integer type = (Integer) item.get(0);
+ if (type == 2) {
+ String dns = (String) item.get(1);
+ if (dnsHostname.equalsIgnoreCase(dns)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private static Set loadSvcProviderTokens() {
+
+ // if have service loader implementations, then stuff role tokens into cache
+ // and keep track of these tokens so that they will get refreshed from
+ // service loader and not zts server
+
+ Set