mirror of https://github.com/vernonkeenan/lib
parent
bdf29af51a
commit
d53ad0d601
|
|
@ -0,0 +1,305 @@
|
||||||
|
package members_client_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.tnxs.net/vernonkeenan/lib/api/members/members_client"
|
||||||
|
"code.tnxs.net/vernonkeenan/lib/api/members/members_client/clusters"
|
||||||
|
"code.tnxs.net/vernonkeenan/lib/api/members/members_models"
|
||||||
|
openapiruntime "github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var clusterTestAuth = openapiruntime.ClientAuthInfoWriterFunc(
|
||||||
|
func(openapiruntime.ClientRequest, strfmt.Registry) error { return nil },
|
||||||
|
)
|
||||||
|
|
||||||
|
type clusterCaptureTransport struct {
|
||||||
|
operation *openapiruntime.ClientOperation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (transport *clusterCaptureTransport) Submit(
|
||||||
|
operation *openapiruntime.ClientOperation,
|
||||||
|
) (any, error) {
|
||||||
|
return transport.SubmitContext(context.Background(), operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (transport *clusterCaptureTransport) SubmitContext(
|
||||||
|
_ context.Context,
|
||||||
|
operation *openapiruntime.ClientOperation,
|
||||||
|
) (any, error) {
|
||||||
|
transport.operation = operation
|
||||||
|
switch operation.ID {
|
||||||
|
case "getClusters":
|
||||||
|
return clusters.NewGetClustersOK(), nil
|
||||||
|
case "postClusters":
|
||||||
|
return clusters.NewPostClustersOK(), nil
|
||||||
|
case "putClusters":
|
||||||
|
return clusters.NewPutClustersOK(), nil
|
||||||
|
default:
|
||||||
|
panic("unexpected generated Cluster operation: " + operation.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGeneratedClusterOperationContract(t *testing.T) {
|
||||||
|
type operationCall func(openapiruntime.ContextualTransport) error
|
||||||
|
tests := []struct {
|
||||||
|
name, wantID, wantMethod, wantPath string
|
||||||
|
call operationCall
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "list or get Cluster", wantID: "getClusters",
|
||||||
|
wantMethod: "GET", wantPath: "/clusters",
|
||||||
|
call: func(transport openapiruntime.ContextualTransport) error {
|
||||||
|
_, err := clusters.New(transport, strfmt.Default).GetClusters(
|
||||||
|
clusters.NewGetClustersParams().WithTenantID("tenant-example"),
|
||||||
|
clusterTestAuth,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "create Cluster", wantID: "postClusters",
|
||||||
|
wantMethod: "POST", wantPath: "/clusters",
|
||||||
|
call: func(transport openapiruntime.ContextualTransport) error {
|
||||||
|
_, err := clusters.New(transport, strfmt.Default).PostClusters(
|
||||||
|
clusters.NewPostClustersParams().WithTenantID("tenant-example"),
|
||||||
|
clusterTestAuth,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "CAS update Cluster", wantID: "putClusters",
|
||||||
|
wantMethod: "PUT", wantPath: "/clusters",
|
||||||
|
call: func(transport openapiruntime.ContextualTransport) error {
|
||||||
|
_, err := clusters.New(transport, strfmt.Default).PutClusters(
|
||||||
|
clusters.NewPutClustersParams().WithTenantID("tenant-example"),
|
||||||
|
clusterTestAuth,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
transport := &clusterCaptureTransport{}
|
||||||
|
if err := test.call(transport); err != nil {
|
||||||
|
t.Fatalf("generated client operation failed: %v", err)
|
||||||
|
}
|
||||||
|
if transport.operation == nil {
|
||||||
|
t.Fatal("generated client did not submit an operation")
|
||||||
|
}
|
||||||
|
if transport.operation.ID != test.wantID {
|
||||||
|
t.Errorf("operation ID = %q, want %q", transport.operation.ID, test.wantID)
|
||||||
|
}
|
||||||
|
if transport.operation.Method != test.wantMethod {
|
||||||
|
t.Errorf("method = %q, want %q", transport.operation.Method, test.wantMethod)
|
||||||
|
}
|
||||||
|
if transport.operation.PathPattern != test.wantPath {
|
||||||
|
t.Errorf("path = %q, want %q", transport.operation.PathPattern, test.wantPath)
|
||||||
|
}
|
||||||
|
if transport.operation.AuthInfo == nil {
|
||||||
|
t.Error("generated operation discarded its compound auth-info writer")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClusterTenantBindingCompoundAuthExactScopesAndCAS(t *testing.T) {
|
||||||
|
specText := readMembersLearningSpec(t)
|
||||||
|
pathBlock := learningSpecPathBlock(t, specText, "/clusters")
|
||||||
|
for _, forbidden := range []string{" delete:", " patch:"} {
|
||||||
|
if strings.Contains(pathBlock, forbidden) {
|
||||||
|
t.Errorf("/clusters exposes unsupported %s", strings.TrimSpace(forbidden))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operations := map[string]struct {
|
||||||
|
id, scope string
|
||||||
|
}{
|
||||||
|
"get": {id: "getClusters", scope: "members:cluster:read"},
|
||||||
|
"post": {id: "postClusters", scope: "members:cluster:create"},
|
||||||
|
"put": {id: "putClusters", scope: "members:cluster:update"},
|
||||||
|
}
|
||||||
|
const compoundSecurity = " security:\n - ApiKeyAuth: []\n kvSessionCookie: []"
|
||||||
|
for method, expected := range operations {
|
||||||
|
block := learningSpecOperationBlock(t, specText, "/clusters", method)
|
||||||
|
if !strings.Contains(block, " operationId: "+expected.id+"\n") {
|
||||||
|
t.Errorf("%s /clusters lost operationId %q", strings.ToUpper(method), expected.id)
|
||||||
|
}
|
||||||
|
if strings.Count(block, compoundSecurity) != 1 {
|
||||||
|
t.Errorf("%s /clusters does not preserve compound authentication", strings.ToUpper(method))
|
||||||
|
}
|
||||||
|
if !strings.Contains(block, expected.scope) {
|
||||||
|
t.Errorf("%s /clusters lost exact scope %q", strings.ToUpper(method), expected.scope)
|
||||||
|
}
|
||||||
|
if !strings.Contains(block, `- $ref: "#/parameters/clusterTenantId"`) {
|
||||||
|
t.Errorf("%s /clusters is not tenantId-bound", strings.ToUpper(method))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recordID := "cluster-id"
|
||||||
|
getParams := clusters.NewGetClustersParams().
|
||||||
|
WithTenantID("tenant-example").
|
||||||
|
WithClusterID(&recordID)
|
||||||
|
if getParams.TenantID != "tenant-example" {
|
||||||
|
t.Fatal("Cluster list/get client lost the required tenantId")
|
||||||
|
}
|
||||||
|
if getParams.ClusterID == nil || *getParams.ClusterID != recordID {
|
||||||
|
t.Fatal("Cluster list/get client lost its clusterId filter")
|
||||||
|
}
|
||||||
|
if clusters.NewPostClustersParams().WithTenantID("tenant-example").TenantID != "tenant-example" {
|
||||||
|
t.Fatal("Cluster create client lost the required tenantId")
|
||||||
|
}
|
||||||
|
if clusters.NewPutClustersParams().WithTenantID("tenant-example").TenantID != "tenant-example" {
|
||||||
|
t.Fatal("Cluster update client lost the required tenantId")
|
||||||
|
}
|
||||||
|
if !clusters.NewPutClustersConflict().IsCode(409) {
|
||||||
|
t.Fatal("Cluster update client lost the optimistic concurrency response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClusterModelAndSingleRecordRequestAreBounded(t *testing.T) {
|
||||||
|
assertExactModelFields(t, members_models.Cluster{}, map[string]string{
|
||||||
|
"CreatedByID": "*string", "CreatedDate": "*string", "Description": "*string",
|
||||||
|
"Environment": "*string", "Gateway": "*string", "ID": "string",
|
||||||
|
"IPAddress": "*string", "LastModifiedByID": "*string",
|
||||||
|
"LastModifiedDate": "*string", "Name": "*string", "OwnerID": "*string",
|
||||||
|
"Ref": "*string", "Status": "*string", "Subnet": "*string",
|
||||||
|
"TenantID": "*string", "Type": "*string", "Zone": "*string",
|
||||||
|
})
|
||||||
|
|
||||||
|
firstName, secondName := "One", "Two"
|
||||||
|
request := &members_models.ClusterRequest{
|
||||||
|
Data: []*members_models.Cluster{{Name: &firstName}, {Name: &secondName}},
|
||||||
|
}
|
||||||
|
if err := request.Validate(strfmt.Default); err == nil {
|
||||||
|
t.Fatal("generated Cluster request accepted a bulk payload")
|
||||||
|
}
|
||||||
|
if err := (&members_models.ClusterRequest{
|
||||||
|
Data: []*members_models.Cluster{{Name: &firstName}},
|
||||||
|
}).Validate(strfmt.Default); err != nil {
|
||||||
|
t.Fatalf("generated Cluster request rejected one valid record: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMembersCompoundAuthWritesBothCredentialsWithoutExposure(t *testing.T) {
|
||||||
|
const (
|
||||||
|
apiKey = "test-api-key"
|
||||||
|
sessionToken = "test-session-token"
|
||||||
|
)
|
||||||
|
writer, err := members_client.NewMembersCompoundAuth(apiKey, sessionToken)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("construct compound auth writer: %v", err)
|
||||||
|
}
|
||||||
|
request := new(openapiruntime.TestClientRequest)
|
||||||
|
if err := writer.AuthenticateRequest(request, strfmt.Default); err != nil {
|
||||||
|
t.Fatalf("write compound authentication: %v", err)
|
||||||
|
}
|
||||||
|
if got := request.Headers.Get("X-API-Key"); got != apiKey {
|
||||||
|
t.Errorf("X-API-Key = %q, want test value", got)
|
||||||
|
}
|
||||||
|
if got := request.Headers.Get("Cookie"); got != "kvSession="+sessionToken {
|
||||||
|
t.Errorf("Cookie = %q, want kvSession test value", got)
|
||||||
|
}
|
||||||
|
formatted := fmt.Sprintf("%v", writer)
|
||||||
|
if strings.Contains(formatted, apiKey) || strings.Contains(formatted, sessionToken) {
|
||||||
|
t.Fatal("compound auth writer formatting exposed credential material")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMembersCompoundAuthRejectsMissingOrUnsafeCredentialsWithoutEcho(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name, apiKey, sessionToken string
|
||||||
|
}{
|
||||||
|
{name: "missing API key", sessionToken: "session"},
|
||||||
|
{name: "missing session", apiKey: "api-key"},
|
||||||
|
{name: "API key header injection", apiKey: "api-key\r\nunsafe", sessionToken: "session"},
|
||||||
|
{name: "session cookie injection", apiKey: "api-key", sessionToken: "session;unsafe"},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
if writer, err := members_client.NewMembersCompoundAuth(
|
||||||
|
test.apiKey, test.sessionToken,
|
||||||
|
); err == nil || writer != nil {
|
||||||
|
t.Fatal("unsafe compound authentication was accepted")
|
||||||
|
} else if (test.apiKey != "" && strings.Contains(err.Error(), test.apiKey)) ||
|
||||||
|
(test.sessionToken != "" && strings.Contains(err.Error(), test.sessionToken)) {
|
||||||
|
t.Fatal("validation error exposed credential material")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClusterSurfaceOmitsDeleteDatabaseAndDSN(t *testing.T) {
|
||||||
|
contract := reflect.TypeOf((*clusters.ClientService)(nil)).Elem()
|
||||||
|
for index := 0; index < contract.NumMethod(); index++ {
|
||||||
|
method := contract.Method(index).Name
|
||||||
|
for _, forbidden := range []string{"Delete", "Database", "DSN"} {
|
||||||
|
if strings.Contains(method, forbidden) {
|
||||||
|
t.Errorf("Cluster client exposes forbidden method %s", method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root := reflect.TypeOf(members_client.Members{})
|
||||||
|
if _, exists := root.FieldByName("Clusters"); !exists {
|
||||||
|
t.Fatal("root Members client does not expose governed Clusters")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGeneratedClusterSurfaceHasNoExternalBypassOrSecrets(t *testing.T) {
|
||||||
|
repoRoot := learningRepoRoot(t)
|
||||||
|
targets := []string{
|
||||||
|
filepath.Join(repoRoot, "api", "members", "members_client", "clusters"),
|
||||||
|
filepath.Join(repoRoot, "api", "members", "members_client", "compound_auth.go"),
|
||||||
|
filepath.Join(repoRoot, "api", "members", "members_models", "cluster.go"),
|
||||||
|
filepath.Join(repoRoot, "api", "members", "members_models", "cluster_request.go"),
|
||||||
|
filepath.Join(repoRoot, "api", "members", "members_models", "cluster_response.go"),
|
||||||
|
}
|
||||||
|
credentialLiteral := regexp.MustCompile(
|
||||||
|
`(?i)(api[_-]?key|password|secret)\s*[:=]\s*["'][^"']+["']`,
|
||||||
|
)
|
||||||
|
for _, target := range targets {
|
||||||
|
err := filepath.WalkDir(target, func(
|
||||||
|
path string, entry os.DirEntry, walkErr error,
|
||||||
|
) error {
|
||||||
|
if walkErr != nil {
|
||||||
|
return walkErr
|
||||||
|
}
|
||||||
|
if entry.IsDir() || !strings.HasSuffix(path, ".go") ||
|
||||||
|
strings.HasSuffix(path, "_test.go") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
content, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lower := strings.ToLower(string(content))
|
||||||
|
for _, forbidden := range []string{
|
||||||
|
"salesforce", "sf-gate", "go-force", "private key-----",
|
||||||
|
"members_client/databases", "dsn",
|
||||||
|
} {
|
||||||
|
if strings.Contains(lower, forbidden) {
|
||||||
|
t.Errorf("%s contains forbidden boundary %q", path, forbidden)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if credentialLiteral.Match(content) {
|
||||||
|
t.Errorf("%s contains a credential-shaped literal", path)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("scan generated Cluster target %s: %v", target, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -60,30 +60,30 @@ type ClientOption func(*runtime.ClientOperation)
|
||||||
// ClientService is the interface for Client methods.
|
// ClientService is the interface for Client methods.
|
||||||
type ClientService interface {
|
type ClientService interface {
|
||||||
|
|
||||||
// GetClusters get a list clusters.
|
// GetClusters get governed tenant clusters.
|
||||||
GetClusters(params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error)
|
GetClusters(params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error)
|
||||||
|
|
||||||
// GetClustersContext get a list clusters.
|
// GetClustersContext get governed tenant clusters.
|
||||||
GetClustersContext(ctx context.Context, params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error)
|
GetClustersContext(ctx context.Context, params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error)
|
||||||
|
|
||||||
// PostClusters create new clusters.
|
// PostClusters create a governed cluster.
|
||||||
PostClusters(params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error)
|
PostClusters(params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error)
|
||||||
|
|
||||||
// PostClustersContext create new clusters.
|
// PostClustersContext create a governed cluster.
|
||||||
PostClustersContext(ctx context.Context, params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error)
|
PostClustersContext(ctx context.Context, params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error)
|
||||||
|
|
||||||
// PutClusters update clustera.
|
// PutClusters update a governed cluster.
|
||||||
PutClusters(params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error)
|
PutClusters(params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error)
|
||||||
|
|
||||||
// PutClustersContext update clustera.
|
// PutClustersContext update a governed cluster.
|
||||||
PutClustersContext(ctx context.Context, params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error)
|
PutClustersContext(ctx context.Context, params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error)
|
||||||
|
|
||||||
SetTransport(transport runtime.ContextualTransport)
|
SetTransport(transport runtime.ContextualTransport)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClusters gets a list clusters.
|
// GetClusters gets governed tenant clusters.
|
||||||
//
|
//
|
||||||
// Return a list of Cluster records from the datastore.
|
// Return tenant-scoped Cluster records. Requires members:cluster:read and an active human membership in tenantId..
|
||||||
//
|
//
|
||||||
// This method does not support injected context.
|
// This method does not support injected context.
|
||||||
// However, timeout and opentracing contexts are honored whenever enabled.
|
// However, timeout and opentracing contexts are honored whenever enabled.
|
||||||
|
|
@ -100,9 +100,9 @@ func (a *Client) GetClusters(params *GetClustersParams, authInfo runtime.ClientA
|
||||||
return a.GetClustersContext(ctx, params, authInfo, opts...)
|
return a.GetClustersContext(ctx, params, authInfo, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClustersContext gets a list clusters.
|
// GetClustersContext gets governed tenant clusters.
|
||||||
//
|
//
|
||||||
// Return a list of Cluster records from the datastore.
|
// Return tenant-scoped Cluster records. Requires members:cluster:read and an active human membership in tenantId..
|
||||||
//
|
//
|
||||||
// Do not use the deprecated [GetClustersParams.Context] with this method: it would be ignored.
|
// Do not use the deprecated [GetClustersParams.Context] with this method: it would be ignored.
|
||||||
func (a *Client) GetClustersContext(ctx context.Context, params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error) {
|
func (a *Client) GetClustersContext(ctx context.Context, params *GetClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetClustersOK, error) {
|
||||||
|
|
@ -148,9 +148,9 @@ func (a *Client) GetClustersContext(ctx context.Context, params *GetClustersPara
|
||||||
panic(msg)
|
panic(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostClusters creates new clusters.
|
// PostClusters creates a governed cluster.
|
||||||
//
|
//
|
||||||
// Create Clusters.
|
// Create one tenant-scoped Cluster. Requires members:cluster:create and active Owner or Manager access. ID, TenantID, and audit fields are server-owned..
|
||||||
//
|
//
|
||||||
// This method does not support injected context.
|
// This method does not support injected context.
|
||||||
// However, timeout and opentracing contexts are honored whenever enabled.
|
// However, timeout and opentracing contexts are honored whenever enabled.
|
||||||
|
|
@ -167,9 +167,9 @@ func (a *Client) PostClusters(params *PostClustersParams, authInfo runtime.Clien
|
||||||
return a.PostClustersContext(ctx, params, authInfo, opts...)
|
return a.PostClustersContext(ctx, params, authInfo, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostClustersContext creates new clusters.
|
// PostClustersContext creates a governed cluster.
|
||||||
//
|
//
|
||||||
// Create Clusters.
|
// Create one tenant-scoped Cluster. Requires members:cluster:create and active Owner or Manager access. ID, TenantID, and audit fields are server-owned..
|
||||||
//
|
//
|
||||||
// Do not use the deprecated [PostClustersParams.Context] with this method: it would be ignored.
|
// Do not use the deprecated [PostClustersParams.Context] with this method: it would be ignored.
|
||||||
func (a *Client) PostClustersContext(ctx context.Context, params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error) {
|
func (a *Client) PostClustersContext(ctx context.Context, params *PostClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PostClustersOK, error) {
|
||||||
|
|
@ -215,9 +215,9 @@ func (a *Client) PostClustersContext(ctx context.Context, params *PostClustersPa
|
||||||
panic(msg)
|
panic(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutClusters updates clustera.
|
// PutClusters updates a governed cluster.
|
||||||
//
|
//
|
||||||
// Update Cluster.
|
// CAS-update one tenant-scoped Cluster. Requires members:cluster:update, active Owner or Manager access, and the current LastModifiedDate. TenantID and audit fields remain server-owned..
|
||||||
//
|
//
|
||||||
// This method does not support injected context.
|
// This method does not support injected context.
|
||||||
// However, timeout and opentracing contexts are honored whenever enabled.
|
// However, timeout and opentracing contexts are honored whenever enabled.
|
||||||
|
|
@ -234,9 +234,9 @@ func (a *Client) PutClusters(params *PutClustersParams, authInfo runtime.ClientA
|
||||||
return a.PutClustersContext(ctx, params, authInfo, opts...)
|
return a.PutClustersContext(ctx, params, authInfo, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutClustersContext updates clustera.
|
// PutClustersContext updates a governed cluster.
|
||||||
//
|
//
|
||||||
// Update Cluster.
|
// CAS-update one tenant-scoped Cluster. Requires members:cluster:update, active Owner or Manager access, and the current LastModifiedDate. TenantID and audit fields remain server-owned..
|
||||||
//
|
//
|
||||||
// Do not use the deprecated [PutClustersParams.Context] with this method: it would be ignored.
|
// Do not use the deprecated [PutClustersParams.Context] with this method: it would be ignored.
|
||||||
func (a *Client) PutClustersContext(ctx context.Context, params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error) {
|
func (a *Client) PutClustersContext(ctx context.Context, params *PutClustersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*PutClustersOK, error) {
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,11 @@ type GetClustersParams struct {
|
||||||
// Format: int64
|
// Format: int64
|
||||||
Offset *int64
|
Offset *int64
|
||||||
|
|
||||||
|
// TenantID.
|
||||||
|
//
|
||||||
|
// Tenant that owns the Cluster. Members verifies the active human membership and never accepts TenantID from the body.
|
||||||
|
TenantID string
|
||||||
|
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
|
|
||||||
inner innerParams
|
inner innerParams
|
||||||
|
|
@ -176,6 +181,17 @@ func (o *GetClustersParams) SetOffset(offset *int64) {
|
||||||
o.Offset = offset
|
o.Offset = offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTenantID adds the tenantID to the get clusters params.
|
||||||
|
func (o *GetClustersParams) WithTenantID(tenantID string) *GetClustersParams {
|
||||||
|
o.SetTenantID(tenantID)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTenantID adds the tenantId to the get clusters params.
|
||||||
|
func (o *GetClustersParams) SetTenantID(tenantID string) {
|
||||||
|
o.TenantID = tenantID
|
||||||
|
}
|
||||||
|
|
||||||
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
||||||
func (o *GetClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
func (o *GetClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||||
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
||||||
|
|
@ -234,6 +250,16 @@ func (o *GetClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// query param tenantId
|
||||||
|
qrTenantID := o.TenantID
|
||||||
|
qTenantID := qrTenantID
|
||||||
|
if qTenantID != "" {
|
||||||
|
|
||||||
|
if err := r.SetQueryParam("tenantId", qTenantID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,14 @@ type PostClustersParams struct {
|
||||||
|
|
||||||
// ClusterRequest.
|
// ClusterRequest.
|
||||||
//
|
//
|
||||||
// An array of Cluster records
|
// Exactly one governed Cluster record
|
||||||
ClusterRequest *members_models.ClusterRequest
|
ClusterRequest *members_models.ClusterRequest
|
||||||
|
|
||||||
|
// TenantID.
|
||||||
|
//
|
||||||
|
// Tenant that owns the Cluster. Members verifies the active human membership and never accepts TenantID from the body.
|
||||||
|
TenantID string
|
||||||
|
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
|
|
||||||
inner innerParams
|
inner innerParams
|
||||||
|
|
@ -140,6 +145,17 @@ func (o *PostClustersParams) SetClusterRequest(clusterRequest *members_models.Cl
|
||||||
o.ClusterRequest = clusterRequest
|
o.ClusterRequest = clusterRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTenantID adds the tenantID to the post clusters params.
|
||||||
|
func (o *PostClustersParams) WithTenantID(tenantID string) *PostClustersParams {
|
||||||
|
o.SetTenantID(tenantID)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTenantID adds the tenantId to the post clusters params.
|
||||||
|
func (o *PostClustersParams) SetTenantID(tenantID string) {
|
||||||
|
o.TenantID = tenantID
|
||||||
|
}
|
||||||
|
|
||||||
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
||||||
func (o *PostClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
func (o *PostClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||||
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
||||||
|
|
@ -152,6 +168,16 @@ func (o *PostClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// query param tenantId
|
||||||
|
qrTenantID := o.TenantID
|
||||||
|
qTenantID := qrTenantID
|
||||||
|
if qTenantID != "" {
|
||||||
|
|
||||||
|
if err := r.SetQueryParam("tenantId", qTenantID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,14 @@ type PutClustersParams struct {
|
||||||
|
|
||||||
// ClusterRequest.
|
// ClusterRequest.
|
||||||
//
|
//
|
||||||
// An array of Cluster records
|
// Exactly one governed Cluster record
|
||||||
ClusterRequest *members_models.ClusterRequest
|
ClusterRequest *members_models.ClusterRequest
|
||||||
|
|
||||||
|
// TenantID.
|
||||||
|
//
|
||||||
|
// Tenant that owns the Cluster. Members verifies the active human membership and never accepts TenantID from the body.
|
||||||
|
TenantID string
|
||||||
|
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
|
|
||||||
inner innerParams
|
inner innerParams
|
||||||
|
|
@ -140,6 +145,17 @@ func (o *PutClustersParams) SetClusterRequest(clusterRequest *members_models.Clu
|
||||||
o.ClusterRequest = clusterRequest
|
o.ClusterRequest = clusterRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithTenantID adds the tenantID to the put clusters params.
|
||||||
|
func (o *PutClustersParams) WithTenantID(tenantID string) *PutClustersParams {
|
||||||
|
o.SetTenantID(tenantID)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTenantID adds the tenantId to the put clusters params.
|
||||||
|
func (o *PutClustersParams) SetTenantID(tenantID string) {
|
||||||
|
o.TenantID = tenantID
|
||||||
|
}
|
||||||
|
|
||||||
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
// WriteToRequest writes these params to a [runtime.ClientRequest].
|
||||||
func (o *PutClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
func (o *PutClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||||
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
if err := r.SetTimeout(o.inner.timeout); err != nil {
|
||||||
|
|
@ -152,6 +168,16 @@ func (o *PutClustersParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// query param tenantId
|
||||||
|
qrTenantID := o.TenantID
|
||||||
|
qTenantID := qrTenantID
|
||||||
|
if qTenantID != "" {
|
||||||
|
|
||||||
|
if err := r.SetQueryParam("tenantId", qTenantID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ func (o *PutClustersReader) ReadResponse(response runtime.ClientResponse, consum
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, result
|
return nil, result
|
||||||
|
case 409:
|
||||||
|
result := NewPutClustersConflict()
|
||||||
|
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, result
|
||||||
case 422:
|
case 422:
|
||||||
result := NewPutClustersUnprocessableEntity()
|
result := NewPutClustersUnprocessableEntity()
|
||||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||||
|
|
@ -347,6 +353,74 @@ func (o *PutClustersNotFound) readResponse(response runtime.ClientResponse, cons
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPutClustersConflict creates a PutClustersConflict with default headers values
|
||||||
|
func NewPutClustersConflict() *PutClustersConflict {
|
||||||
|
return &PutClustersConflict{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutClustersConflict describes a response with status code 409, with default header values.
|
||||||
|
//
|
||||||
|
// The supplied LastModifiedDate is stale; reload the record before retrying.
|
||||||
|
type PutClustersConflict struct {
|
||||||
|
Payload *members_models.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSuccess returns true when this put clusters conflict response has a 2xx status code
|
||||||
|
func (o *PutClustersConflict) IsSuccess() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRedirect returns true when this put clusters conflict response has a 3xx status code
|
||||||
|
func (o *PutClustersConflict) IsRedirect() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsClientError returns true when this put clusters conflict response has a 4xx status code
|
||||||
|
func (o *PutClustersConflict) IsClientError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsServerError returns true when this put clusters conflict response has a 5xx status code
|
||||||
|
func (o *PutClustersConflict) IsServerError() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsCode returns true when this put clusters conflict response a status code equal to that given
|
||||||
|
func (o *PutClustersConflict) IsCode(code int) bool {
|
||||||
|
return code == 409
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code gets the status code for the put clusters conflict response
|
||||||
|
func (o *PutClustersConflict) Code() int {
|
||||||
|
return 409
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PutClustersConflict) Error() string {
|
||||||
|
payload, _ := json.Marshal(o.Payload)
|
||||||
|
return fmt.Sprintf("[PUT /clusters][%d] putClustersConflict %s", 409, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PutClustersConflict) String() string {
|
||||||
|
payload, _ := json.Marshal(o.Payload)
|
||||||
|
return fmt.Sprintf("[PUT /clusters][%d] putClustersConflict %s", 409, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PutClustersConflict) GetPayload() *members_models.Error {
|
||||||
|
return o.Payload
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PutClustersConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
o.Payload = new(members_models.Error)
|
||||||
|
|
||||||
|
// response payload
|
||||||
|
if err := consumer.Consume(response.Body(), o.Payload); err != nil && !stderrors.Is(err, io.EOF) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewPutClustersUnprocessableEntity creates a PutClustersUnprocessableEntity with default headers values
|
// NewPutClustersUnprocessableEntity creates a PutClustersUnprocessableEntity with default headers values
|
||||||
func NewPutClustersUnprocessableEntity() *PutClustersUnprocessableEntity {
|
func NewPutClustersUnprocessableEntity() *PutClustersUnprocessableEntity {
|
||||||
return &PutClustersUnprocessableEntity{}
|
return &PutClustersUnprocessableEntity{}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
// (c) 2012-2020 by Taxnexus, Inc.
|
||||||
|
// All rights reserved worldwide.
|
||||||
|
// Proprietary product; unlicensed use is not allowed
|
||||||
|
|
||||||
|
package members_client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxCredentialLength = 8192
|
||||||
|
|
||||||
|
// NewMembersCompoundAuth returns the auth writer required by governed Members
|
||||||
|
// operations: a service API key plus the active human kvSession cookie.
|
||||||
|
//
|
||||||
|
// Credential values are retained only inside the returned closure. Validation
|
||||||
|
// errors identify the invalid field without including its value.
|
||||||
|
func NewMembersCompoundAuth(apiKey, sessionToken string) (runtime.ClientAuthInfoWriter, error) {
|
||||||
|
if err := validateHeaderCredential("Members API key", apiKey); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := validateCookieCredential("Members session token", sessionToken); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtime.ClientAuthInfoWriterFunc(func(request runtime.ClientRequest, _ strfmt.Registry) error {
|
||||||
|
if err := request.SetHeaderParam("X-API-Key", apiKey); err != nil {
|
||||||
|
return fmt.Errorf("set Members API key header: %w", err)
|
||||||
|
}
|
||||||
|
if err := request.SetHeaderParam("Cookie", "kvSession="+sessionToken); err != nil {
|
||||||
|
return fmt.Errorf("set Members session cookie: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateHeaderCredential(name, value string) error {
|
||||||
|
if value == "" {
|
||||||
|
return fmt.Errorf("%s is required", name)
|
||||||
|
}
|
||||||
|
if len(value) > maxCredentialLength {
|
||||||
|
return fmt.Errorf("%s exceeds the maximum length", name)
|
||||||
|
}
|
||||||
|
for index := 0; index < len(value); index++ {
|
||||||
|
if value[index] < 0x21 || value[index] > 0x7e {
|
||||||
|
return fmt.Errorf("%s contains an invalid header byte", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCookieCredential(name, value string) error {
|
||||||
|
if err := validateHeaderCredential(name, value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for index := 0; index < len(value); index++ {
|
||||||
|
character := value[index]
|
||||||
|
if character == '"' || character == ',' || character == ';' || character == '\\' {
|
||||||
|
return errors.New(name + " contains an invalid cookie byte")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const membersProviderSpecSHA256 = "091a5ea132ea076ecfd391a02458e4a2445aa16dee89487b0aef977631766c4c"
|
const membersProviderSpecSHA256 = "707dcee4b2078d431ba7f6c6a81105fb1c94c4b0b9298fa04567e63343af9a9d"
|
||||||
|
|
||||||
var learningTestAuth = openapiruntime.ClientAuthInfoWriterFunc(func(openapiruntime.ClientRequest, strfmt.Registry) error {
|
var learningTestAuth = openapiruntime.ClientAuthInfoWriterFunc(func(openapiruntime.ClientRequest, strfmt.Registry) error {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -517,7 +517,7 @@ func TestMembersSpecIsPinnedToProviderSource(t *testing.T) {
|
||||||
}
|
}
|
||||||
sum := sha256.Sum256(mainSpec)
|
sum := sha256.Sum256(mainSpec)
|
||||||
if got := hex.EncodeToString(sum[:]); got != membersProviderSpecSHA256 {
|
if got := hex.EncodeToString(sum[:]); got != membersProviderSpecSHA256 {
|
||||||
t.Fatalf("Members spec drifted from integrated Track provider commit 6bfdcbe: SHA-256 = %s, want %s", got, membersProviderSpecSHA256)
|
t.Fatalf("Members spec drifted from integrated Cluster provider commit a7cedc5: SHA-256 = %s, want %s", got, membersProviderSpecSHA256)
|
||||||
}
|
}
|
||||||
|
|
||||||
externalSpec, err := os.ReadFile(filepath.Join(repoRoot, "swagger", "external", "members-vernonkeenan.yaml"))
|
externalSpec, err := os.ReadFile(filepath.Join(repoRoot, "swagger", "external", "members-vernonkeenan.yaml"))
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const membersTrackSpecSHA256 = "091a5ea132ea076ecfd391a02458e4a2445aa16dee89487b0aef977631766c4c"
|
const membersTrackSpecSHA256 = "707dcee4b2078d431ba7f6c6a81105fb1c94c4b0b9298fa04567e63343af9a9d"
|
||||||
|
|
||||||
var trackTestAuth = openapiruntime.ClientAuthInfoWriterFunc(
|
var trackTestAuth = openapiruntime.ClientAuthInfoWriterFunc(
|
||||||
func(openapiruntime.ClientRequest, strfmt.Registry) error { return nil },
|
func(openapiruntime.ClientRequest, strfmt.Registry) error { return nil },
|
||||||
|
|
@ -233,7 +233,7 @@ func TestMembersSpecIsPinnedToTrackProviderCommit(t *testing.T) {
|
||||||
sum := sha256.Sum256(mainSpec)
|
sum := sha256.Sum256(mainSpec)
|
||||||
if got := hex.EncodeToString(sum[:]); got != membersTrackSpecSHA256 {
|
if got := hex.EncodeToString(sum[:]); got != membersTrackSpecSHA256 {
|
||||||
t.Fatalf(
|
t.Fatalf(
|
||||||
"Members spec drifted from integrated Track provider commit 6bfdcbe: SHA-256 = %s, want %s",
|
"Members spec drifted from integrated Cluster provider commit a7cedc5: SHA-256 = %s, want %s",
|
||||||
got, membersTrackSpecSHA256,
|
got, membersTrackSpecSHA256,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,74 +9,439 @@ package members_models
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/swag/jsonutils"
|
"github.com/go-openapi/swag/jsonutils"
|
||||||
|
"github.com/go-openapi/swag/typeutils"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cluster cluster
|
// Cluster Tenant-owned infrastructure metadata. TenantID, identity, and audit fields are server-owned.
|
||||||
//
|
//
|
||||||
// swagger:model cluster
|
// swagger:model Cluster
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
|
|
||||||
// Created By
|
// created by ID
|
||||||
|
// Read Only: true
|
||||||
|
// Max Length: 36
|
||||||
CreatedByID *string `json:"CreatedByID,omitempty"`
|
CreatedByID *string `json:"CreatedByID,omitempty"`
|
||||||
|
|
||||||
// Created Date
|
// created date
|
||||||
|
// Read Only: true
|
||||||
|
// Max Length: 64
|
||||||
CreatedDate *string `json:"CreatedDate,omitempty"`
|
CreatedDate *string `json:"CreatedDate,omitempty"`
|
||||||
|
|
||||||
// Description
|
// description
|
||||||
|
// Max Length: 255
|
||||||
Description *string `json:"Description,omitempty"`
|
Description *string `json:"Description,omitempty"`
|
||||||
|
|
||||||
// Environment
|
// environment
|
||||||
|
// Max Length: 255
|
||||||
Environment *string `json:"Environment,omitempty"`
|
Environment *string `json:"Environment,omitempty"`
|
||||||
|
|
||||||
// Gateway
|
// gateway
|
||||||
|
// Max Length: 255
|
||||||
Gateway *string `json:"Gateway,omitempty"`
|
Gateway *string `json:"Gateway,omitempty"`
|
||||||
|
|
||||||
// Record Id
|
// ID
|
||||||
|
// Max Length: 36
|
||||||
ID string `json:"ID,omitempty"`
|
ID string `json:"ID,omitempty"`
|
||||||
|
|
||||||
// IP Address
|
// IP address
|
||||||
|
// Max Length: 255
|
||||||
IPAddress *string `json:"IPAddress,omitempty"`
|
IPAddress *string `json:"IPAddress,omitempty"`
|
||||||
|
|
||||||
// Last Modified By
|
// last modified by ID
|
||||||
|
// Read Only: true
|
||||||
|
// Max Length: 36
|
||||||
LastModifiedByID *string `json:"LastModifiedByID,omitempty"`
|
LastModifiedByID *string `json:"LastModifiedByID,omitempty"`
|
||||||
|
|
||||||
// Last Modified Date
|
// last modified date
|
||||||
|
// Max Length: 64
|
||||||
LastModifiedDate *string `json:"LastModifiedDate,omitempty"`
|
LastModifiedDate *string `json:"LastModifiedDate,omitempty"`
|
||||||
|
|
||||||
// Cluster Name
|
// name
|
||||||
Name *string `json:"Name,omitempty"`
|
// Required: true
|
||||||
|
// Max Length: 255
|
||||||
|
// Min Length: 1
|
||||||
|
Name *string `json:"Name"`
|
||||||
|
|
||||||
// Owner
|
// owner ID
|
||||||
|
// Max Length: 36
|
||||||
OwnerID *string `json:"OwnerID,omitempty"`
|
OwnerID *string `json:"OwnerID,omitempty"`
|
||||||
|
|
||||||
// External Reference
|
// ref
|
||||||
|
// Max Length: 255
|
||||||
Ref *string `json:"Ref,omitempty"`
|
Ref *string `json:"Ref,omitempty"`
|
||||||
|
|
||||||
// Status
|
// status
|
||||||
|
// Max Length: 255
|
||||||
Status *string `json:"Status,omitempty"`
|
Status *string `json:"Status,omitempty"`
|
||||||
|
|
||||||
// Subnet
|
// subnet
|
||||||
|
// Max Length: 255
|
||||||
Subnet *string `json:"Subnet,omitempty"`
|
Subnet *string `json:"Subnet,omitempty"`
|
||||||
|
|
||||||
// The ID of the tenant who owns this Database
|
// tenant ID
|
||||||
|
// Read Only: true
|
||||||
|
// Max Length: 36
|
||||||
TenantID *string `json:"TenantID,omitempty"`
|
TenantID *string `json:"TenantID,omitempty"`
|
||||||
|
|
||||||
// Type
|
// type
|
||||||
|
// Max Length: 255
|
||||||
Type *string `json:"Type,omitempty"`
|
Type *string `json:"Type,omitempty"`
|
||||||
|
|
||||||
// Zone
|
// zone
|
||||||
|
// Max Length: 255
|
||||||
Zone *string `json:"Zone,omitempty"`
|
Zone *string `json:"Zone,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates this cluster
|
// Validate validates this cluster
|
||||||
func (m *Cluster) Validate(formats strfmt.Registry) error {
|
func (m *Cluster) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateCreatedByID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateCreatedDate(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateDescription(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateEnvironment(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateGateway(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateIPAddress(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateLastModifiedByID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateLastModifiedDate(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateName(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateOwnerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateRef(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateStatus(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateSubnet(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateTenantID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateType(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateZone(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContextValidate validates this cluster based on context it is used
|
func (m *Cluster) validateCreatedByID(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.CreatedByID) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("CreatedByID", "body", *m.CreatedByID, 36); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateCreatedDate(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.CreatedDate) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("CreatedDate", "body", *m.CreatedDate, 64); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateDescription(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Description) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Description", "body", *m.Description, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateEnvironment(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Environment) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Environment", "body", *m.Environment, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateGateway(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Gateway) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Gateway", "body", *m.Gateway, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateID(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.ID) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("ID", "body", m.ID, 36); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateIPAddress(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.IPAddress) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("IPAddress", "body", *m.IPAddress, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateLastModifiedByID(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.LastModifiedByID) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("LastModifiedByID", "body", *m.LastModifiedByID, 36); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateLastModifiedDate(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.LastModifiedDate) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("LastModifiedDate", "body", *m.LastModifiedDate, 64); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateName(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("Name", "body", m.Name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MinLength("Name", "body", *m.Name, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Name", "body", *m.Name, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateOwnerID(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.OwnerID) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("OwnerID", "body", *m.OwnerID, 36); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateRef(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Ref) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Ref", "body", *m.Ref, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateStatus(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Status) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Status", "body", *m.Status, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateSubnet(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Subnet) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Subnet", "body", *m.Subnet, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateTenantID(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.TenantID) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("TenantID", "body", *m.TenantID, 36); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateType(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Type) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Type", "body", *m.Type, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) validateZone(formats strfmt.Registry) error {
|
||||||
|
if typeutils.IsZero(m.Zone) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxLength("Zone", "body", *m.Zone, 255); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextValidate validate this cluster based on the context it is used
|
||||||
func (m *Cluster) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
func (m *Cluster) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.contextValidateCreatedByID(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.contextValidateCreatedDate(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.contextValidateLastModifiedByID(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.contextValidateTenantID(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) contextValidateCreatedByID(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.ReadOnly(ctx, "CreatedByID", "body", m.CreatedByID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) contextValidateCreatedDate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.ReadOnly(ctx, "CreatedDate", "body", m.CreatedDate); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) contextValidateLastModifiedByID(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.ReadOnly(ctx, "LastModifiedByID", "body", m.LastModifiedByID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) contextValidateTenantID(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.ReadOnly(ctx, "TenantID", "body", m.TenantID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,18 @@ import (
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/swag/jsonutils"
|
"github.com/go-openapi/swag/jsonutils"
|
||||||
"github.com/go-openapi/swag/typeutils"
|
"github.com/go-openapi/swag/typeutils"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ClusterRequest cluster request
|
// ClusterRequest Exactly one governed Cluster object
|
||||||
//
|
//
|
||||||
// swagger:model ClusterRequest
|
// swagger:model ClusterRequest
|
||||||
type ClusterRequest struct {
|
type ClusterRequest struct {
|
||||||
|
|
||||||
// data
|
// data
|
||||||
|
// Required: true
|
||||||
|
// Max Items: 1
|
||||||
|
// Min Items: 1
|
||||||
Data []*Cluster `json:"Data"`
|
Data []*Cluster `json:"Data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,8 +45,19 @@ func (m *ClusterRequest) Validate(formats strfmt.Registry) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ClusterRequest) validateData(formats strfmt.Registry) error {
|
func (m *ClusterRequest) validateData(formats strfmt.Registry) error {
|
||||||
if typeutils.IsZero(m.Data) { // not required
|
|
||||||
return nil
|
if err := validate.Required("Data", "body", m.Data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
iDataSize := int64(len(m.Data))
|
||||||
|
|
||||||
|
if err := validate.MinItems("Data", "body", iDataSize, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validate.MaxItems("Data", "body", iDataSize, 1); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(m.Data); i++ {
|
for i := 0; i < len(m.Data); i++ {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/go-openapi/swag/typeutils"
|
"github.com/go-openapi/swag/typeutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ClusterResponse An array of cluster objects
|
// ClusterResponse An array of governed tenant Cluster objects
|
||||||
//
|
//
|
||||||
// swagger:model ClusterResponse
|
// swagger:model ClusterResponse
|
||||||
type ClusterResponse struct {
|
type ClusterResponse struct {
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,16 @@ parameters:
|
||||||
name: clusterId
|
name: clusterId
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
clusterTenantId:
|
||||||
|
description: Tenant that owns the Cluster. Members verifies the active human membership and never accepts TenantID from the body.
|
||||||
|
in: query
|
||||||
|
name: tenantId
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
maxLength: 36
|
||||||
ClusterRequest:
|
ClusterRequest:
|
||||||
description: An array of Cluster records
|
description: Exactly one governed Cluster record
|
||||||
in: body
|
in: body
|
||||||
name: ClusterRequest
|
name: ClusterRequest
|
||||||
required: true
|
required: true
|
||||||
|
|
@ -1807,10 +1815,11 @@ paths:
|
||||||
- Attendees
|
- Attendees
|
||||||
/clusters:
|
/clusters:
|
||||||
get:
|
get:
|
||||||
description: Return a list of Cluster records from the datastore
|
description: Return tenant-scoped Cluster records. Requires members:cluster:read and an active human membership in tenantId.
|
||||||
operationId: getClusters
|
operationId: getClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/clusterIdQuery"
|
- $ref: "#/parameters/clusterIdQuery"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
- $ref: "#/parameters/limitQuery"
|
- $ref: "#/parameters/limitQuery"
|
||||||
- $ref: "#/parameters/offsetQuery"
|
- $ref: "#/parameters/offsetQuery"
|
||||||
responses:
|
responses:
|
||||||
|
|
@ -1828,14 +1837,16 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Get a list Clusters
|
kvSessionCookie: []
|
||||||
|
summary: Get governed tenant Clusters
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
post:
|
post:
|
||||||
description: Create Clusters
|
description: Create one tenant-scoped Cluster. Requires members:cluster:create and active Owner or Manager access. ID, TenantID, and audit fields are server-owned.
|
||||||
operationId: postClusters
|
operationId: postClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/ClusterRequest"
|
- $ref: "#/parameters/ClusterRequest"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/responses/ClusterResponse"
|
$ref: "#/responses/ClusterResponse"
|
||||||
|
|
@ -1851,14 +1862,16 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Create new Clusters
|
kvSessionCookie: []
|
||||||
|
summary: Create a governed Cluster
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
put:
|
put:
|
||||||
description: Update Cluster
|
description: CAS-update one tenant-scoped Cluster. Requires members:cluster:update, active Owner or Manager access, and the current LastModifiedDate. TenantID and audit fields remain server-owned.
|
||||||
operationId: putClusters
|
operationId: putClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/ClusterRequest"
|
- $ref: "#/parameters/ClusterRequest"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/responses/ClusterResponse"
|
$ref: "#/responses/ClusterResponse"
|
||||||
|
|
@ -1866,6 +1879,8 @@ paths:
|
||||||
$ref: "#/responses/Unauthorized"
|
$ref: "#/responses/Unauthorized"
|
||||||
"403":
|
"403":
|
||||||
$ref: "#/responses/AccessForbidden"
|
$ref: "#/responses/AccessForbidden"
|
||||||
|
"409":
|
||||||
|
$ref: "#/responses/Conflict"
|
||||||
"404":
|
"404":
|
||||||
$ref: "#/responses/NotFound"
|
$ref: "#/responses/NotFound"
|
||||||
"422":
|
"422":
|
||||||
|
|
@ -1874,7 +1889,8 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Update Clustera
|
kvSessionCookie: []
|
||||||
|
summary: Update a governed Cluster
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
/courselessons:
|
/courselessons:
|
||||||
|
|
@ -4363,6 +4379,83 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- Users
|
- Users
|
||||||
definitions:
|
definitions:
|
||||||
|
Cluster:
|
||||||
|
description: Tenant-owned infrastructure metadata. TenantID, identity, and audit fields are server-owned.
|
||||||
|
type: object
|
||||||
|
required: [Name]
|
||||||
|
properties:
|
||||||
|
ID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
CreatedByID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
CreatedDate:
|
||||||
|
type: string
|
||||||
|
maxLength: 64
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
Description:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Environment:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Gateway:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
IPAddress:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
LastModifiedByID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
LastModifiedDate:
|
||||||
|
type: string
|
||||||
|
maxLength: 64
|
||||||
|
x-nullable: true
|
||||||
|
Name:
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
OwnerID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
Ref:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Status:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Subnet:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
TenantID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
Type:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Zone:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
Track:
|
Track:
|
||||||
description: A governed Track root. The schema has no tenant key, so Members derives ownership from the server-owned creator and active Keenan Vision tenant membership.
|
description: A governed Track root. The schema has no tenant key, so Members derives ownership from the server-owned creator and active Keenan Vision tenant membership.
|
||||||
type: object
|
type: object
|
||||||
|
|
@ -4793,18 +4886,22 @@ definitions:
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
ClusterRequest:
|
ClusterRequest:
|
||||||
|
description: Exactly one governed Cluster object
|
||||||
|
required: [Data]
|
||||||
properties:
|
properties:
|
||||||
Data:
|
Data:
|
||||||
items:
|
items:
|
||||||
$ref: "../../lib/swagger/defs/cluster.yaml#/Cluster"
|
$ref: "#/definitions/Cluster"
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 1
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
ClusterResponse:
|
ClusterResponse:
|
||||||
description: An array of cluster objects
|
description: An array of governed tenant Cluster objects
|
||||||
properties:
|
properties:
|
||||||
Data:
|
Data:
|
||||||
items:
|
items:
|
||||||
$ref: "../../lib/swagger/defs/cluster.yaml#/Cluster"
|
$ref: "#/definitions/Cluster"
|
||||||
type: array
|
type: array
|
||||||
Meta:
|
Meta:
|
||||||
$ref: "#/definitions/ResponseMeta"
|
$ref: "#/definitions/ResponseMeta"
|
||||||
|
|
|
||||||
|
|
@ -154,8 +154,16 @@ parameters:
|
||||||
name: clusterId
|
name: clusterId
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
clusterTenantId:
|
||||||
|
description: Tenant that owns the Cluster. Members verifies the active human membership and never accepts TenantID from the body.
|
||||||
|
in: query
|
||||||
|
name: tenantId
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
maxLength: 36
|
||||||
ClusterRequest:
|
ClusterRequest:
|
||||||
description: An array of Cluster records
|
description: Exactly one governed Cluster record
|
||||||
in: body
|
in: body
|
||||||
name: ClusterRequest
|
name: ClusterRequest
|
||||||
required: true
|
required: true
|
||||||
|
|
@ -1807,10 +1815,11 @@ paths:
|
||||||
- Attendees
|
- Attendees
|
||||||
/clusters:
|
/clusters:
|
||||||
get:
|
get:
|
||||||
description: Return a list of Cluster records from the datastore
|
description: Return tenant-scoped Cluster records. Requires members:cluster:read and an active human membership in tenantId.
|
||||||
operationId: getClusters
|
operationId: getClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/clusterIdQuery"
|
- $ref: "#/parameters/clusterIdQuery"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
- $ref: "#/parameters/limitQuery"
|
- $ref: "#/parameters/limitQuery"
|
||||||
- $ref: "#/parameters/offsetQuery"
|
- $ref: "#/parameters/offsetQuery"
|
||||||
responses:
|
responses:
|
||||||
|
|
@ -1828,14 +1837,16 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Get a list Clusters
|
kvSessionCookie: []
|
||||||
|
summary: Get governed tenant Clusters
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
post:
|
post:
|
||||||
description: Create Clusters
|
description: Create one tenant-scoped Cluster. Requires members:cluster:create and active Owner or Manager access. ID, TenantID, and audit fields are server-owned.
|
||||||
operationId: postClusters
|
operationId: postClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/ClusterRequest"
|
- $ref: "#/parameters/ClusterRequest"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/responses/ClusterResponse"
|
$ref: "#/responses/ClusterResponse"
|
||||||
|
|
@ -1851,14 +1862,16 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Create new Clusters
|
kvSessionCookie: []
|
||||||
|
summary: Create a governed Cluster
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
put:
|
put:
|
||||||
description: Update Cluster
|
description: CAS-update one tenant-scoped Cluster. Requires members:cluster:update, active Owner or Manager access, and the current LastModifiedDate. TenantID and audit fields remain server-owned.
|
||||||
operationId: putClusters
|
operationId: putClusters
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: "#/parameters/ClusterRequest"
|
- $ref: "#/parameters/ClusterRequest"
|
||||||
|
- $ref: "#/parameters/clusterTenantId"
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
$ref: "#/responses/ClusterResponse"
|
$ref: "#/responses/ClusterResponse"
|
||||||
|
|
@ -1866,6 +1879,8 @@ paths:
|
||||||
$ref: "#/responses/Unauthorized"
|
$ref: "#/responses/Unauthorized"
|
||||||
"403":
|
"403":
|
||||||
$ref: "#/responses/AccessForbidden"
|
$ref: "#/responses/AccessForbidden"
|
||||||
|
"409":
|
||||||
|
$ref: "#/responses/Conflict"
|
||||||
"404":
|
"404":
|
||||||
$ref: "#/responses/NotFound"
|
$ref: "#/responses/NotFound"
|
||||||
"422":
|
"422":
|
||||||
|
|
@ -1874,7 +1889,8 @@ paths:
|
||||||
$ref: "#/responses/ServerError"
|
$ref: "#/responses/ServerError"
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Update Clustera
|
kvSessionCookie: []
|
||||||
|
summary: Update a governed Cluster
|
||||||
tags:
|
tags:
|
||||||
- Clusters
|
- Clusters
|
||||||
/courselessons:
|
/courselessons:
|
||||||
|
|
@ -4363,6 +4379,83 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- Users
|
- Users
|
||||||
definitions:
|
definitions:
|
||||||
|
Cluster:
|
||||||
|
description: Tenant-owned infrastructure metadata. TenantID, identity, and audit fields are server-owned.
|
||||||
|
type: object
|
||||||
|
required: [Name]
|
||||||
|
properties:
|
||||||
|
ID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
CreatedByID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
CreatedDate:
|
||||||
|
type: string
|
||||||
|
maxLength: 64
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
Description:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Environment:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Gateway:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
IPAddress:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
LastModifiedByID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
LastModifiedDate:
|
||||||
|
type: string
|
||||||
|
maxLength: 64
|
||||||
|
x-nullable: true
|
||||||
|
Name:
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
OwnerID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
Ref:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Status:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Subnet:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
TenantID:
|
||||||
|
type: string
|
||||||
|
maxLength: 36
|
||||||
|
x-nullable: true
|
||||||
|
readOnly: true
|
||||||
|
Type:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
|
Zone:
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
x-nullable: true
|
||||||
Track:
|
Track:
|
||||||
description: A governed Track root. The schema has no tenant key, so Members derives ownership from the server-owned creator and active Keenan Vision tenant membership.
|
description: A governed Track root. The schema has no tenant key, so Members derives ownership from the server-owned creator and active Keenan Vision tenant membership.
|
||||||
type: object
|
type: object
|
||||||
|
|
@ -4793,18 +4886,22 @@ definitions:
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
ClusterRequest:
|
ClusterRequest:
|
||||||
|
description: Exactly one governed Cluster object
|
||||||
|
required: [Data]
|
||||||
properties:
|
properties:
|
||||||
Data:
|
Data:
|
||||||
items:
|
items:
|
||||||
$ref: "../../lib/swagger/defs/cluster.yaml#/Cluster"
|
$ref: "#/definitions/Cluster"
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 1
|
||||||
type: array
|
type: array
|
||||||
type: object
|
type: object
|
||||||
ClusterResponse:
|
ClusterResponse:
|
||||||
description: An array of cluster objects
|
description: An array of governed tenant Cluster objects
|
||||||
properties:
|
properties:
|
||||||
Data:
|
Data:
|
||||||
items:
|
items:
|
||||||
$ref: "../../lib/swagger/defs/cluster.yaml#/Cluster"
|
$ref: "#/definitions/Cluster"
|
||||||
type: array
|
type: array
|
||||||
Meta:
|
Meta:
|
||||||
$ref: "#/definitions/ResponseMeta"
|
$ref: "#/definitions/ResponseMeta"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue