feat: port top-level export command from influxdb (#131)

This commit is contained in:
Daniel Moran 2021-06-21 08:23:18 -04:00 committed by GitHub
parent 0ee555c6a7
commit bd0b90df41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1869 additions and 2 deletions

173
api/api_templates.gen.go Normal file
View File

@ -0,0 +1,173 @@
/*
* 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"
_ioutil "io/ioutil"
_nethttp "net/http"
_neturl "net/url"
)
// Linger please
var (
_ _context.Context
)
type TemplatesApi interface {
/*
* ExportTemplate Export a new Influx Template
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @return ApiExportTemplateRequest
*/
ExportTemplate(ctx _context.Context) ApiExportTemplateRequest
/*
* ExportTemplateExecute executes the request
* @return []TemplateEntry
*/
ExportTemplateExecute(r ApiExportTemplateRequest) ([]TemplateEntry, error)
}
// TemplatesApiService TemplatesApi service
type TemplatesApiService service
type ApiExportTemplateRequest struct {
ctx _context.Context
ApiService TemplatesApi
templateExport *TemplateExport
}
func (r ApiExportTemplateRequest) TemplateExport(templateExport TemplateExport) ApiExportTemplateRequest {
r.templateExport = &templateExport
return r
}
func (r ApiExportTemplateRequest) GetTemplateExport() *TemplateExport {
return r.templateExport
}
func (r ApiExportTemplateRequest) Execute() ([]TemplateEntry, error) {
return r.ApiService.ExportTemplateExecute(r)
}
/*
* ExportTemplate Export a new Influx Template
* @param ctx _context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
* @return ApiExportTemplateRequest
*/
func (a *TemplatesApiService) ExportTemplate(ctx _context.Context) ApiExportTemplateRequest {
return ApiExportTemplateRequest{
ApiService: a,
ctx: ctx,
}
}
/*
* Execute executes the request
* @return []TemplateEntry
*/
func (a *TemplatesApiService) ExportTemplateExecute(r ApiExportTemplateRequest) ([]TemplateEntry, error) {
var (
localVarHTTPMethod = _nethttp.MethodPost
localVarPostBody interface{}
localVarFormFileName string
localVarFileName string
localVarFileBytes []byte
localVarReturnValue []TemplateEntry
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TemplatesApiService.ExportTemplate")
if err != nil {
return localVarReturnValue, GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/templates/export"
localVarHeaderParams := make(map[string]string)
localVarQueryParams := _neturl.Values{}
localVarFormParams := _neturl.Values{}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{"application/json"}
// 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
}
// body params
localVarPostBody = r.templateExport
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
}
if localVarHTTPResponse.StatusCode >= 300 {
body, err := GunzipIfNeeded(localVarHTTPResponse)
if err != nil {
body.Close()
return localVarReturnValue, err
}
localVarBody, err := _ioutil.ReadAll(body)
body.Close()
if err != nil {
return localVarReturnValue, err
}
newErr := GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
var v Error
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, newErr
}
newErr.model = &v
return localVarReturnValue, newErr
}
body, err := GunzipIfNeeded(localVarHTTPResponse)
if err != nil {
body.Close()
return localVarReturnValue, err
}
localVarBody, err := _ioutil.ReadAll(body)
body.Close()
if err != nil {
return localVarReturnValue, err
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, newErr
}
return localVarReturnValue, nil
}

View File

@ -71,6 +71,8 @@ type APIClient struct {
TelegrafsApi TelegrafsApi
TemplatesApi TemplatesApi
UsersApi UsersApi
WriteApi WriteApi
@ -104,6 +106,7 @@ func NewAPIClient(cfg *Configuration) *APIClient {
c.SetupApi = (*SetupApiService)(&c.common)
c.TasksApi = (*TasksApiService)(&c.common)
c.TelegrafsApi = (*TelegrafsApiService)(&c.common)
c.TemplatesApi = (*TemplatesApiService)(&c.common)
c.UsersApi = (*UsersApiService)(&c.common)
c.WriteApi = (*WriteApiService)(&c.common)

View File

@ -71,6 +71,8 @@ paths:
$ref: "./overrides/paths/telegrafs_telegrafID.yml"
/dashboards:
$ref: "./overrides/paths/dashboards.yml"
/templates/export:
$ref: "./overrides/paths/templates_export.yml"
components:
parameters:
TraceSpan:
@ -253,3 +255,11 @@ components:
$ref: "./openapi/src/common/schemas/Cells.yml"
Cell:
$ref: "./openapi/src/common/schemas/Cell.yml"
TemplateExport:
$ref: "./overrides/schemas/TemplateExport.yml"
Template:
$ref: "./openapi/src/common/schemas/Template.yml"
TemplateKind:
$ref: "./openapi/src/common/schemas/TemplateKind.yml"
TemplateEntry:
$ref: "./openapi/src/common/schemas/TemplateEntry.yml"

@ -1 +1 @@
Subproject commit b837e212d51bfd9510a486849678c8a8e38e1d8e
Subproject commit 1060f69e9ffd3307a6db63c817cd51a82ff73fc4

View File

@ -0,0 +1,25 @@
post:
operationId: ExportTemplate
tags:
- Templates
summary: Export a new Influx Template
requestBody:
description: Export resources as an InfluxDB template.
required: false
content:
application/json:
schema:
$ref: "../schemas/TemplateExport.yml"
responses:
"200":
description: InfluxDB template created
content:
application/json:
schema:
$ref: "../../openapi/src/common/schemas/Template.yml"
default:
description: Unexpected error
content:
application/json:
schema:
$ref: "../../openapi/src/common/schemas/Error.yml"

View File

@ -0,0 +1,35 @@
type: object
properties:
stackID:
type: string
orgIDs:
type: array
items:
type: object
properties:
orgID:
type: string
resourceFilters:
type: object
properties:
byLabel:
type: array
items:
type: string
byResourceKind:
type: array
items:
$ref: "../../openapi/src/common/schemas/TemplateKind.yml"
resources:
type: array
items:
type: object
properties:
id:
type: string
kind:
$ref: "../../openapi/src/common/schemas/TemplateKind.yml"
name:
type: string
required: [kind]
required: [resources]

View File

@ -0,0 +1,221 @@
/*
* 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 (
"encoding/json"
)
// TemplateEntry struct for TemplateEntry
type TemplateEntry struct {
ApiVersion *string `json:"apiVersion,omitempty"`
Kind *TemplateKind `json:"kind,omitempty"`
Meta *TemplateEntryMeta `json:"meta,omitempty"`
Spec *map[string]interface{} `json:"spec,omitempty"`
}
// NewTemplateEntry instantiates a new TemplateEntry object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateEntry() *TemplateEntry {
this := TemplateEntry{}
return &this
}
// NewTemplateEntryWithDefaults instantiates a new TemplateEntry object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateEntryWithDefaults() *TemplateEntry {
this := TemplateEntry{}
return &this
}
// GetApiVersion returns the ApiVersion field value if set, zero value otherwise.
func (o *TemplateEntry) GetApiVersion() string {
if o == nil || o.ApiVersion == nil {
var ret string
return ret
}
return *o.ApiVersion
}
// GetApiVersionOk returns a tuple with the ApiVersion field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateEntry) GetApiVersionOk() (*string, bool) {
if o == nil || o.ApiVersion == nil {
return nil, false
}
return o.ApiVersion, true
}
// HasApiVersion returns a boolean if a field has been set.
func (o *TemplateEntry) HasApiVersion() bool {
if o != nil && o.ApiVersion != nil {
return true
}
return false
}
// SetApiVersion gets a reference to the given string and assigns it to the ApiVersion field.
func (o *TemplateEntry) SetApiVersion(v string) {
o.ApiVersion = &v
}
// GetKind returns the Kind field value if set, zero value otherwise.
func (o *TemplateEntry) GetKind() TemplateKind {
if o == nil || o.Kind == nil {
var ret TemplateKind
return ret
}
return *o.Kind
}
// GetKindOk returns a tuple with the Kind field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateEntry) GetKindOk() (*TemplateKind, bool) {
if o == nil || o.Kind == nil {
return nil, false
}
return o.Kind, true
}
// HasKind returns a boolean if a field has been set.
func (o *TemplateEntry) HasKind() bool {
if o != nil && o.Kind != nil {
return true
}
return false
}
// SetKind gets a reference to the given TemplateKind and assigns it to the Kind field.
func (o *TemplateEntry) SetKind(v TemplateKind) {
o.Kind = &v
}
// GetMeta returns the Meta field value if set, zero value otherwise.
func (o *TemplateEntry) GetMeta() TemplateEntryMeta {
if o == nil || o.Meta == nil {
var ret TemplateEntryMeta
return ret
}
return *o.Meta
}
// GetMetaOk returns a tuple with the Meta field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateEntry) GetMetaOk() (*TemplateEntryMeta, bool) {
if o == nil || o.Meta == nil {
return nil, false
}
return o.Meta, true
}
// HasMeta returns a boolean if a field has been set.
func (o *TemplateEntry) HasMeta() bool {
if o != nil && o.Meta != nil {
return true
}
return false
}
// SetMeta gets a reference to the given TemplateEntryMeta and assigns it to the Meta field.
func (o *TemplateEntry) SetMeta(v TemplateEntryMeta) {
o.Meta = &v
}
// GetSpec returns the Spec field value if set, zero value otherwise.
func (o *TemplateEntry) GetSpec() map[string]interface{} {
if o == nil || o.Spec == nil {
var ret map[string]interface{}
return ret
}
return *o.Spec
}
// GetSpecOk returns a tuple with the Spec field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateEntry) GetSpecOk() (*map[string]interface{}, bool) {
if o == nil || o.Spec == nil {
return nil, false
}
return o.Spec, true
}
// HasSpec returns a boolean if a field has been set.
func (o *TemplateEntry) HasSpec() bool {
if o != nil && o.Spec != nil {
return true
}
return false
}
// SetSpec gets a reference to the given map[string]interface{} and assigns it to the Spec field.
func (o *TemplateEntry) SetSpec(v map[string]interface{}) {
o.Spec = &v
}
func (o TemplateEntry) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.ApiVersion != nil {
toSerialize["apiVersion"] = o.ApiVersion
}
if o.Kind != nil {
toSerialize["kind"] = o.Kind
}
if o.Meta != nil {
toSerialize["meta"] = o.Meta
}
if o.Spec != nil {
toSerialize["spec"] = o.Spec
}
return json.Marshal(toSerialize)
}
type NullableTemplateEntry struct {
value *TemplateEntry
isSet bool
}
func (v NullableTemplateEntry) Get() *TemplateEntry {
return v.value
}
func (v *NullableTemplateEntry) Set(val *TemplateEntry) {
v.value = val
v.isSet = true
}
func (v NullableTemplateEntry) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateEntry) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateEntry(val *TemplateEntry) *NullableTemplateEntry {
return &NullableTemplateEntry{value: val, isSet: true}
}
func (v NullableTemplateEntry) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateEntry) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,113 @@
/*
* 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 (
"encoding/json"
)
// TemplateEntryMeta struct for TemplateEntryMeta
type TemplateEntryMeta struct {
Name *string `json:"name,omitempty"`
}
// NewTemplateEntryMeta instantiates a new TemplateEntryMeta object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateEntryMeta() *TemplateEntryMeta {
this := TemplateEntryMeta{}
return &this
}
// NewTemplateEntryMetaWithDefaults instantiates a new TemplateEntryMeta object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateEntryMetaWithDefaults() *TemplateEntryMeta {
this := TemplateEntryMeta{}
return &this
}
// GetName returns the Name field value if set, zero value otherwise.
func (o *TemplateEntryMeta) GetName() string {
if o == nil || o.Name == nil {
var ret string
return ret
}
return *o.Name
}
// GetNameOk returns a tuple with the Name field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateEntryMeta) GetNameOk() (*string, bool) {
if o == nil || o.Name == nil {
return nil, false
}
return o.Name, true
}
// HasName returns a boolean if a field has been set.
func (o *TemplateEntryMeta) HasName() bool {
if o != nil && o.Name != nil {
return true
}
return false
}
// SetName gets a reference to the given string and assigns it to the Name field.
func (o *TemplateEntryMeta) SetName(v string) {
o.Name = &v
}
func (o TemplateEntryMeta) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.Name != nil {
toSerialize["name"] = o.Name
}
return json.Marshal(toSerialize)
}
type NullableTemplateEntryMeta struct {
value *TemplateEntryMeta
isSet bool
}
func (v NullableTemplateEntryMeta) Get() *TemplateEntryMeta {
return v.value
}
func (v *NullableTemplateEntryMeta) Set(val *TemplateEntryMeta) {
v.value = val
v.isSet = true
}
func (v NullableTemplateEntryMeta) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateEntryMeta) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateEntryMeta(val *TemplateEntryMeta) *NullableTemplateEntryMeta {
return &NullableTemplateEntryMeta{value: val, isSet: true}
}
func (v NullableTemplateEntryMeta) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateEntryMeta) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,178 @@
/*
* 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 (
"encoding/json"
)
// TemplateExport struct for TemplateExport
type TemplateExport struct {
StackID *string `json:"stackID,omitempty"`
OrgIDs *[]TemplateExportOrgIDs `json:"orgIDs,omitempty"`
Resources []TemplateExportResources `json:"resources"`
}
// NewTemplateExport instantiates a new TemplateExport object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateExport(resources []TemplateExportResources) *TemplateExport {
this := TemplateExport{}
this.Resources = resources
return &this
}
// NewTemplateExportWithDefaults instantiates a new TemplateExport object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateExportWithDefaults() *TemplateExport {
this := TemplateExport{}
return &this
}
// GetStackID returns the StackID field value if set, zero value otherwise.
func (o *TemplateExport) GetStackID() string {
if o == nil || o.StackID == nil {
var ret string
return ret
}
return *o.StackID
}
// GetStackIDOk returns a tuple with the StackID field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExport) GetStackIDOk() (*string, bool) {
if o == nil || o.StackID == nil {
return nil, false
}
return o.StackID, true
}
// HasStackID returns a boolean if a field has been set.
func (o *TemplateExport) HasStackID() bool {
if o != nil && o.StackID != nil {
return true
}
return false
}
// SetStackID gets a reference to the given string and assigns it to the StackID field.
func (o *TemplateExport) SetStackID(v string) {
o.StackID = &v
}
// GetOrgIDs returns the OrgIDs field value if set, zero value otherwise.
func (o *TemplateExport) GetOrgIDs() []TemplateExportOrgIDs {
if o == nil || o.OrgIDs == nil {
var ret []TemplateExportOrgIDs
return ret
}
return *o.OrgIDs
}
// GetOrgIDsOk returns a tuple with the OrgIDs field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExport) GetOrgIDsOk() (*[]TemplateExportOrgIDs, bool) {
if o == nil || o.OrgIDs == nil {
return nil, false
}
return o.OrgIDs, true
}
// HasOrgIDs returns a boolean if a field has been set.
func (o *TemplateExport) HasOrgIDs() bool {
if o != nil && o.OrgIDs != nil {
return true
}
return false
}
// SetOrgIDs gets a reference to the given []TemplateExportOrgIDs and assigns it to the OrgIDs field.
func (o *TemplateExport) SetOrgIDs(v []TemplateExportOrgIDs) {
o.OrgIDs = &v
}
// GetResources returns the Resources field value
func (o *TemplateExport) GetResources() []TemplateExportResources {
if o == nil {
var ret []TemplateExportResources
return ret
}
return o.Resources
}
// GetResourcesOk returns a tuple with the Resources field value
// and a boolean to check if the value has been set.
func (o *TemplateExport) GetResourcesOk() (*[]TemplateExportResources, bool) {
if o == nil {
return nil, false
}
return &o.Resources, true
}
// SetResources sets field value
func (o *TemplateExport) SetResources(v []TemplateExportResources) {
o.Resources = v
}
func (o TemplateExport) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.StackID != nil {
toSerialize["stackID"] = o.StackID
}
if o.OrgIDs != nil {
toSerialize["orgIDs"] = o.OrgIDs
}
if true {
toSerialize["resources"] = o.Resources
}
return json.Marshal(toSerialize)
}
type NullableTemplateExport struct {
value *TemplateExport
isSet bool
}
func (v NullableTemplateExport) Get() *TemplateExport {
return v.value
}
func (v *NullableTemplateExport) Set(val *TemplateExport) {
v.value = val
v.isSet = true
}
func (v NullableTemplateExport) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateExport) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateExport(val *TemplateExport) *NullableTemplateExport {
return &NullableTemplateExport{value: val, isSet: true}
}
func (v NullableTemplateExport) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateExport) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,149 @@
/*
* 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 (
"encoding/json"
)
// TemplateExportOrgIDs struct for TemplateExportOrgIDs
type TemplateExportOrgIDs struct {
OrgID *string `json:"orgID,omitempty"`
ResourceFilters *TemplateExportResourceFilters `json:"resourceFilters,omitempty"`
}
// NewTemplateExportOrgIDs instantiates a new TemplateExportOrgIDs object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateExportOrgIDs() *TemplateExportOrgIDs {
this := TemplateExportOrgIDs{}
return &this
}
// NewTemplateExportOrgIDsWithDefaults instantiates a new TemplateExportOrgIDs object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateExportOrgIDsWithDefaults() *TemplateExportOrgIDs {
this := TemplateExportOrgIDs{}
return &this
}
// GetOrgID returns the OrgID field value if set, zero value otherwise.
func (o *TemplateExportOrgIDs) GetOrgID() string {
if o == nil || o.OrgID == nil {
var ret string
return ret
}
return *o.OrgID
}
// GetOrgIDOk returns a tuple with the OrgID field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportOrgIDs) GetOrgIDOk() (*string, bool) {
if o == nil || o.OrgID == nil {
return nil, false
}
return o.OrgID, true
}
// HasOrgID returns a boolean if a field has been set.
func (o *TemplateExportOrgIDs) HasOrgID() bool {
if o != nil && o.OrgID != nil {
return true
}
return false
}
// SetOrgID gets a reference to the given string and assigns it to the OrgID field.
func (o *TemplateExportOrgIDs) SetOrgID(v string) {
o.OrgID = &v
}
// GetResourceFilters returns the ResourceFilters field value if set, zero value otherwise.
func (o *TemplateExportOrgIDs) GetResourceFilters() TemplateExportResourceFilters {
if o == nil || o.ResourceFilters == nil {
var ret TemplateExportResourceFilters
return ret
}
return *o.ResourceFilters
}
// GetResourceFiltersOk returns a tuple with the ResourceFilters field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportOrgIDs) GetResourceFiltersOk() (*TemplateExportResourceFilters, bool) {
if o == nil || o.ResourceFilters == nil {
return nil, false
}
return o.ResourceFilters, true
}
// HasResourceFilters returns a boolean if a field has been set.
func (o *TemplateExportOrgIDs) HasResourceFilters() bool {
if o != nil && o.ResourceFilters != nil {
return true
}
return false
}
// SetResourceFilters gets a reference to the given TemplateExportResourceFilters and assigns it to the ResourceFilters field.
func (o *TemplateExportOrgIDs) SetResourceFilters(v TemplateExportResourceFilters) {
o.ResourceFilters = &v
}
func (o TemplateExportOrgIDs) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.OrgID != nil {
toSerialize["orgID"] = o.OrgID
}
if o.ResourceFilters != nil {
toSerialize["resourceFilters"] = o.ResourceFilters
}
return json.Marshal(toSerialize)
}
type NullableTemplateExportOrgIDs struct {
value *TemplateExportOrgIDs
isSet bool
}
func (v NullableTemplateExportOrgIDs) Get() *TemplateExportOrgIDs {
return v.value
}
func (v *NullableTemplateExportOrgIDs) Set(val *TemplateExportOrgIDs) {
v.value = val
v.isSet = true
}
func (v NullableTemplateExportOrgIDs) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateExportOrgIDs) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateExportOrgIDs(val *TemplateExportOrgIDs) *NullableTemplateExportOrgIDs {
return &NullableTemplateExportOrgIDs{value: val, isSet: true}
}
func (v NullableTemplateExportOrgIDs) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateExportOrgIDs) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,149 @@
/*
* 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 (
"encoding/json"
)
// TemplateExportResourceFilters struct for TemplateExportResourceFilters
type TemplateExportResourceFilters struct {
ByLabel *[]string `json:"byLabel,omitempty"`
ByResourceKind *[]TemplateKind `json:"byResourceKind,omitempty"`
}
// NewTemplateExportResourceFilters instantiates a new TemplateExportResourceFilters object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateExportResourceFilters() *TemplateExportResourceFilters {
this := TemplateExportResourceFilters{}
return &this
}
// NewTemplateExportResourceFiltersWithDefaults instantiates a new TemplateExportResourceFilters object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateExportResourceFiltersWithDefaults() *TemplateExportResourceFilters {
this := TemplateExportResourceFilters{}
return &this
}
// GetByLabel returns the ByLabel field value if set, zero value otherwise.
func (o *TemplateExportResourceFilters) GetByLabel() []string {
if o == nil || o.ByLabel == nil {
var ret []string
return ret
}
return *o.ByLabel
}
// GetByLabelOk returns a tuple with the ByLabel field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportResourceFilters) GetByLabelOk() (*[]string, bool) {
if o == nil || o.ByLabel == nil {
return nil, false
}
return o.ByLabel, true
}
// HasByLabel returns a boolean if a field has been set.
func (o *TemplateExportResourceFilters) HasByLabel() bool {
if o != nil && o.ByLabel != nil {
return true
}
return false
}
// SetByLabel gets a reference to the given []string and assigns it to the ByLabel field.
func (o *TemplateExportResourceFilters) SetByLabel(v []string) {
o.ByLabel = &v
}
// GetByResourceKind returns the ByResourceKind field value if set, zero value otherwise.
func (o *TemplateExportResourceFilters) GetByResourceKind() []TemplateKind {
if o == nil || o.ByResourceKind == nil {
var ret []TemplateKind
return ret
}
return *o.ByResourceKind
}
// GetByResourceKindOk returns a tuple with the ByResourceKind field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportResourceFilters) GetByResourceKindOk() (*[]TemplateKind, bool) {
if o == nil || o.ByResourceKind == nil {
return nil, false
}
return o.ByResourceKind, true
}
// HasByResourceKind returns a boolean if a field has been set.
func (o *TemplateExportResourceFilters) HasByResourceKind() bool {
if o != nil && o.ByResourceKind != nil {
return true
}
return false
}
// SetByResourceKind gets a reference to the given []TemplateKind and assigns it to the ByResourceKind field.
func (o *TemplateExportResourceFilters) SetByResourceKind(v []TemplateKind) {
o.ByResourceKind = &v
}
func (o TemplateExportResourceFilters) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.ByLabel != nil {
toSerialize["byLabel"] = o.ByLabel
}
if o.ByResourceKind != nil {
toSerialize["byResourceKind"] = o.ByResourceKind
}
return json.Marshal(toSerialize)
}
type NullableTemplateExportResourceFilters struct {
value *TemplateExportResourceFilters
isSet bool
}
func (v NullableTemplateExportResourceFilters) Get() *TemplateExportResourceFilters {
return v.value
}
func (v *NullableTemplateExportResourceFilters) Set(val *TemplateExportResourceFilters) {
v.value = val
v.isSet = true
}
func (v NullableTemplateExportResourceFilters) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateExportResourceFilters) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateExportResourceFilters(val *TemplateExportResourceFilters) *NullableTemplateExportResourceFilters {
return &NullableTemplateExportResourceFilters{value: val, isSet: true}
}
func (v NullableTemplateExportResourceFilters) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateExportResourceFilters) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,178 @@
/*
* 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 (
"encoding/json"
)
// TemplateExportResources struct for TemplateExportResources
type TemplateExportResources struct {
Id *string `json:"id,omitempty"`
Kind TemplateKind `json:"kind"`
Name *string `json:"name,omitempty"`
}
// NewTemplateExportResources instantiates a new TemplateExportResources object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewTemplateExportResources(kind TemplateKind) *TemplateExportResources {
this := TemplateExportResources{}
this.Kind = kind
return &this
}
// NewTemplateExportResourcesWithDefaults instantiates a new TemplateExportResources object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewTemplateExportResourcesWithDefaults() *TemplateExportResources {
this := TemplateExportResources{}
return &this
}
// GetId returns the Id field value if set, zero value otherwise.
func (o *TemplateExportResources) GetId() string {
if o == nil || o.Id == nil {
var ret string
return ret
}
return *o.Id
}
// GetIdOk returns a tuple with the Id field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportResources) GetIdOk() (*string, bool) {
if o == nil || o.Id == nil {
return nil, false
}
return o.Id, true
}
// HasId returns a boolean if a field has been set.
func (o *TemplateExportResources) HasId() bool {
if o != nil && o.Id != nil {
return true
}
return false
}
// SetId gets a reference to the given string and assigns it to the Id field.
func (o *TemplateExportResources) SetId(v string) {
o.Id = &v
}
// GetKind returns the Kind field value
func (o *TemplateExportResources) GetKind() TemplateKind {
if o == nil {
var ret TemplateKind
return ret
}
return o.Kind
}
// GetKindOk returns a tuple with the Kind field value
// and a boolean to check if the value has been set.
func (o *TemplateExportResources) GetKindOk() (*TemplateKind, bool) {
if o == nil {
return nil, false
}
return &o.Kind, true
}
// SetKind sets field value
func (o *TemplateExportResources) SetKind(v TemplateKind) {
o.Kind = v
}
// GetName returns the Name field value if set, zero value otherwise.
func (o *TemplateExportResources) GetName() string {
if o == nil || o.Name == nil {
var ret string
return ret
}
return *o.Name
}
// GetNameOk returns a tuple with the Name field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *TemplateExportResources) GetNameOk() (*string, bool) {
if o == nil || o.Name == nil {
return nil, false
}
return o.Name, true
}
// HasName returns a boolean if a field has been set.
func (o *TemplateExportResources) HasName() bool {
if o != nil && o.Name != nil {
return true
}
return false
}
// SetName gets a reference to the given string and assigns it to the Name field.
func (o *TemplateExportResources) SetName(v string) {
o.Name = &v
}
func (o TemplateExportResources) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
if o.Id != nil {
toSerialize["id"] = o.Id
}
if true {
toSerialize["kind"] = o.Kind
}
if o.Name != nil {
toSerialize["name"] = o.Name
}
return json.Marshal(toSerialize)
}
type NullableTemplateExportResources struct {
value *TemplateExportResources
isSet bool
}
func (v NullableTemplateExportResources) Get() *TemplateExportResources {
return v.value
}
func (v *NullableTemplateExportResources) Set(val *TemplateExportResources) {
v.value = val
v.isSet = true
}
func (v NullableTemplateExportResources) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateExportResources) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateExportResources(val *TemplateExportResources) *NullableTemplateExportResources {
return &NullableTemplateExportResources{value: val, isSet: true}
}
func (v NullableTemplateExportResources) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateExportResources) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -0,0 +1,95 @@
/*
* 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 (
"encoding/json"
"fmt"
)
// TemplateKind the model 'TemplateKind'
type TemplateKind string
// List of TemplateKind
const (
TEMPLATEKIND_BUCKET TemplateKind = "Bucket"
TEMPLATEKIND_CHECK TemplateKind = "Check"
TEMPLATEKIND_CHECK_DEADMAN TemplateKind = "CheckDeadman"
TEMPLATEKIND_CHECK_THRESHOLD TemplateKind = "CheckThreshold"
TEMPLATEKIND_DASHBOARD TemplateKind = "Dashboard"
TEMPLATEKIND_LABEL TemplateKind = "Label"
TEMPLATEKIND_NOTIFICATION_ENDPOINT TemplateKind = "NotificationEndpoint"
TEMPLATEKIND_NOTIFICATION_ENDPOINT_HTTP TemplateKind = "NotificationEndpointHTTP"
TEMPLATEKIND_NOTIFICATION_ENDPOINT_PAGER_DUTY TemplateKind = "NotificationEndpointPagerDuty"
TEMPLATEKIND_NOTIFICATION_ENDPOINT_SLACK TemplateKind = "NotificationEndpointSlack"
TEMPLATEKIND_NOTIFICATION_RULE TemplateKind = "NotificationRule"
TEMPLATEKIND_TASK TemplateKind = "Task"
TEMPLATEKIND_TELEGRAF TemplateKind = "Telegraf"
TEMPLATEKIND_VARIABLE TemplateKind = "Variable"
)
func (v *TemplateKind) UnmarshalJSON(src []byte) error {
var value string
err := json.Unmarshal(src, &value)
if err != nil {
return err
}
enumTypeValue := TemplateKind(value)
for _, existing := range []TemplateKind{"Bucket", "Check", "CheckDeadman", "CheckThreshold", "Dashboard", "Label", "NotificationEndpoint", "NotificationEndpointHTTP", "NotificationEndpointPagerDuty", "NotificationEndpointSlack", "NotificationRule", "Task", "Telegraf", "Variable"} {
if existing == enumTypeValue {
*v = enumTypeValue
return nil
}
}
return fmt.Errorf("%+v is not a valid TemplateKind", value)
}
// Ptr returns reference to TemplateKind value
func (v TemplateKind) Ptr() *TemplateKind {
return &v
}
type NullableTemplateKind struct {
value *TemplateKind
isSet bool
}
func (v NullableTemplateKind) Get() *TemplateKind {
return v.value
}
func (v *NullableTemplateKind) Set(val *TemplateKind) {
v.value = val
v.isSet = true
}
func (v NullableTemplateKind) IsSet() bool {
return v.isSet
}
func (v *NullableTemplateKind) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableTemplateKind(val *TemplateKind) *NullableTemplateKind {
return &NullableTemplateKind{value: val, isSet: true}
}
func (v NullableTemplateKind) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableTemplateKind) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

154
clients/export/export.go Normal file
View File

@ -0,0 +1,154 @@
package export
import (
"context"
"encoding/json"
"fmt"
"io"
"github.com/influxdata/influx-cli/v2/api"
"github.com/influxdata/influx-cli/v2/clients"
"gopkg.in/yaml.v3"
)
type OutEncoding int
const (
YamlEncoding OutEncoding = iota
JsonEncoding
)
type Client struct {
clients.CLI
api.TemplatesApi
}
type Params struct {
Out io.Writer
OutEncoding
StackId string
BucketIds []string
BucketNames []string
CheckIds []string
CheckNames []string
DashboardIds []string
DashboardNames []string
EndpointIds []string
EndpointNames []string
LabelIds []string
LabelNames []string
RuleIds []string
RuleNames []string
TaskIds []string
TaskNames []string
TelegrafIds []string
TelegrafNames []string
VariableIds []string
VariableNames []string
}
func (c Client) Export(ctx context.Context, params *Params) error {
var exportReq api.TemplateExport
if params.StackId != "" {
exportReq.StackID = &params.StackId
}
filters := []struct {
kind api.TemplateKind
ids []string
names []string
}{
{
kind: api.TEMPLATEKIND_BUCKET,
ids: params.BucketIds,
names: params.BucketNames,
},
{
kind: api.TEMPLATEKIND_CHECK,
ids: params.CheckIds,
names: params.CheckNames,
},
{
kind: api.TEMPLATEKIND_DASHBOARD,
ids: params.DashboardIds,
names: params.DashboardNames,
},
{
kind: api.TEMPLATEKIND_LABEL,
ids: params.LabelIds,
names: params.LabelNames,
},
{
kind: api.TEMPLATEKIND_NOTIFICATION_ENDPOINT,
ids: params.EndpointIds,
names: params.EndpointNames,
},
{
kind: api.TEMPLATEKIND_NOTIFICATION_RULE,
ids: params.RuleIds,
names: params.RuleNames,
},
{
kind: api.TEMPLATEKIND_TASK,
ids: params.TaskIds,
names: params.TaskNames,
},
{
kind: api.TEMPLATEKIND_TELEGRAF,
ids: params.TelegrafIds,
names: params.TelegrafNames,
},
{
kind: api.TEMPLATEKIND_VARIABLE,
ids: params.VariableIds,
names: params.VariableNames,
},
}
for _, filter := range filters {
for _, id := range filter.ids {
id := id
exportReq.Resources = append(exportReq.Resources, api.TemplateExportResources{
Kind: filter.kind,
Id: &id,
})
}
for _, name := range filter.names {
name := name
exportReq.Resources = append(exportReq.Resources, api.TemplateExportResources{
Kind: filter.kind,
Name: &name,
})
}
}
tmpl, err := c.ExportTemplate(ctx).TemplateExport(exportReq).Execute()
if err != nil {
return fmt.Errorf("failed to export template: %w", err)
}
if err := writeTemplate(params.Out, params.OutEncoding, tmpl); err != nil {
return fmt.Errorf("failed to write exported template: %w", err)
}
return nil
}
func writeTemplate(out io.Writer, encoding OutEncoding, template []api.TemplateEntry) error {
switch encoding {
case JsonEncoding:
enc := json.NewEncoder(out)
enc.SetIndent("", "\t")
return enc.Encode(template)
case YamlEncoding:
enc := yaml.NewEncoder(out)
for _, entry := range template {
if err := enc.Encode(entry); err != nil {
return err
}
}
default:
return fmt.Errorf("encoding %q is not recognized", encoding)
}
return nil
}

379
cmd/influx/export.go Normal file
View File

@ -0,0 +1,379 @@
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/influxdata/influx-cli/v2/clients/export"
"github.com/influxdata/influx-cli/v2/pkg/cli/middleware"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
)
func newExportCmd() *cli.Command {
var params struct {
out string
stackId string
resourceType ResourceType
bucketIds string
bucketNames string
checkIds string
checkNames string
dashboardIds string
dashboardNames string
endpointIds string
endpointNames string
labelIds string
labelNames string
ruleIds string
ruleNames string
taskIds string
taskNames string
telegrafIds string
telegrafNames string
variableIds string
variableNames string
}
return &cli.Command{
Name: "export",
Usage: "Export existing resources as a template",
Description: `The export command provides a mechanism to export existing resources to a
template. Each template resource kind is supported via flags.
Examples:
# export buckets by ID
influx export --buckets=$ID1,$ID2,$ID3
# export buckets, labels, and dashboards by ID
influx export \
--buckets=$BID1,$BID2,$BID3 \
--labels=$LID1,$LID2,$LID3 \
--dashboards=$DID1,$DID2,$DID3
# export all resources for a stack
influx export --stack-id $STACK_ID
# export a stack with resources not associated with the stack
influx export --stack-id $STACK_ID --buckets $BUCKET_ID
All of the resources are supported via the examples provided above. Provide the
resource flag and then provide the IDs.
For information about exporting InfluxDB templates, see
https://docs.influxdata.com/influxdb/latest/reference/cli/influx/export/`,
Flags: append(
commonFlagsNoPrint(),
&cli.StringFlag{
Name: "file",
Usage: "Output file for created template; defaults to std out if no file provided; the extension of provided file (.yml/.json) will dictate encoding",
Aliases: []string{"f"},
Destination: &params.out,
},
&cli.StringFlag{
Name: "stack-id",
Usage: "ID for stack to include in export",
Destination: &params.stackId,
},
&cli.GenericFlag{
Name: "resource-type",
Usage: "If specified, strings on stdin/positional args will be treated as IDs of the given type",
Value: &params.resourceType,
},
&cli.StringFlag{
Name: "buckets",
Usage: "List of bucket ids comma separated",
Destination: &params.bucketIds,
},
&cli.StringFlag{
Name: "checks",
Usage: "List of check ids comma separated",
Destination: &params.checkIds,
},
&cli.StringFlag{
Name: "dashboards",
Usage: "List of dashboard ids comma separated",
Destination: &params.dashboardIds,
},
&cli.StringFlag{
Name: "endpoints",
Usage: "List of notification endpoint ids comma separated",
Destination: &params.endpointIds,
},
&cli.StringFlag{
Name: "labels",
Usage: "List of label ids comma separated",
Destination: &params.labelIds,
},
&cli.StringFlag{
Name: "rules",
Usage: "List of notification rule ids comma separated",
Destination: &params.ruleIds,
},
&cli.StringFlag{
Name: "tasks",
Usage: "List of task ids comma separated",
Destination: &params.taskIds,
},
&cli.StringFlag{
Name: "telegraf-configs",
Usage: "List of telegraf config ids comma separated",
Destination: &params.telegrafIds,
},
&cli.StringFlag{
Name: "variables",
Usage: "List of variable ids comma separated",
Destination: &params.variableIds,
},
&cli.StringFlag{
Name: "bucket-names",
Usage: "List of bucket names comma separated",
Destination: &params.bucketNames,
},
&cli.StringFlag{
Name: "check-names",
Usage: "List of check names comma separated",
Destination: &params.checkNames,
},
&cli.StringFlag{
Name: "dashboard-names",
Usage: "List of dashboard names comma separated",
Destination: &params.dashboardNames,
},
&cli.StringFlag{
Name: "endpoint-names",
Usage: "List of notification endpoint names comma separated",
Destination: &params.endpointNames,
},
&cli.StringFlag{
Name: "label-names",
Usage: "List of label names comma separated",
Destination: &params.labelNames,
},
&cli.StringFlag{
Name: "rule-names",
Usage: "List of notification rule names comma separated",
Destination: &params.ruleNames,
},
&cli.StringFlag{
Name: "task-names",
Usage: "List of task names comma separated",
Destination: &params.taskNames,
},
&cli.StringFlag{
Name: "telegraf-config-names",
Usage: "List of telegraf config names comma separated",
Destination: &params.telegrafNames,
},
&cli.StringFlag{
Name: "variable-names",
Usage: "List of variable names comma separated",
Destination: &params.variableNames,
},
),
ArgsUsage: "[resource-id]...",
Before: middleware.WithBeforeFns(withCli(), withApi(true)),
Action: func(ctx *cli.Context) error {
parsedParams := export.Params{
StackId: params.stackId,
BucketIds: splitNonEmpty(params.bucketIds),
BucketNames: splitNonEmpty(params.bucketNames),
CheckIds: splitNonEmpty(params.checkIds),
CheckNames: splitNonEmpty(params.checkNames),
DashboardIds: splitNonEmpty(params.dashboardIds),
DashboardNames: splitNonEmpty(params.dashboardNames),
EndpointIds: splitNonEmpty(params.endpointIds),
EndpointNames: splitNonEmpty(params.endpointNames),
LabelIds: splitNonEmpty(params.labelIds),
LabelNames: splitNonEmpty(params.labelNames),
RuleIds: splitNonEmpty(params.ruleIds),
RuleNames: splitNonEmpty(params.ruleNames),
TaskIds: splitNonEmpty(params.taskIds),
TaskNames: splitNonEmpty(params.taskNames),
TelegrafIds: splitNonEmpty(params.telegrafIds),
TelegrafNames: splitNonEmpty(params.telegrafNames),
VariableIds: splitNonEmpty(params.variableIds),
VariableNames: splitNonEmpty(params.variableNames),
}
if params.out == "" {
parsedParams.Out = os.Stdout
} else {
f, err := os.OpenFile(params.out, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("failed to open output path %q: %w", params.out, err)
}
defer f.Close()
parsedParams.Out = f
}
switch filepath.Ext(params.out) {
case ".json":
parsedParams.OutEncoding = export.JsonEncoding
default: // Also covers path == "" for stdout.
parsedParams.OutEncoding = export.YamlEncoding
}
if params.resourceType != TypeUnset {
ids := ctx.Args().Slice()
// Read any IDs from stdin.
// !IsTerminal detects when some other process is piping into this command.
if !isatty.IsTerminal(os.Stdin.Fd()) {
inBytes, err := io.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("failed to read args from std in: %w", err)
}
ids = append(ids, strings.Fields(string(inBytes))...)
}
switch params.resourceType {
case TypeBucket:
parsedParams.BucketIds = append(parsedParams.BucketIds, ids...)
case TypeCheck:
parsedParams.CheckIds = append(parsedParams.CheckIds, ids...)
case TypeDashboard:
parsedParams.DashboardIds = append(parsedParams.DashboardIds, ids...)
case TypeLabel:
parsedParams.LabelIds = append(parsedParams.LabelIds, ids...)
case TypeNotificationEndpoint:
parsedParams.EndpointIds = append(parsedParams.EndpointIds, ids...)
case TypeNotificationRule:
parsedParams.RuleIds = append(parsedParams.RuleIds, ids...)
case TypeTask:
parsedParams.TaskIds = append(parsedParams.TaskIds, ids...)
case TypeTelegraf:
parsedParams.TelegrafIds = append(parsedParams.TelegrafIds, ids...)
case TypeVariable:
parsedParams.VariableIds = append(parsedParams.VariableIds, ids...)
// NOTE: The API doesn't support filtering by these resource subtypes,
// and instead converts them to the parent type. For example,
// `--resource-type notificationEndpointHTTP` gets translated to a filter
// on all notification endpoints on the server-side. I think this was
// intentional since the 2.0.x CLI didn't expose flags to filter on subtypes,
// but a bug/oversight in its parsing still allowed the subtypes through
// when passing IDs over stdin.
// Instead of allowing the type-filter to be silently converted by the server,
// we catch the previously-allowed subtypes here and return a (hopefully) useful
// error suggesting the correct flag to use.
case TypeCheckDeadman, TypeCheckThreshold:
return fmt.Errorf("filtering on resource-type %q is not supported by the API. Use resource-type %q instead", params.resourceType, TypeCheck)
case TypeNotificationEndpointHTTP, TypeNotificationEndpointPagerDuty, TypeNotificationEndpointSlack:
return fmt.Errorf("filtering on resource-type %q is not supported by the API. Use resource-type %q instead", params.resourceType, TypeNotificationEndpoint)
default:
}
} else if ctx.NArg() > 0 {
return fmt.Errorf("must specify --resource-type when passing IDs as args")
}
client := export.Client{
CLI: getCLI(ctx),
TemplatesApi: getAPI(ctx).TemplatesApi,
}
return client.Export(ctx.Context, &parsedParams)
},
}
}
func splitNonEmpty(s string) []string {
if s == "" {
return nil
}
return strings.Split(s, ",")
}
type ResourceType int
const (
TypeUnset ResourceType = iota
TypeBucket
TypeCheck
TypeCheckDeadman
TypeCheckThreshold
TypeDashboard
TypeLabel
TypeNotificationEndpoint
TypeNotificationEndpointHTTP
TypeNotificationEndpointPagerDuty
TypeNotificationEndpointSlack
TypeNotificationRule
TypeTask
TypeTelegraf
TypeVariable
)
func (r ResourceType) String() string {
switch r {
case TypeBucket:
return "bucket"
case TypeCheck:
return "check"
case TypeCheckDeadman:
return "checkDeadman"
case TypeCheckThreshold:
return "checkThreshold"
case TypeDashboard:
return "dashboard"
case TypeLabel:
return "label"
case TypeNotificationEndpoint:
return "notificationEndpoint"
case TypeNotificationEndpointHTTP:
return "notificationEndpointHTTP"
case TypeNotificationEndpointPagerDuty:
return "notificationEndpointPagerDuty"
case TypeNotificationEndpointSlack:
return "notificationEndpointSlack"
case TypeNotificationRule:
return "notificationRule"
case TypeTask:
return "task"
case TypeTelegraf:
return "telegraf"
case TypeVariable:
return "variable"
case TypeUnset:
fallthrough
default:
return "unset"
}
}
func (r *ResourceType) Set(v string) error {
switch strings.ToLower(v) {
case "bucket":
*r = TypeBucket
case "check":
*r = TypeCheck
case "checkdeadman":
*r = TypeCheckDeadman
case "checkthreshold":
*r = TypeCheckThreshold
case "dashboard":
*r = TypeDashboard
case "label":
*r = TypeLabel
case "notificationendpoint":
*r = TypeNotificationEndpoint
case "notificationendpointhttp":
*r = TypeNotificationEndpointHTTP
case "notificationendpointpagerduty":
*r = TypeNotificationEndpointPagerDuty
case "notificationendpointslack":
*r = TypeNotificationEndpointSlack
case "notificationrule":
*r = TypeNotificationRule
case "task":
*r = TypeTask
case "telegraf":
*r = TypeTelegraf
case "variable":
*r = TypeVariable
default:
return fmt.Errorf("unknown resource type: %s", v)
}
return nil
}

View File

@ -48,6 +48,7 @@ var app = cli.App{
newRestoreCmd(),
newTelegrafsCommand(),
newDashboardsCommand(),
newExportCmd(),
},
}

2
go.mod
View File

@ -12,10 +12,12 @@ require (
github.com/golang/mock v1.5.0
github.com/google/go-cmp v0.5.5
github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.13
github.com/stretchr/testify v1.7.0
github.com/urfave/cli/v2 v2.3.0
golang.org/x/text v0.3.3
golang.org/x/tools v0.1.0
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
honnef.co/go/tools v0.1.3
)

4
go.sum
View File

@ -37,8 +37,9 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -71,6 +72,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=