feat: all-access and operator token from CLI (#285)
* chore: include enum values in openapi generated code * chore: add enum template to list of template overrides * chore: update template and generated code * feat: generate permissions list from openapi spec * feat: all-access and operator token from CLI Closes #22510 * fix: cloud fixed the resources endpoint * fix: all access and operator permissions cannot be composed * fix: review comments from dan-moran
This commit is contained in:
parent
ade82cc4fe
commit
714a73d9eb
203
api/api_resource_list.gen.go
Normal file
203
api/api_resource_list.gen.go
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Subset of Influx API covered by Influx CLI
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 2.0.0
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
_context "context"
|
||||
_fmt "fmt"
|
||||
_io "io"
|
||||
_nethttp "net/http"
|
||||
_neturl "net/url"
|
||||
)
|
||||
|
||||
// Linger please
|
||||
var (
|
||||
_ _context.Context
|
||||
)
|
||||
|
||||
type ResourceListApi interface {
|
||||
|
||||
/*
|
||||
* GetResources List all known resources
|
||||
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
* @return ApiGetResourcesRequest
|
||||
*/
|
||||
GetResources(ctx _context.Context) ApiGetResourcesRequest
|
||||
|
||||
/*
|
||||
* GetResourcesExecute executes the request
|
||||
* @return []string
|
||||
*/
|
||||
GetResourcesExecute(r ApiGetResourcesRequest) ([]string, error)
|
||||
|
||||
// Sets additional descriptive text in the error message if any request in
|
||||
// this API fails, indicating that it is intended to be used only on OSS
|
||||
// servers.
|
||||
OnlyOSS() ResourceListApi
|
||||
|
||||
// Sets additional descriptive text in the error message if any request in
|
||||
// this API fails, indicating that it is intended to be used only on cloud
|
||||
// servers.
|
||||
OnlyCloud() ResourceListApi
|
||||
}
|
||||
|
||||
// ResourceListApiService ResourceListApi service
|
||||
type ResourceListApiService service
|
||||
|
||||
func (a *ResourceListApiService) OnlyOSS() ResourceListApi {
|
||||
a.isOnlyOSS = true
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *ResourceListApiService) OnlyCloud() ResourceListApi {
|
||||
a.isOnlyCloud = true
|
||||
return a
|
||||
}
|
||||
|
||||
type ApiGetResourcesRequest struct {
|
||||
ctx _context.Context
|
||||
ApiService ResourceListApi
|
||||
zapTraceSpan *string
|
||||
}
|
||||
|
||||
func (r ApiGetResourcesRequest) ZapTraceSpan(zapTraceSpan string) ApiGetResourcesRequest {
|
||||
r.zapTraceSpan = &zapTraceSpan
|
||||
return r
|
||||
}
|
||||
func (r ApiGetResourcesRequest) GetZapTraceSpan() *string {
|
||||
return r.zapTraceSpan
|
||||
}
|
||||
|
||||
func (r ApiGetResourcesRequest) Execute() ([]string, error) {
|
||||
return r.ApiService.GetResourcesExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
* GetResources List all known resources
|
||||
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
* @return ApiGetResourcesRequest
|
||||
*/
|
||||
func (a *ResourceListApiService) GetResources(ctx _context.Context) ApiGetResourcesRequest {
|
||||
return ApiGetResourcesRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute executes the request
|
||||
* @return []string
|
||||
*/
|
||||
func (a *ResourceListApiService) GetResourcesExecute(r ApiGetResourcesRequest) ([]string, error) {
|
||||
var (
|
||||
localVarHTTPMethod = _nethttp.MethodGet
|
||||
localVarPostBody interface{}
|
||||
localVarFormFileName string
|
||||
localVarFileName string
|
||||
localVarFileBytes []byte
|
||||
localVarReturnValue []string
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ResourceListApiService.GetResources")
|
||||
if err != nil {
|
||||
return localVarReturnValue, GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/resources"
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := _neturl.Values{}
|
||||
localVarFormParams := _neturl.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
if r.zapTraceSpan != nil {
|
||||
localVarHeaderParams["Zap-Trace-Span"] = parameterToString(*r.zapTraceSpan, "")
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes)
|
||||
if err != nil {
|
||||
return localVarReturnValue, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, err
|
||||
}
|
||||
|
||||
var errorPrefix string
|
||||
if a.isOnlyOSS {
|
||||
errorPrefix = "InfluxDB OSS-only command failed: "
|
||||
} else if a.isOnlyCloud {
|
||||
errorPrefix = "InfluxDB Cloud-only command failed: "
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
body, err := GunzipIfNeeded(localVarHTTPResponse)
|
||||
if err != nil {
|
||||
body.Close()
|
||||
return localVarReturnValue, _fmt.Errorf("%s%w", errorPrefix, err)
|
||||
}
|
||||
localVarBody, err := _io.ReadAll(body)
|
||||
body.Close()
|
||||
if err != nil {
|
||||
return localVarReturnValue, _fmt.Errorf("%s%w", errorPrefix, err)
|
||||
}
|
||||
newErr := GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: _fmt.Sprintf("%s%s", errorPrefix, localVarHTTPResponse.Status),
|
||||
}
|
||||
var v Error
|
||||
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr.error = _fmt.Sprintf("%s: %s", newErr.Error(), err.Error())
|
||||
return localVarReturnValue, newErr
|
||||
}
|
||||
v.SetMessage(_fmt.Sprintf("%s: %s", newErr.Error(), v.GetMessage()))
|
||||
newErr.model = &v
|
||||
return localVarReturnValue, newErr
|
||||
}
|
||||
|
||||
body, err := GunzipIfNeeded(localVarHTTPResponse)
|
||||
if err != nil {
|
||||
body.Close()
|
||||
return localVarReturnValue, _fmt.Errorf("%s%w", errorPrefix, err)
|
||||
}
|
||||
localVarBody, err := _io.ReadAll(body)
|
||||
body.Close()
|
||||
if err != nil {
|
||||
return localVarReturnValue, _fmt.Errorf("%s%w", errorPrefix, err)
|
||||
}
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: _fmt.Sprintf("%s%s", errorPrefix, err.Error()),
|
||||
}
|
||||
return localVarReturnValue, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, nil
|
||||
}
|
52
api/cli-extras.gen.yml
Normal file
52
api/cli-extras.gen.yml
Normal file
@ -0,0 +1,52 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Extra configuration to force openapi to generate enum validators
|
||||
version: 2.0.0
|
||||
servers: []
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
ResourceEnumOSS:
|
||||
type: string
|
||||
enum:
|
||||
- authorizations
|
||||
- buckets
|
||||
- dashboards
|
||||
- orgs
|
||||
- sources
|
||||
- tasks
|
||||
- telegrafs
|
||||
- users
|
||||
- variables
|
||||
- scrapers
|
||||
- secrets
|
||||
- labels
|
||||
- views
|
||||
- documents
|
||||
- notificationRules
|
||||
- notificationEndpoints
|
||||
- checks
|
||||
- dbrp
|
||||
- notebooks
|
||||
ResourceEnumCloud:
|
||||
type: string
|
||||
enum:
|
||||
- authorizations
|
||||
- buckets
|
||||
- dashboards
|
||||
- orgs
|
||||
- tasks
|
||||
- telegrafs
|
||||
- users
|
||||
- variables
|
||||
- secrets
|
||||
- labels
|
||||
- views
|
||||
- documents
|
||||
- notificationRules
|
||||
- notificationEndpoints
|
||||
- checks
|
||||
- dbrp
|
||||
- flows
|
||||
- annotations
|
||||
- functions
|
@ -72,6 +72,8 @@ type APIClient struct {
|
||||
|
||||
ReplicationsApi ReplicationsApi
|
||||
|
||||
ResourceListApi ResourceListApi
|
||||
|
||||
RestoreApi RestoreApi
|
||||
|
||||
SecretsApi SecretsApi
|
||||
@ -122,6 +124,7 @@ func NewAPIClient(cfg *Configuration) *APIClient {
|
||||
c.QueryApi = (*QueryApiService)(&c.common)
|
||||
c.RemoteConnectionsApi = (*RemoteConnectionsApiService)(&c.common)
|
||||
c.ReplicationsApi = (*ReplicationsApiService)(&c.common)
|
||||
c.ResourceListApi = (*ResourceListApiService)(&c.common)
|
||||
c.RestoreApi = (*RestoreApiService)(&c.common)
|
||||
c.SecretsApi = (*SecretsApiService)(&c.common)
|
||||
c.SetupApi = (*SetupApiService)(&c.common)
|
||||
|
13
api/contract/cli-extras.yml
Normal file
13
api/contract/cli-extras.yml
Normal file
@ -0,0 +1,13 @@
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
title: Extra configuration to force openapi to generate enum validators
|
||||
version: 2.0.0
|
||||
servers: []
|
||||
paths: {}
|
||||
components:
|
||||
schemas:
|
||||
ResourceEnumOSS:
|
||||
$ref: "./openapi/src/common/schemas/Resource.yml#/properties/type"
|
||||
ResourceEnumCloud:
|
||||
$ref: "./openapi/src/cloud/schemas/Resource.yml#/properties/type"
|
||||
|
@ -63,6 +63,8 @@ paths:
|
||||
$ref: "./overrides/paths/backup_metadata.yml"
|
||||
/backup/shards/{shardID}:
|
||||
$ref: "./openapi/src/oss/paths/backup_shards_shardID.yml"
|
||||
/resources:
|
||||
$ref: "./openapi/src/common/paths/resources.yml"
|
||||
/restore/kv:
|
||||
$ref: "./openapi/src/oss/paths/restore_kv.yml"
|
||||
/restore/sql:
|
||||
|
1
api/extras/.openapi-generator-ignore
Normal file
1
api/extras/.openapi-generator-ignore
Normal file
@ -0,0 +1 @@
|
||||
README.md
|
11
api/extras/README.md
Normal file
11
api/extras/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Influx CLI - extra files supporting HTTP client
|
||||
|
||||
The `.go` files in this module are generated using [`OpenAPITools/openapi-generator`](https://github.com/OpenAPITools/openapi-generator),
|
||||
based off of our public API documentation.
|
||||
|
||||
See https://github.com/OpenAPITools/openapi-generator/issues/2360 - enums are not generated by default if they are defined inline.
|
||||
Even if they were generated by default, there appears to be no way to turn off the validation, which would be bad if the client
|
||||
started receiving new string values that were unrecognized (using an old client with a newer InfluxDB instance).
|
||||
|
||||
So the go files in this directory are generated from some enums where we want to know the list of 'known' valid values, but
|
||||
we don't want to always validate on marshal/unmarshal.
|
104
api/extras/model_resource_enum_cloud.gen.go
Normal file
104
api/extras/model_resource_enum_cloud.gen.go
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Extra configuration to force openapi to generate enum validators
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 2.0.0
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package extras
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ResourceEnumCloud the model 'ResourceEnumCloud'
|
||||
type ResourceEnumCloud string
|
||||
|
||||
// List of ResourceEnumCloud
|
||||
const (
|
||||
RESOURCEENUMCLOUD_AUTHORIZATIONS ResourceEnumCloud = "authorizations"
|
||||
RESOURCEENUMCLOUD_BUCKETS ResourceEnumCloud = "buckets"
|
||||
RESOURCEENUMCLOUD_DASHBOARDS ResourceEnumCloud = "dashboards"
|
||||
RESOURCEENUMCLOUD_ORGS ResourceEnumCloud = "orgs"
|
||||
RESOURCEENUMCLOUD_TASKS ResourceEnumCloud = "tasks"
|
||||
RESOURCEENUMCLOUD_TELEGRAFS ResourceEnumCloud = "telegrafs"
|
||||
RESOURCEENUMCLOUD_USERS ResourceEnumCloud = "users"
|
||||
RESOURCEENUMCLOUD_VARIABLES ResourceEnumCloud = "variables"
|
||||
RESOURCEENUMCLOUD_SECRETS ResourceEnumCloud = "secrets"
|
||||
RESOURCEENUMCLOUD_LABELS ResourceEnumCloud = "labels"
|
||||
RESOURCEENUMCLOUD_VIEWS ResourceEnumCloud = "views"
|
||||
RESOURCEENUMCLOUD_DOCUMENTS ResourceEnumCloud = "documents"
|
||||
RESOURCEENUMCLOUD_NOTIFICATION_RULES ResourceEnumCloud = "notificationRules"
|
||||
RESOURCEENUMCLOUD_NOTIFICATION_ENDPOINTS ResourceEnumCloud = "notificationEndpoints"
|
||||
RESOURCEENUMCLOUD_CHECKS ResourceEnumCloud = "checks"
|
||||
RESOURCEENUMCLOUD_DBRP ResourceEnumCloud = "dbrp"
|
||||
RESOURCEENUMCLOUD_FLOWS ResourceEnumCloud = "flows"
|
||||
RESOURCEENUMCLOUD_ANNOTATIONS ResourceEnumCloud = "annotations"
|
||||
RESOURCEENUMCLOUD_FUNCTIONS ResourceEnumCloud = "functions"
|
||||
)
|
||||
|
||||
func ResourceEnumCloudValues() []ResourceEnumCloud {
|
||||
return []ResourceEnumCloud{"authorizations", "buckets", "dashboards", "orgs", "tasks", "telegrafs", "users", "variables", "secrets", "labels", "views", "documents", "notificationRules", "notificationEndpoints", "checks", "dbrp", "flows", "annotations", "functions"}
|
||||
}
|
||||
|
||||
func (v *ResourceEnumCloud) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enumTypeValue := ResourceEnumCloud(value)
|
||||
for _, existing := range []ResourceEnumCloud{"authorizations", "buckets", "dashboards", "orgs", "tasks", "telegrafs", "users", "variables", "secrets", "labels", "views", "documents", "notificationRules", "notificationEndpoints", "checks", "dbrp", "flows", "annotations", "functions"} {
|
||||
if existing == enumTypeValue {
|
||||
*v = enumTypeValue
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%+v is not a valid ResourceEnumCloud", value)
|
||||
}
|
||||
|
||||
// Ptr returns reference to ResourceEnumCloud value
|
||||
func (v ResourceEnumCloud) Ptr() *ResourceEnumCloud {
|
||||
return &v
|
||||
}
|
||||
|
||||
type NullableResourceEnumCloud struct {
|
||||
value *ResourceEnumCloud
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumCloud) Get() *ResourceEnumCloud {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumCloud) Set(val *ResourceEnumCloud) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumCloud) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumCloud) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableResourceEnumCloud(val *ResourceEnumCloud) *NullableResourceEnumCloud {
|
||||
return &NullableResourceEnumCloud{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumCloud) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumCloud) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
104
api/extras/model_resource_enum_oss.gen.go
Normal file
104
api/extras/model_resource_enum_oss.gen.go
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Extra configuration to force openapi to generate enum validators
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 2.0.0
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package extras
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ResourceEnumOSS the model 'ResourceEnumOSS'
|
||||
type ResourceEnumOSS string
|
||||
|
||||
// List of ResourceEnumOSS
|
||||
const (
|
||||
RESOURCEENUMOSS_AUTHORIZATIONS ResourceEnumOSS = "authorizations"
|
||||
RESOURCEENUMOSS_BUCKETS ResourceEnumOSS = "buckets"
|
||||
RESOURCEENUMOSS_DASHBOARDS ResourceEnumOSS = "dashboards"
|
||||
RESOURCEENUMOSS_ORGS ResourceEnumOSS = "orgs"
|
||||
RESOURCEENUMOSS_SOURCES ResourceEnumOSS = "sources"
|
||||
RESOURCEENUMOSS_TASKS ResourceEnumOSS = "tasks"
|
||||
RESOURCEENUMOSS_TELEGRAFS ResourceEnumOSS = "telegrafs"
|
||||
RESOURCEENUMOSS_USERS ResourceEnumOSS = "users"
|
||||
RESOURCEENUMOSS_VARIABLES ResourceEnumOSS = "variables"
|
||||
RESOURCEENUMOSS_SCRAPERS ResourceEnumOSS = "scrapers"
|
||||
RESOURCEENUMOSS_SECRETS ResourceEnumOSS = "secrets"
|
||||
RESOURCEENUMOSS_LABELS ResourceEnumOSS = "labels"
|
||||
RESOURCEENUMOSS_VIEWS ResourceEnumOSS = "views"
|
||||
RESOURCEENUMOSS_DOCUMENTS ResourceEnumOSS = "documents"
|
||||
RESOURCEENUMOSS_NOTIFICATION_RULES ResourceEnumOSS = "notificationRules"
|
||||
RESOURCEENUMOSS_NOTIFICATION_ENDPOINTS ResourceEnumOSS = "notificationEndpoints"
|
||||
RESOURCEENUMOSS_CHECKS ResourceEnumOSS = "checks"
|
||||
RESOURCEENUMOSS_DBRP ResourceEnumOSS = "dbrp"
|
||||
RESOURCEENUMOSS_NOTEBOOKS ResourceEnumOSS = "notebooks"
|
||||
)
|
||||
|
||||
func ResourceEnumOSSValues() []ResourceEnumOSS {
|
||||
return []ResourceEnumOSS{"authorizations", "buckets", "dashboards", "orgs", "sources", "tasks", "telegrafs", "users", "variables", "scrapers", "secrets", "labels", "views", "documents", "notificationRules", "notificationEndpoints", "checks", "dbrp", "notebooks"}
|
||||
}
|
||||
|
||||
func (v *ResourceEnumOSS) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enumTypeValue := ResourceEnumOSS(value)
|
||||
for _, existing := range []ResourceEnumOSS{"authorizations", "buckets", "dashboards", "orgs", "sources", "tasks", "telegrafs", "users", "variables", "scrapers", "secrets", "labels", "views", "documents", "notificationRules", "notificationEndpoints", "checks", "dbrp", "notebooks"} {
|
||||
if existing == enumTypeValue {
|
||||
*v = enumTypeValue
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%+v is not a valid ResourceEnumOSS", value)
|
||||
}
|
||||
|
||||
// Ptr returns reference to ResourceEnumOSS value
|
||||
func (v ResourceEnumOSS) Ptr() *ResourceEnumOSS {
|
||||
return &v
|
||||
}
|
||||
|
||||
type NullableResourceEnumOSS struct {
|
||||
value *ResourceEnumOSS
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumOSS) Get() *ResourceEnumOSS {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumOSS) Set(val *ResourceEnumOSS) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumOSS) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumOSS) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableResourceEnumOSS(val *ResourceEnumOSS) *NullableResourceEnumOSS {
|
||||
return &NullableResourceEnumOSS{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableResourceEnumOSS) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableResourceEnumOSS) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
328
api/extras/utils.gen.go
Normal file
328
api/extras/utils.gen.go
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Extra configuration to force openapi to generate enum validators
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 2.0.0
|
||||
*/
|
||||
|
||||
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||
|
||||
package extras
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PtrBool is a helper routine that returns a pointer to given boolean value.
|
||||
func PtrBool(v bool) *bool { return &v }
|
||||
|
||||
// PtrInt is a helper routine that returns a pointer to given integer value.
|
||||
func PtrInt(v int) *int { return &v }
|
||||
|
||||
// PtrInt32 is a helper routine that returns a pointer to given integer value.
|
||||
func PtrInt32(v int32) *int32 { return &v }
|
||||
|
||||
// PtrInt64 is a helper routine that returns a pointer to given integer value.
|
||||
func PtrInt64(v int64) *int64 { return &v }
|
||||
|
||||
// PtrFloat32 is a helper routine that returns a pointer to given float value.
|
||||
func PtrFloat32(v float32) *float32 { return &v }
|
||||
|
||||
// PtrFloat64 is a helper routine that returns a pointer to given float value.
|
||||
func PtrFloat64(v float64) *float64 { return &v }
|
||||
|
||||
// PtrString is a helper routine that returns a pointer to given string value.
|
||||
func PtrString(v string) *string { return &v }
|
||||
|
||||
// PtrTime is helper routine that returns a pointer to given Time value.
|
||||
func PtrTime(v time.Time) *time.Time { return &v }
|
||||
|
||||
type NullableBool struct {
|
||||
value *bool
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableBool) Get() *bool {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableBool) Set(val *bool) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableBool) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableBool) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableBool(val *bool) *NullableBool {
|
||||
return &NullableBool{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableBool) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableBool) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableInt struct {
|
||||
value *int
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableInt) Get() *int {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableInt) Set(val *int) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableInt) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableInt) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableInt(val *int) *NullableInt {
|
||||
return &NullableInt{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableInt) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableInt) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableInt32 struct {
|
||||
value *int32
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableInt32) Get() *int32 {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableInt32) Set(val *int32) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableInt32) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableInt32) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableInt32(val *int32) *NullableInt32 {
|
||||
return &NullableInt32{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableInt32) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableInt32) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableInt64 struct {
|
||||
value *int64
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableInt64) Get() *int64 {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableInt64) Set(val *int64) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableInt64) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableInt64) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableInt64(val *int64) *NullableInt64 {
|
||||
return &NullableInt64{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableInt64) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableInt64) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableFloat32 struct {
|
||||
value *float32
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableFloat32) Get() *float32 {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableFloat32) Set(val *float32) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableFloat32) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableFloat32) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableFloat32(val *float32) *NullableFloat32 {
|
||||
return &NullableFloat32{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableFloat32) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableFloat32) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableFloat64 struct {
|
||||
value *float64
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableFloat64) Get() *float64 {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableFloat64) Set(val *float64) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableFloat64) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableFloat64) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableFloat64(val *float64) *NullableFloat64 {
|
||||
return &NullableFloat64{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableFloat64) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableFloat64) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableString struct {
|
||||
value *string
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableString) Get() *string {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableString) Set(val *string) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableString) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableString) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableString(val *string) *NullableString {
|
||||
return &NullableString{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableString) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *NullableString) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
||||
|
||||
type NullableTime struct {
|
||||
value *time.Time
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v NullableTime) Get() *time.Time {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *NullableTime) Set(val *time.Time) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v NullableTime) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *NullableTime) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullableTime(val *time.Time) *NullableTime {
|
||||
return &NullableTime{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v NullableTime) MarshalJSON() ([]byte, error) {
|
||||
return v.value.MarshalJSON()
|
||||
}
|
||||
|
||||
func (v *NullableTime) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
@ -27,6 +27,10 @@ const (
|
||||
COLUMNDATATYPE_UNSIGNED ColumnDataType = "unsigned"
|
||||
)
|
||||
|
||||
func ColumnDataTypeValues() []ColumnDataType {
|
||||
return []ColumnDataType{"integer", "float", "boolean", "string", "unsigned"}
|
||||
}
|
||||
|
||||
func (v *ColumnDataType) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -25,6 +25,10 @@ const (
|
||||
COLUMNSEMANTICTYPE_FIELD ColumnSemanticType = "field"
|
||||
)
|
||||
|
||||
func ColumnSemanticTypeValues() []ColumnSemanticType {
|
||||
return []ColumnSemanticType{"timestamp", "tag", "field"}
|
||||
}
|
||||
|
||||
func (v *ColumnSemanticType) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -35,6 +35,10 @@ const (
|
||||
ERRORCODE_UNSUPPORTED_MEDIA_TYPE ErrorCode = "unsupported media type"
|
||||
)
|
||||
|
||||
func ErrorCodeValues() []ErrorCode {
|
||||
return []ErrorCode{"internal error", "not found", "conflict", "invalid", "unprocessable entity", "empty value", "unavailable", "forbidden", "too many requests", "unauthorized", "method not allowed", "request too large", "unsupported media type"}
|
||||
}
|
||||
|
||||
func (v *ErrorCode) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -24,6 +24,10 @@ const (
|
||||
HEALTHCHECKSTATUS_FAIL HealthCheckStatus = "fail"
|
||||
)
|
||||
|
||||
func HealthCheckStatusValues() []HealthCheckStatus {
|
||||
return []HealthCheckStatus{"pass", "fail"}
|
||||
}
|
||||
|
||||
func (v *HealthCheckStatus) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -28,6 +28,10 @@ const (
|
||||
LINEPROTOCOLERRORCODE_UNAVAILABLE LineProtocolErrorCode = "unavailable"
|
||||
)
|
||||
|
||||
func LineProtocolErrorCodeValues() []LineProtocolErrorCode {
|
||||
return []LineProtocolErrorCode{"internal error", "not found", "conflict", "invalid", "empty value", "unavailable"}
|
||||
}
|
||||
|
||||
func (v *LineProtocolErrorCode) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -23,6 +23,10 @@ const (
|
||||
LINEPROTOCOLLENGTHERRORCODE_INVALID LineProtocolLengthErrorCode = "invalid"
|
||||
)
|
||||
|
||||
func LineProtocolLengthErrorCodeValues() []LineProtocolLengthErrorCode {
|
||||
return []LineProtocolLengthErrorCode{"invalid"}
|
||||
}
|
||||
|
||||
func (v *LineProtocolLengthErrorCode) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -24,6 +24,10 @@ const (
|
||||
SCHEMATYPE_EXPLICIT SchemaType = "explicit"
|
||||
)
|
||||
|
||||
func SchemaTypeValues() []SchemaType {
|
||||
return []SchemaType{"implicit", "explicit"}
|
||||
}
|
||||
|
||||
func (v *SchemaType) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -24,6 +24,10 @@ const (
|
||||
TASKSTATUSTYPE_INACTIVE TaskStatusType = "inactive"
|
||||
)
|
||||
|
||||
func TaskStatusTypeValues() []TaskStatusType {
|
||||
return []TaskStatusType{"active", "inactive"}
|
||||
}
|
||||
|
||||
func (v *TaskStatusType) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -24,6 +24,10 @@ const (
|
||||
TEMPLATEAPPLYACTIONKIND_SKIP_RESOURCE TemplateApplyActionKind = "skipResource"
|
||||
)
|
||||
|
||||
func TemplateApplyActionKindValues() []TemplateApplyActionKind {
|
||||
return []TemplateApplyActionKind{"skipKind", "skipResource"}
|
||||
}
|
||||
|
||||
func (v *TemplateApplyActionKind) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -26,6 +26,10 @@ const (
|
||||
WRITEPRECISION_NS WritePrecision = "ns"
|
||||
)
|
||||
|
||||
func WritePrecisionValues() []WritePrecision {
|
||||
return []WritePrecision{"ms", "s", "us", "ns"}
|
||||
}
|
||||
|
||||
func (v *WritePrecision) UnmarshalJSON(src []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(src, &value)
|
||||
|
@ -32,6 +32,9 @@ multiple locations.
|
||||
* Deleted `ContextOAuth2` key to match modification in client
|
||||
* Fixed error strings to be idiomatic according to staticcheck (lowercase, no punctuation)
|
||||
|
||||
`model_enum.mustache`
|
||||
* Add a function to build and return a slice of the valid values for the enum, named <enum_name>Values
|
||||
|
||||
`model_oneof.mustache`
|
||||
* Fixed error strings to be idiomatic according to staticcheck (lowercase, no punctuation)
|
||||
|
||||
|
75
api/templates/model_enum.mustache
Normal file
75
api/templates/model_enum.mustache
Normal file
@ -0,0 +1,75 @@
|
||||
// {{{classname}}} {{#description}}{{{.}}}{{/description}}{{^description}}the model '{{{classname}}}'{{/description}}
|
||||
type {{{classname}}} {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/format}}
|
||||
|
||||
// List of {{{name}}}
|
||||
const (
|
||||
{{#allowableValues}}
|
||||
{{#enumVars}}
|
||||
{{^-first}}
|
||||
{{/-first}}
|
||||
{{#enumClassPrefix}}{{{classname.toUpperCase}}}_{{/enumClassPrefix}}{{name}} {{{classname}}} = {{{value}}}
|
||||
{{/enumVars}}
|
||||
{{/allowableValues}}
|
||||
)
|
||||
|
||||
func {{{classname}}}Values() []{{{classname}}} {
|
||||
return []{{classname}}{ {{#allowableValues}}{{#enumVars}}{{{value}}}, {{/enumVars}} {{/allowableValues}} }
|
||||
}
|
||||
|
||||
func (v *{{{classname}}}) UnmarshalJSON(src []byte) error {
|
||||
var value {{^format}}{{dataType}}{{/format}}{{#format}}{{{format}}}{{/format}}
|
||||
err := json.Unmarshal(src, &value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enumTypeValue := {{{classname}}}(value)
|
||||
for _, existing := range []{{classname}}{ {{#allowableValues}}{{#enumVars}}{{{value}}}, {{/enumVars}} {{/allowableValues}} } {
|
||||
if existing == enumTypeValue {
|
||||
*v = enumTypeValue
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("%+v is not a valid {{classname}}", value)
|
||||
}
|
||||
|
||||
// Ptr returns reference to {{{name}}} value
|
||||
func (v {{{classname}}}) Ptr() *{{{classname}}} {
|
||||
return &v
|
||||
}
|
||||
|
||||
type Nullable{{{classname}}} struct {
|
||||
value *{{{classname}}}
|
||||
isSet bool
|
||||
}
|
||||
|
||||
func (v Nullable{{classname}}) Get() *{{classname}} {
|
||||
return v.value
|
||||
}
|
||||
|
||||
func (v *Nullable{{classname}}) Set(val *{{classname}}) {
|
||||
v.value = val
|
||||
v.isSet = true
|
||||
}
|
||||
|
||||
func (v Nullable{{classname}}) IsSet() bool {
|
||||
return v.isSet
|
||||
}
|
||||
|
||||
func (v *Nullable{{classname}}) Unset() {
|
||||
v.value = nil
|
||||
v.isSet = false
|
||||
}
|
||||
|
||||
func NewNullable{{classname}}(val *{{classname}}) *Nullable{{classname}} {
|
||||
return &Nullable{{classname}}{value: val, isSet: true}
|
||||
}
|
||||
|
||||
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v.value)
|
||||
}
|
||||
|
||||
func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
|
||||
v.isSet = true
|
||||
return json.Unmarshal(src, &v.value)
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/influxdata/influx-cli/v2/api"
|
||||
"github.com/influxdata/influx-cli/v2/api/extras"
|
||||
"github.com/influxdata/influx-cli/v2/clients"
|
||||
"github.com/influxdata/influx-cli/v2/pkg/influxid"
|
||||
)
|
||||
@ -14,6 +15,7 @@ type Client struct {
|
||||
api.AuthorizationsApi
|
||||
api.UsersApi
|
||||
api.OrganizationsApi
|
||||
api.ResourceListApi
|
||||
}
|
||||
|
||||
const (
|
||||
@ -37,43 +39,71 @@ type printParams struct {
|
||||
tokens []token
|
||||
}
|
||||
|
||||
type ResourcePermission struct {
|
||||
Name string
|
||||
Read bool
|
||||
Write bool
|
||||
IsCloud bool
|
||||
IsOss bool
|
||||
}
|
||||
|
||||
type CreateParams struct {
|
||||
clients.OrgParams
|
||||
User string
|
||||
Description string
|
||||
|
||||
WriteUserPermission bool
|
||||
ReadUserPermission bool
|
||||
|
||||
WriteBucketsPermission bool
|
||||
ReadBucketsPermission bool
|
||||
ResourcePermissions []*ResourcePermission
|
||||
|
||||
WriteBucketIds []string
|
||||
ReadBucketIds []string
|
||||
|
||||
WriteTasksPermission bool
|
||||
ReadTasksPermission bool
|
||||
OperatorPermission bool
|
||||
AllAccess bool
|
||||
}
|
||||
|
||||
WriteTelegrafsPermission bool
|
||||
ReadTelegrafsPermission bool
|
||||
func BuildResourcePermissions() []*ResourcePermission {
|
||||
cloudResources := make(map[string]struct{})
|
||||
ossResources := make(map[string]struct{})
|
||||
for _, val := range extras.ResourceEnumCloudValues() {
|
||||
cloudResources[string(val)] = struct{}{}
|
||||
}
|
||||
for _, val := range extras.ResourceEnumOSSValues() {
|
||||
ossResources[string(val)] = struct{}{}
|
||||
}
|
||||
|
||||
WriteOrganizationsPermission bool
|
||||
ReadOrganizationsPermission bool
|
||||
perms := make([]*ResourcePermission, 0, len(ossResources))
|
||||
// First the common permissions in order
|
||||
for _, val := range extras.ResourceEnumOSSValues() {
|
||||
if _, ok := cloudResources[string(val)]; ok {
|
||||
perms = append(perms, &ResourcePermission{
|
||||
Name: string(val),
|
||||
IsCloud: true,
|
||||
IsOss: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
WriteDashboardsPermission bool
|
||||
ReadDashboardsPermission bool
|
||||
// Then oss-only in order
|
||||
for _, val := range extras.ResourceEnumOSSValues() {
|
||||
if _, ok := cloudResources[string(val)]; !ok {
|
||||
perms = append(perms, &ResourcePermission{
|
||||
Name: string(val),
|
||||
IsOss: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
WriteCheckPermission bool
|
||||
ReadCheckPermission bool
|
||||
// Then cloud-only in order
|
||||
for _, val := range extras.ResourceEnumCloudValues() {
|
||||
if _, ok := ossResources[string(val)]; !ok {
|
||||
perms = append(perms, &ResourcePermission{
|
||||
Name: string(val),
|
||||
IsCloud: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
WriteNotificationRulePermission bool
|
||||
ReadNotificationRulePermission bool
|
||||
|
||||
WriteNotificationEndpointPermission bool
|
||||
ReadNotificationEndpointPermission bool
|
||||
|
||||
WriteDBRPPermission bool
|
||||
ReadDBRPPermission bool
|
||||
return perms
|
||||
}
|
||||
|
||||
func (c Client) Create(ctx context.Context, params *CreateParams) error {
|
||||
@ -90,6 +120,13 @@ func (c Client) Create(ctx context.Context, params *CreateParams) error {
|
||||
{action: WriteAction, perms: params.WriteBucketIds},
|
||||
}
|
||||
|
||||
// Get the user ID because the command only takes a username, not ID
|
||||
users, err := c.UsersApi.GetUsers(ctx).Name(params.User).Execute()
|
||||
if err != nil || len(users.GetUsers()) == 0 {
|
||||
return fmt.Errorf("could not find user with name %q: %w", params.User, err)
|
||||
}
|
||||
userID := users.GetUsers()[0].GetId()
|
||||
|
||||
var permissions []api.Permission
|
||||
for _, bp := range bucketPerms {
|
||||
for _, p := range bp.perms {
|
||||
@ -106,86 +143,81 @@ func (c Client) Create(ctx context.Context, params *CreateParams) error {
|
||||
}
|
||||
}
|
||||
|
||||
providedPerm := []struct {
|
||||
readPerm, writePerm bool
|
||||
resourceType string
|
||||
}{
|
||||
{
|
||||
readPerm: params.ReadBucketsPermission,
|
||||
writePerm: params.WriteBucketsPermission,
|
||||
resourceType: "buckets",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadCheckPermission,
|
||||
writePerm: params.WriteCheckPermission,
|
||||
resourceType: "checks",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadDashboardsPermission,
|
||||
writePerm: params.WriteDashboardsPermission,
|
||||
resourceType: "dashboards",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadNotificationEndpointPermission,
|
||||
writePerm: params.WriteNotificationEndpointPermission,
|
||||
resourceType: "notificationEndpoints",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadNotificationRulePermission,
|
||||
writePerm: params.WriteNotificationRulePermission,
|
||||
resourceType: "notificationRules",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadOrganizationsPermission,
|
||||
writePerm: params.WriteOrganizationsPermission,
|
||||
resourceType: "orgs",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadTasksPermission,
|
||||
writePerm: params.WriteTasksPermission,
|
||||
resourceType: "tasks",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadTelegrafsPermission,
|
||||
writePerm: params.WriteTelegrafsPermission,
|
||||
resourceType: "telegrafs",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadUserPermission,
|
||||
writePerm: params.WriteUserPermission,
|
||||
resourceType: "users",
|
||||
},
|
||||
{
|
||||
readPerm: params.ReadDBRPPermission,
|
||||
writePerm: params.WriteDBRPPermission,
|
||||
resourceType: "dbrp",
|
||||
},
|
||||
}
|
||||
|
||||
for _, provided := range providedPerm {
|
||||
for _, resourcePermission := range params.ResourcePermissions {
|
||||
var actions []string
|
||||
if provided.readPerm {
|
||||
if resourcePermission.Read {
|
||||
actions = append(actions, ReadAction)
|
||||
}
|
||||
if provided.writePerm {
|
||||
if resourcePermission.Write {
|
||||
actions = append(actions, WriteAction)
|
||||
}
|
||||
|
||||
for _, action := range actions {
|
||||
p := api.Permission{
|
||||
Action: action,
|
||||
Resource: makePermResource(provided.resourceType, "", orgID),
|
||||
Resource: makePermResource(resourcePermission.Name, "", orgID),
|
||||
}
|
||||
permissions = append(permissions, p)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the user ID because the command only takes a username, not ID
|
||||
users, err := c.UsersApi.GetUsers(ctx).Name(params.User).Execute()
|
||||
if err != nil || len(users.GetUsers()) == 0 {
|
||||
return fmt.Errorf("could not find user with name %q: %w", params.User, err)
|
||||
if params.OperatorPermission {
|
||||
if len(permissions) > 0 {
|
||||
return fmt.Errorf("cannot compose other permissions with operator permissions")
|
||||
}
|
||||
resources, err := c.GetResources(ctx).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range resources {
|
||||
for _, action := range []string{ReadAction, WriteAction} {
|
||||
permissions = append(permissions, api.Permission{
|
||||
Action: action,
|
||||
Resource: makePermResource(r, "", ""),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if params.AllAccess {
|
||||
if len(permissions) > 0 {
|
||||
return fmt.Errorf("cannot compose other permissions with all access permissions")
|
||||
}
|
||||
resources, err := c.GetResources(ctx).Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, r := range resources {
|
||||
if r == string(extras.RESOURCEENUMCLOUD_ORGS) {
|
||||
// orgs are handled specifically - all access is for a single org, not global access to all orgs
|
||||
permissions = append(permissions, api.Permission{
|
||||
Action: ReadAction,
|
||||
Resource: api.PermissionResource{
|
||||
Type: r,
|
||||
Id: &orgID,
|
||||
},
|
||||
})
|
||||
} else if r == string(extras.RESOURCEENUMCLOUD_USERS) {
|
||||
// users are handled specifically - all access is for a single user, not global to all users
|
||||
for _, action := range []string{ReadAction, WriteAction} {
|
||||
permissions = append(permissions, api.Permission{
|
||||
Action: action,
|
||||
Resource: api.PermissionResource{
|
||||
Type: r,
|
||||
Id: &userID,
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
for _, action := range []string{ReadAction, WriteAction} {
|
||||
permissions = append(permissions, api.Permission{
|
||||
Action: action,
|
||||
Resource: makePermResource(r, "", orgID),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
userID := users.GetUsers()[0].GetId()
|
||||
|
||||
authReq := api.AuthorizationPostRequest{
|
||||
OrgID: orgID,
|
||||
|
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/influxdata/influx-cli/v2/clients/auth"
|
||||
"github.com/influxdata/influx-cli/v2/pkg/cli/middleware"
|
||||
"github.com/urfave/cli"
|
||||
@ -21,9 +23,32 @@ func newAuthCommand() cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func helpText(perm string) struct{ readHelp, writeHelp string } {
|
||||
var helpOverrides = map[string]struct{ readHelp, writeHelp string }{
|
||||
"user": {"perform read actions against organization users", "perform mutative actions against organization users"},
|
||||
"buckets": {"perform read actions against organization buckets", "perform mutative actions against organization buckets"},
|
||||
"telegrafs": {"read telegraf configs", "create telegraf configs"},
|
||||
"orgs": {"read organizations", "create organizations"},
|
||||
"dbrps": {"read database retention policy mappings", "create database retention policy mappings"},
|
||||
}
|
||||
|
||||
help := helpOverrides[perm]
|
||||
if help.readHelp == "" {
|
||||
help.readHelp = fmt.Sprintf("read %s", perm)
|
||||
}
|
||||
if help.writeHelp == "" {
|
||||
help.writeHelp = fmt.Sprintf("create or update %s", perm)
|
||||
}
|
||||
|
||||
help.readHelp = "Grants the permission to " + help.readHelp
|
||||
help.writeHelp = "Grants the permission to " + help.writeHelp
|
||||
return help
|
||||
}
|
||||
|
||||
func newCreateCommand() cli.Command {
|
||||
var params auth.CreateParams
|
||||
flags := append(commonFlags(), getOrgFlags(¶ms.OrgParams)...)
|
||||
|
||||
flags = append(flags,
|
||||
&cli.StringFlag{
|
||||
Name: "user, u",
|
||||
@ -35,27 +60,6 @@ func newCreateCommand() cli.Command {
|
||||
Usage: "Token description",
|
||||
Destination: ¶ms.Description,
|
||||
},
|
||||
|
||||
&cli.BoolFlag{
|
||||
Name: "write-user",
|
||||
Usage: "Grants the permission to perform mutative actions against organization users",
|
||||
Destination: ¶ms.WriteUserPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-user",
|
||||
Usage: "Grants the permission to perform read actions against organization users",
|
||||
Destination: ¶ms.ReadUserPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-buckets",
|
||||
Usage: "Grants the permission to perform mutative actions against organization buckets",
|
||||
Destination: ¶ms.WriteBucketsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-buckets",
|
||||
Usage: "Grants the permission to perform read actions against organization buckets",
|
||||
Destination: ¶ms.ReadBucketsPermission,
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "write-bucket",
|
||||
Usage: "The bucket id",
|
||||
@ -65,86 +69,40 @@ func newCreateCommand() cli.Command {
|
||||
Usage: "The bucket id",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-tasks",
|
||||
Usage: "Grants the permission to create tasks",
|
||||
Destination: ¶ms.WriteTasksPermission,
|
||||
Name: "operator",
|
||||
Usage: "Grants all permissions in all organizations",
|
||||
Destination: ¶ms.OperatorPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-tasks",
|
||||
Usage: "Grants the permission to read tasks",
|
||||
Destination: ¶ms.ReadTasksPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-telegrafs",
|
||||
Usage: "Grants the permission to create telegraf configs",
|
||||
Destination: ¶ms.WriteTelegrafsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-telegrafs",
|
||||
Usage: "Grants the permission to read telegraf configs",
|
||||
Destination: ¶ms.ReadTelegrafsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-orgs",
|
||||
Usage: "Grants the permission to create organizations",
|
||||
Destination: ¶ms.WriteOrganizationsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-orgs",
|
||||
Usage: "Grants the permission to read organizations",
|
||||
Destination: ¶ms.ReadOrganizationsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-dashboards",
|
||||
Usage: "Grants the permission to create dashboards",
|
||||
Destination: ¶ms.WriteDashboardsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-dashboards",
|
||||
Usage: "Grants the permission to read dashboards",
|
||||
Destination: ¶ms.ReadDashboardsPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-checks",
|
||||
Usage: "Grants the permission to create checks",
|
||||
Destination: ¶ms.WriteCheckPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-checks",
|
||||
Usage: "Grants the permission to read checks",
|
||||
Destination: ¶ms.ReadCheckPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-notificationRules",
|
||||
Usage: "Grants the permission to create notificationRules",
|
||||
Destination: ¶ms.WriteNotificationRulePermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-notificationRules",
|
||||
Usage: "Grants the permission to read notificationRules",
|
||||
Destination: ¶ms.ReadNotificationRulePermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-notificationEndpoints",
|
||||
Usage: "Grants the permission to create notificationEndpoints",
|
||||
Destination: ¶ms.WriteNotificationEndpointPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-notificationEndpoints",
|
||||
Usage: "Grants the permission to read notificationEndpoints",
|
||||
Destination: ¶ms.ReadNotificationEndpointPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-dbrps",
|
||||
Usage: "Grants the permission to create database retention policy mappings",
|
||||
Destination: ¶ms.WriteDBRPPermission,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "read-dbrps",
|
||||
Usage: "Grants the permission to read database retention policy mappings",
|
||||
Destination: ¶ms.ReadDBRPPermission,
|
||||
Name: "all-access",
|
||||
Usage: "Grants all permissions in a single organization",
|
||||
Destination: ¶ms.AllAccess,
|
||||
},
|
||||
)
|
||||
|
||||
params.ResourcePermissions = auth.BuildResourcePermissions()
|
||||
for _, perm := range params.ResourcePermissions {
|
||||
help := helpText(perm.Name)
|
||||
ossVsCloud := ""
|
||||
if perm.IsCloud && !perm.IsOss {
|
||||
ossVsCloud = " (Cloud only)"
|
||||
}
|
||||
if !perm.IsCloud && perm.IsOss {
|
||||
ossVsCloud = " (OSS only)"
|
||||
}
|
||||
flags = append(flags,
|
||||
&cli.BoolFlag{
|
||||
Name: "read-" + perm.Name,
|
||||
Usage: help.readHelp + ossVsCloud,
|
||||
Destination: &perm.Read,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "write-" + perm.Name,
|
||||
Usage: help.writeHelp + ossVsCloud,
|
||||
Destination: &perm.Write,
|
||||
})
|
||||
}
|
||||
|
||||
return cli.Command{
|
||||
Name: "create",
|
||||
Usage: "Create authorization",
|
||||
@ -160,6 +118,7 @@ func newCreateCommand() cli.Command {
|
||||
AuthorizationsApi: api.AuthorizationsApi,
|
||||
UsersApi: api.UsersApi,
|
||||
OrganizationsApi: api.OrganizationsApi,
|
||||
ResourceListApi: api.ResourceListApi,
|
||||
}
|
||||
return client.Create(getContext(ctx), ¶ms)
|
||||
},
|
||||
|
@ -20,6 +20,15 @@ docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
--outfile /api/cli.gen.yml \
|
||||
--type yaml
|
||||
|
||||
# Merge extras to a separate file
|
||||
docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
-v "${API_DIR}":/api \
|
||||
${MERGE_DOCKER_IMG} \
|
||||
swagger-cli bundle /api/contract/cli-extras.yml \
|
||||
--outfile /api/cli-extras.gen.yml \
|
||||
--type yaml
|
||||
|
||||
|
||||
# Run the generator - This produces many more files than we want to track in git.
|
||||
docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
-v "${API_DIR}":/api \
|
||||
@ -31,10 +40,24 @@ docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
-t /api/templates \
|
||||
--additional-properties packageName=api,enumClassPrefix=true,generateInterfaces=true
|
||||
|
||||
# Run the generator for extras
|
||||
docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
-v "${API_DIR}":/api \
|
||||
${GENERATOR_DOCKER_IMG} \
|
||||
generate \
|
||||
-g go \
|
||||
-i /api/cli-extras.gen.yml \
|
||||
-o /api/extras \
|
||||
-t /api/templates \
|
||||
--additional-properties packageName=extras,enumClassPrefix=true,generateInterfaces=true
|
||||
|
||||
rm ${API_DIR}/extras/{client.go,configuration.go,response.go}
|
||||
|
||||
# Edit the generated files.
|
||||
for DIR in "${API_DIR}" "${API_DIR}/extras" ; do
|
||||
(
|
||||
# Clean up files we don't care about.
|
||||
cd "${API_DIR}"
|
||||
cd $DIR
|
||||
rm -rf go.mod go.sum git_push.sh api docs .openapi-generator .travis.yml .gitignore
|
||||
|
||||
# Change extension of generated files.
|
||||
@ -42,8 +65,9 @@ docker run --rm -it -u "$(id -u):$(id -g)" \
|
||||
base=$(basename ${f} .go)
|
||||
mv ${f} ${base}.gen.go
|
||||
done
|
||||
|
||||
# Clean up the generated code.
|
||||
cd "${ROOT_DIR}"
|
||||
>/dev/null make fmt
|
||||
)
|
||||
done
|
||||
|
||||
# Clean up the generated code.
|
||||
cd "${ROOT_DIR}"
|
||||
>/dev/null make fmt
|
||||
|
Loading…
x
Reference in New Issue
Block a user