From f21434a97177121bdf8c036ee493376e30104d07 Mon Sep 17 00:00:00 2001
From: Prakash Senthil Vel <23444145+prakashsvmx@users.noreply.github.com>
Date: Wed, 22 Feb 2023 01:20:04 +0530
Subject: [PATCH] Export import server config from settings page (#2664)
---
integration/admin_api_integration_test.go | 115 ++++++++++++---
integration/sample-import-config.txt | 28 ++++
models/config_export_response.go | 70 +++++++++
models/env_override.go | 2 +-
.../screens/Console/Common/Hooks/useApi.tsx | 4 +-
.../ConfigurationOptions.tsx | 14 ++
.../ExportConfigButton.tsx | 43 ++++++
.../ImportConfigButton.tsx | 91 ++++++++++++
restapi/admin_config.go | 55 +++++++
restapi/embedded_spec.go | 130 +++++++++++++++++
.../operations/configuration/export_config.go | 88 ++++++++++++
.../configuration/export_config_parameters.go | 63 ++++++++
.../configuration/export_config_responses.go | 135 ++++++++++++++++++
.../configuration/export_config_urlbuilder.go | 104 ++++++++++++++
.../configuration/post_configs_import.go | 88 ++++++++++++
.../post_configs_import_parameters.go | 103 +++++++++++++
.../post_configs_import_responses.go | 115 +++++++++++++++
.../post_configs_import_urlbuilder.go | 104 ++++++++++++++
restapi/operations/console_api.go | 24 ++++
swagger-console.yml | 43 ++++++
20 files changed, 1397 insertions(+), 22 deletions(-)
create mode 100644 integration/sample-import-config.txt
create mode 100644 models/config_export_response.go
create mode 100644 portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ExportConfigButton.tsx
create mode 100644 portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ImportConfigButton.tsx
create mode 100644 restapi/operations/configuration/export_config.go
create mode 100644 restapi/operations/configuration/export_config_parameters.go
create mode 100644 restapi/operations/configuration/export_config_responses.go
create mode 100644 restapi/operations/configuration/export_config_urlbuilder.go
create mode 100644 restapi/operations/configuration/post_configs_import.go
create mode 100644 restapi/operations/configuration/post_configs_import_parameters.go
create mode 100644 restapi/operations/configuration/post_configs_import_responses.go
create mode 100644 restapi/operations/configuration/post_configs_import_urlbuilder.go
diff --git a/integration/admin_api_integration_test.go b/integration/admin_api_integration_test.go
index 749bedc72..ee0a39e05 100644
--- a/integration/admin_api_integration_test.go
+++ b/integration/admin_api_integration_test.go
@@ -22,8 +22,12 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "io"
"log"
+ "mime/multipart"
"net/http"
+ "os"
+ "path"
"testing"
"time"
@@ -155,33 +159,33 @@ func NotifyPostgres() (*http.Response, error) {
func TestNotifyPostgres(t *testing.T) {
// Variables
- assert := assert.New(t)
+ asserter := assert.New(t)
// Test
response, err := NotifyPostgres()
finalResponse := inspectHTTPResponse(response)
- assert.Nil(err)
+ asserter.Nil(err)
if err != nil {
log.Println(err)
- assert.Fail(finalResponse)
+ asserter.Fail(finalResponse)
return
}
if response != nil {
- assert.Equal(200, response.StatusCode, finalResponse)
+ asserter.Equal(200, response.StatusCode, finalResponse)
}
}
func TestRestartService(t *testing.T) {
- assert := assert.New(t)
+ asserter := assert.New(t)
restartResponse, restartError := RestartService()
- assert.Nil(restartError)
+ asserter.Nil(restartError)
if restartError != nil {
log.Println(restartError)
return
}
addObjRsp := inspectHTTPResponse(restartResponse)
if restartResponse != nil {
- assert.Equal(
+ asserter.Equal(
204,
restartResponse.StatusCode,
addObjRsp,
@@ -212,18 +216,18 @@ func ListPoliciesWithBucket(bucketName string) (*http.Response, error) {
func TestListPoliciesWithBucket(t *testing.T) {
// Test Variables
bucketName := "testlistpolicieswithbucket"
- assert := assert.New(t)
+ asserter := assert.New(t)
// Test
response, err := ListPoliciesWithBucket(bucketName)
- assert.Nil(err)
+ asserter.Nil(err)
if err != nil {
log.Println(err)
return
}
parsedResponse := inspectHTTPResponse(response)
if response != nil {
- assert.Equal(
+ asserter.Equal(
200,
response.StatusCode,
parsedResponse,
@@ -254,18 +258,18 @@ func ListUsersWithAccessToBucket(bucketName string) (*http.Response, error) {
func TestListUsersWithAccessToBucket(t *testing.T) {
// Test Variables
bucketName := "testlistuserswithaccesstobucket1"
- assert := assert.New(t)
+ asserter := assert.New(t)
// Test
response, err := ListUsersWithAccessToBucket(bucketName)
- assert.Nil(err)
+ asserter.Nil(err)
if err != nil {
log.Println(err)
return
}
parsedResponse := inspectHTTPResponse(response)
if response != nil {
- assert.Equal(
+ asserter.Equal(
200,
response.StatusCode,
parsedResponse,
@@ -274,16 +278,16 @@ func TestListUsersWithAccessToBucket(t *testing.T) {
}
func TestGetNodes(t *testing.T) {
- assert := assert.New(t)
+ asserter := assert.New(t)
getNodesResponse, getNodesError := GetNodes()
- assert.Nil(getNodesError)
+ asserter.Nil(getNodesError)
if getNodesError != nil {
log.Println(getNodesError)
return
}
addObjRsp := inspectHTTPResponse(getNodesResponse)
if getNodesResponse != nil {
- assert.Equal(
+ asserter.Equal(
200,
getNodesResponse.StatusCode,
addObjRsp,
@@ -312,16 +316,89 @@ func ArnList() (*http.Response, error) {
}
func TestArnList(t *testing.T) {
- assert := assert.New(t)
+ asserter := assert.New(t)
resp, err := ArnList()
- assert.Nil(err)
+ asserter.Nil(err)
if err != nil {
log.Println(err)
return
}
objRsp := inspectHTTPResponse(resp)
if resp != nil {
- assert.Equal(
+ asserter.Equal(
+ 200,
+ resp.StatusCode,
+ objRsp,
+ )
+ }
+}
+
+func ExportConfig() (*http.Response, error) {
+ request, err := http.NewRequest(
+ "GET", "http://localhost:9090/api/v1/configs/export", nil)
+ if err != nil {
+ log.Println(err)
+ }
+ request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
+ client := &http.Client{
+ Timeout: 2 * time.Second,
+ }
+ response, err := client.Do(request)
+ return response, err
+}
+
+func ImportConfig() (*http.Response, error) {
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+ formFile, _ := writer.CreateFormFile("file", "sample-import-config.txt")
+ fileDir, _ := os.Getwd()
+ fileName := "sample-import-config.txt"
+ filePath := path.Join(fileDir, fileName)
+ file, _ := os.Open(filePath)
+ io.Copy(formFile, file)
+ writer.Close()
+ request, err := http.NewRequest(
+ "POST", "http://localhost:9090/api/v1/configs/import",
+ bytes.NewReader(body.Bytes()),
+ )
+ if err != nil {
+ log.Println(err)
+ }
+ request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
+ request.Header.Set("Content-Type", writer.FormDataContentType())
+
+ client := &http.Client{
+ Timeout: 2 * time.Second,
+ }
+
+ rsp, _ := client.Do(request)
+ if rsp.StatusCode != http.StatusOK {
+ log.Printf("Request failed with response code: %d", rsp.StatusCode)
+ }
+ return rsp, err
+}
+
+func TestExportConfig(t *testing.T) {
+ asserter := assert.New(t)
+ resp, err := ExportConfig()
+ asserter.Nil(err)
+ objRsp := inspectHTTPResponse(resp)
+ if resp != nil {
+ asserter.Equal(
+ 200,
+ resp.StatusCode,
+ objRsp,
+ )
+ }
+}
+
+func TestImportConfig(t *testing.T) {
+ asserter := assert.New(t)
+ resp, err := ImportConfig()
+ asserter.Nil(err)
+ objRsp := inspectHTTPResponse(resp)
+ if resp != nil {
+ asserter.Equal(
200,
resp.StatusCode,
objRsp,
diff --git a/integration/sample-import-config.txt b/integration/sample-import-config.txt
new file mode 100644
index 000000000..14ebd8632
--- /dev/null
+++ b/integration/sample-import-config.txt
@@ -0,0 +1,28 @@
+subnet license= api_key= proxy=
+# callhome enable=off frequency=24h
+# site name= region=
+# api requests_max=0 requests_deadline=10s cluster_deadline=10s cors_allow_origin=* remote_transport_deadline=2h list_quorum=strict replication_priority=auto transition_workers=100 stale_uploads_cleanup_interval=6h stale_uploads_expiry=24h delete_cleanup_interval=5m disable_odirect=off gzip_objects=off
+# scanner speed=default
+# compression enable=off allow_encryption=off extensions=.txt,.log,.csv,.json,.tar,.xml,.bin mime_types=text/*,application/json,application/xml,binary/octet-stream
+# identity_openid enable= display_name= config_url= client_id= client_secret= claim_name=policy claim_userinfo= role_policy= claim_prefix= redirect_uri= redirect_uri_dynamic=off scopes= vendor= keycloak_realm= keycloak_admin_url=
+# identity_ldap server_addr= srv_record_name= user_dn_search_base_dn= user_dn_search_filter= group_search_filter= group_search_base_dn= tls_skip_verify=off server_insecure=off server_starttls=off lookup_bind_dn= lookup_bind_password=
+# identity_tls skip_verify=off
+# identity_plugin url= auth_token= role_policy= role_id=
+# policy_plugin url= auth_token= enable_http2=off
+# logger_webhook enable=off endpoint= auth_token= client_cert= client_key= queue_size=100000
+# audit_webhook enable=off endpoint= auth_token= client_cert= client_key= queue_size=100000
+# audit_kafka enable=off topic= brokers= sasl_username= sasl_password= sasl_mechanism=plain client_tls_cert= client_tls_key= tls_client_auth=0 sasl=off tls=off tls_skip_verify=off version=
+# notify_webhook enable=off endpoint= auth_token= queue_limit=0 queue_dir= client_cert= client_key=
+# notify_amqp enable=off url= exchange= exchange_type= routing_key= mandatory=off durable=off no_wait=off internal=off auto_deleted=off delivery_mode=0 publisher_confirms=off queue_limit=0 queue_dir=
+# notify_kafka enable=off topic= brokers= sasl_username= sasl_password= sasl_mechanism=plain client_tls_cert= client_tls_key= tls_client_auth=0 sasl=off tls=off tls_skip_verify=off queue_limit=0 queue_dir= version=
+# notify_mqtt enable=off broker= topic= password= username= qos=0 keep_alive_interval=0s reconnect_interval=0s queue_dir= queue_limit=0
+# notify_nats enable=off address= subject= username= password= token= tls=off tls_skip_verify=off cert_authority= client_cert= client_key= ping_interval=0 jetstream=off streaming=off streaming_async=off streaming_max_pub_acks_in_flight=0 streaming_cluster_id= queue_dir= queue_limit=0
+# notify_nsq enable=off nsqd_address= topic= tls=off tls_skip_verify=off queue_dir= queue_limit=0
+# notify_mysql enable=off format=namespace dsn_string= table= queue_dir= queue_limit=0 max_open_connections=2
+# notify_postgres enable=off format=namespace connection_string= table= queue_dir= queue_limit=0 max_open_connections=2
+# notify_elasticsearch enable=off url= format=namespace index= queue_dir= queue_limit=0 username= password=
+# notify_redis enable=off format=namespace address= key= password= queue_dir= queue_limit=0
+# etcd endpoints= path_prefix= coredns_path=/skydns client_cert= client_cert_key=
+# cache drives= exclude= expiry=90 quota=80 after=0 watermark_low=70 watermark_high=80 range=on commit=
+# storage_class standard= rrs=EC:1
+# heal bitrotscan=off max_sleep=1s max_io=100
\ No newline at end of file
diff --git a/models/config_export_response.go b/models/config_export_response.go
new file mode 100644
index 000000000..41efdbeda
--- /dev/null
+++ b/models/config_export_response.go
@@ -0,0 +1,70 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "context"
+
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+)
+
+// ConfigExportResponse config export response
+//
+// swagger:model configExportResponse
+type ConfigExportResponse struct {
+
+ // status
+ Status string `json:"status,omitempty"`
+
+ // Returns base64 encoded value
+ Value string `json:"value,omitempty"`
+}
+
+// Validate validates this config export response
+func (m *ConfigExportResponse) Validate(formats strfmt.Registry) error {
+ return nil
+}
+
+// ContextValidate validates this config export response based on context it is used
+func (m *ConfigExportResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *ConfigExportResponse) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *ConfigExportResponse) UnmarshalBinary(b []byte) error {
+ var res ConfigExportResponse
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/models/env_override.go b/models/env_override.go
index 79cb2903c..6052361f9 100644
--- a/models/env_override.go
+++ b/models/env_override.go
@@ -1,7 +1,7 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
-// Copyright (c) 2022 MinIO, Inc.
+// Copyright (c) 2023 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/portal-ui/src/screens/Console/Common/Hooks/useApi.tsx b/portal-ui/src/screens/Console/Common/Hooks/useApi.tsx
index 1f7155c47..7d4fbcb34 100644
--- a/portal-ui/src/screens/Console/Common/Hooks/useApi.tsx
+++ b/portal-ui/src/screens/Console/Common/Hooks/useApi.tsx
@@ -12,10 +12,10 @@ const useApi = (
): [IsApiInProgress, ApiMethodToInvoke] => {
const [isLoading, setIsLoading] = useState(false);
- const callApi = (method: string, url: string, data?: any) => {
+ const callApi = (method: string, url: string, data?: any, headers?: any) => {
setIsLoading(true);
api
- .invoke(method, url, data)
+ .invoke(method, url, data, headers)
.then((res: any) => {
setIsLoading(false);
onSuccess(res);
diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx
index 5e7005f8f..b7d841f20 100644
--- a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx
+++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationOptions.tsx
@@ -34,6 +34,9 @@ import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
import ConfigurationForm from "./ConfigurationForm";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
+import ExportConfigButton from "./ExportConfigButton";
+import ImportConfigButton from "./ImportConfigButton";
+import { Box } from "@mui/material";
interface IConfigurationOptions {
classes: any;
@@ -78,6 +81,17 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
}
title={"MinIO Configuration:"}
+ actions={
+
+
+
+
+ }
/>
{
+ const dispatch = useDispatch();
+ const [isReqLoading, invokeApi] = useApi(
+ (res: any) => {
+ //base64 encoded information so decode before downloading.
+ performDownload(
+ new Blob([window.atob(res.value)]),
+ `minio-server-config-${DateTime.now().toFormat(
+ "LL-dd-yyyy-HH-mm-ss"
+ )}.conf`
+ );
+ },
+ (err) => {
+ dispatch(setErrorSnackMessage(err));
+ }
+ );
+
+ return (
+
+
+ );
+};
+
+export default ExportConfigButton;
diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ImportConfigButton.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ImportConfigButton.tsx
new file mode 100644
index 000000000..3ced85b87
--- /dev/null
+++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ImportConfigButton.tsx
@@ -0,0 +1,91 @@
+import React, { Fragment, useEffect, useRef, useState } from "react";
+import { Button, DownloadIcon } from "mds";
+import useApi from "../../Common/Hooks/useApi";
+import {
+ setErrorSnackMessage,
+ setServerNeedsRestart,
+} from "../../../../systemSlice";
+import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
+import { useDispatch, useSelector } from "react-redux";
+import { useNavigate } from "react-router-dom";
+import { AppState } from "../../../../store";
+
+const ImportConfigButton = () => {
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+
+ const needsRestart = useSelector(
+ (state: AppState) => state.system.serverNeedsRestart
+ );
+
+ const [refreshPage, setRefreshPage] = useState(
+ undefined
+ );
+ const fileUpload = useRef(null);
+
+ const [isReqLoading, invokeApi] = useApi(
+ (res: any) => {
+ //base64 encoded information so decode before downloading.
+ dispatch(setServerNeedsRestart(true)); //import should refreshPage as per mc.
+ setRefreshPage(true);
+ },
+ (err) => {
+ dispatch(setErrorSnackMessage(err));
+ }
+ );
+
+ useEffect(() => {
+ if (!needsRestart && refreshPage) {
+ navigate(0); // refresh the page.
+ }
+ }, [needsRestart, refreshPage, navigate]);
+
+ const handleUploadButton = (e: any) => {
+ if (
+ e === null ||
+ e === undefined ||
+ e.target.files === null ||
+ e.target.files === undefined
+ ) {
+ return;
+ }
+ e.preventDefault();
+ const [fileToUpload] = e.target.files;
+
+ const formData = new FormData();
+ const blobFile = new Blob([fileToUpload], { type: fileToUpload.type });
+
+ formData.append("file", blobFile, fileToUpload.name);
+ // @ts-ignore
+ invokeApi("POST", `api/v1/configs/import`, formData);
+
+ e.target.value = "";
+ };
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default ImportConfigButton;
diff --git a/restapi/admin_config.go b/restapi/admin_config.go
index 2ff077d67..38d84f0ac 100644
--- a/restapi/admin_config.go
+++ b/restapi/admin_config.go
@@ -18,6 +18,7 @@ package restapi
import (
"context"
+ "encoding/base64"
"fmt"
"strings"
@@ -63,6 +64,21 @@ func registerConfigHandlers(api *operations.ConsoleAPI) {
}
return cfgApi.NewResetConfigOK().WithPayload(resp)
})
+ // Export Configuration as base64 string.
+ api.ConfigurationExportConfigHandler = cfgApi.ExportConfigHandlerFunc(func(params cfgApi.ExportConfigParams, session *models.Principal) middleware.Responder {
+ resp, err := exportConfigResponse(session, params)
+ if err != nil {
+ return cfgApi.NewExportConfigDefault((int(err.Code))).WithPayload(err)
+ }
+ return cfgApi.NewExportConfigOK().WithPayload(resp)
+ })
+ api.ConfigurationPostConfigsImportHandler = cfgApi.PostConfigsImportHandlerFunc(func(params cfgApi.PostConfigsImportParams, session *models.Principal) middleware.Responder {
+ _, err := importConfigResponse(session, params)
+ if err != nil {
+ return cfgApi.NewPostConfigsImportDefault((int(err.Code))).WithPayload(err)
+ }
+ return cfgApi.NewPostConfigsImportDefault(200)
+ })
}
// listConfig gets all configurations' names and their descriptions
@@ -265,3 +281,42 @@ func resetConfigResponse(session *models.Principal, params cfgApi.ResetConfigPar
return &models.SetConfigResponse{Restart: true}, nil
}
+
+func exportConfigResponse(session *models.Principal, params cfgApi.ExportConfigParams) (*models.ConfigExportResponse, *models.Error) {
+ ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
+ defer cancel()
+
+ mAdmin, err := NewMinioAdminClient(session)
+ if err != nil {
+ return nil, ErrorWithContext(ctx, err)
+ }
+ configRes, err := mAdmin.GetConfig(ctx)
+ if err != nil {
+ return nil, ErrorWithContext(ctx, err)
+ }
+ // may contain sensitive information so unpack only when required.
+ return &models.ConfigExportResponse{
+ Status: "success",
+ Value: base64.StdEncoding.EncodeToString(configRes),
+ }, nil
+}
+
+func importConfigResponse(session *models.Principal, params cfgApi.PostConfigsImportParams) (*cfgApi.PostConfigsImportDefault, *models.Error) {
+ ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
+ defer cancel()
+ mAdmin, err := NewMinioAdminClient(session)
+ if err != nil {
+ return nil, ErrorWithContext(ctx, err)
+ }
+ file, _, err := params.HTTPRequest.FormFile("file")
+ defer file.Close()
+
+ if err != nil {
+ return nil, ErrorWithContext(ctx, err)
+ }
+ err = mAdmin.SetConfig(ctx, file)
+ if err != nil {
+ return nil, ErrorWithContext(ctx, err)
+ }
+ return &cfgApi.PostConfigsImportDefault{}, nil
+}
diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go
index 078033300..abd62f08d 100644
--- a/restapi/embedded_spec.go
+++ b/restapi/embedded_spec.go
@@ -2566,6 +2566,59 @@ func init() {
}
}
},
+ "/configs/export": {
+ "get": {
+ "tags": [
+ "Configuration"
+ ],
+ "summary": "Export the current config from MinIO server",
+ "operationId": "ExportConfig",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/configExportResponse"
+ }
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
+ "/configs/import": {
+ "post": {
+ "consumes": [
+ "multipart/form-data"
+ ],
+ "tags": [
+ "Configuration"
+ ],
+ "summary": "Uploads an Object.",
+ "parameters": [
+ {
+ "type": "file",
+ "name": "file",
+ "in": "formData",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "A successful response."
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
"/configs/{name}": {
"get": {
"tags": [
@@ -5942,6 +5995,18 @@ func init() {
}
}
},
+ "configExportResponse": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "value": {
+ "description": "Returns base64 encoded value",
+ "type": "string"
+ }
+ }
+ },
"configuration": {
"type": "object",
"properties": {
@@ -11336,6 +11401,59 @@ func init() {
}
}
},
+ "/configs/export": {
+ "get": {
+ "tags": [
+ "Configuration"
+ ],
+ "summary": "Export the current config from MinIO server",
+ "operationId": "ExportConfig",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/configExportResponse"
+ }
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
+ "/configs/import": {
+ "post": {
+ "consumes": [
+ "multipart/form-data"
+ ],
+ "tags": [
+ "Configuration"
+ ],
+ "summary": "Uploads an Object.",
+ "parameters": [
+ {
+ "type": "file",
+ "name": "file",
+ "in": "formData",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "A successful response."
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
"/configs/{name}": {
"get": {
"tags": [
@@ -14838,6 +14956,18 @@ func init() {
}
}
},
+ "configExportResponse": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ },
+ "value": {
+ "description": "Returns base64 encoded value",
+ "type": "string"
+ }
+ }
+ },
"configuration": {
"type": "object",
"properties": {
diff --git a/restapi/operations/configuration/export_config.go b/restapi/operations/configuration/export_config.go
new file mode 100644
index 000000000..d9c57613a
--- /dev/null
+++ b/restapi/operations/configuration/export_config.go
@@ -0,0 +1,88 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+ "net/http"
+
+ "github.com/go-openapi/runtime/middleware"
+
+ "github.com/minio/console/models"
+)
+
+// ExportConfigHandlerFunc turns a function with the right signature into a export config handler
+type ExportConfigHandlerFunc func(ExportConfigParams, *models.Principal) middleware.Responder
+
+// Handle executing the request and returning a response
+func (fn ExportConfigHandlerFunc) Handle(params ExportConfigParams, principal *models.Principal) middleware.Responder {
+ return fn(params, principal)
+}
+
+// ExportConfigHandler interface for that can handle valid export config params
+type ExportConfigHandler interface {
+ Handle(ExportConfigParams, *models.Principal) middleware.Responder
+}
+
+// NewExportConfig creates a new http.Handler for the export config operation
+func NewExportConfig(ctx *middleware.Context, handler ExportConfigHandler) *ExportConfig {
+ return &ExportConfig{Context: ctx, Handler: handler}
+}
+
+/*
+ ExportConfig swagger:route GET /configs/export Configuration exportConfig
+
+Export the current config from MinIO server
+*/
+type ExportConfig struct {
+ Context *middleware.Context
+ Handler ExportConfigHandler
+}
+
+func (o *ExportConfig) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+ route, rCtx, _ := o.Context.RouteInfo(r)
+ if rCtx != nil {
+ *r = *rCtx
+ }
+ var Params = NewExportConfigParams()
+ uprinc, aCtx, err := o.Context.Authorize(r, route)
+ if err != nil {
+ o.Context.Respond(rw, r, route.Produces, route, err)
+ return
+ }
+ if aCtx != nil {
+ *r = *aCtx
+ }
+ var principal *models.Principal
+ if uprinc != nil {
+ principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
+ }
+
+ if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
+ o.Context.Respond(rw, r, route.Produces, route, err)
+ return
+ }
+
+ res := o.Handler.Handle(Params, principal) // actually handle the request
+ o.Context.Respond(rw, r, route.Produces, route, res)
+
+}
diff --git a/restapi/operations/configuration/export_config_parameters.go b/restapi/operations/configuration/export_config_parameters.go
new file mode 100644
index 000000000..a8ed0781d
--- /dev/null
+++ b/restapi/operations/configuration/export_config_parameters.go
@@ -0,0 +1,63 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "net/http"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/runtime/middleware"
+)
+
+// NewExportConfigParams creates a new ExportConfigParams object
+//
+// There are no default values defined in the spec.
+func NewExportConfigParams() ExportConfigParams {
+
+ return ExportConfigParams{}
+}
+
+// ExportConfigParams contains all the bound params for the export config operation
+// typically these are obtained from a http.Request
+//
+// swagger:parameters ExportConfig
+type ExportConfigParams struct {
+
+ // HTTP Request Object
+ HTTPRequest *http.Request `json:"-"`
+}
+
+// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
+// for simple values it will use straight method calls.
+//
+// To ensure default values, the struct must have been initialized with NewExportConfigParams() beforehand.
+func (o *ExportConfigParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
+ var res []error
+
+ o.HTTPRequest = r
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
diff --git a/restapi/operations/configuration/export_config_responses.go b/restapi/operations/configuration/export_config_responses.go
new file mode 100644
index 000000000..5651bd448
--- /dev/null
+++ b/restapi/operations/configuration/export_config_responses.go
@@ -0,0 +1,135 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "net/http"
+
+ "github.com/go-openapi/runtime"
+
+ "github.com/minio/console/models"
+)
+
+// ExportConfigOKCode is the HTTP code returned for type ExportConfigOK
+const ExportConfigOKCode int = 200
+
+/*
+ExportConfigOK A successful response.
+
+swagger:response exportConfigOK
+*/
+type ExportConfigOK struct {
+
+ /*
+ In: Body
+ */
+ Payload *models.ConfigExportResponse `json:"body,omitempty"`
+}
+
+// NewExportConfigOK creates ExportConfigOK with default headers values
+func NewExportConfigOK() *ExportConfigOK {
+
+ return &ExportConfigOK{}
+}
+
+// WithPayload adds the payload to the export config o k response
+func (o *ExportConfigOK) WithPayload(payload *models.ConfigExportResponse) *ExportConfigOK {
+ o.Payload = payload
+ return o
+}
+
+// SetPayload sets the payload to the export config o k response
+func (o *ExportConfigOK) SetPayload(payload *models.ConfigExportResponse) {
+ o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *ExportConfigOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+ rw.WriteHeader(200)
+ if o.Payload != nil {
+ payload := o.Payload
+ if err := producer.Produce(rw, payload); err != nil {
+ panic(err) // let the recovery middleware deal with this
+ }
+ }
+}
+
+/*
+ExportConfigDefault Generic error response.
+
+swagger:response exportConfigDefault
+*/
+type ExportConfigDefault struct {
+ _statusCode int
+
+ /*
+ In: Body
+ */
+ Payload *models.Error `json:"body,omitempty"`
+}
+
+// NewExportConfigDefault creates ExportConfigDefault with default headers values
+func NewExportConfigDefault(code int) *ExportConfigDefault {
+ if code <= 0 {
+ code = 500
+ }
+
+ return &ExportConfigDefault{
+ _statusCode: code,
+ }
+}
+
+// WithStatusCode adds the status to the export config default response
+func (o *ExportConfigDefault) WithStatusCode(code int) *ExportConfigDefault {
+ o._statusCode = code
+ return o
+}
+
+// SetStatusCode sets the status to the export config default response
+func (o *ExportConfigDefault) SetStatusCode(code int) {
+ o._statusCode = code
+}
+
+// WithPayload adds the payload to the export config default response
+func (o *ExportConfigDefault) WithPayload(payload *models.Error) *ExportConfigDefault {
+ o.Payload = payload
+ return o
+}
+
+// SetPayload sets the payload to the export config default response
+func (o *ExportConfigDefault) SetPayload(payload *models.Error) {
+ o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *ExportConfigDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+ rw.WriteHeader(o._statusCode)
+ if o.Payload != nil {
+ payload := o.Payload
+ if err := producer.Produce(rw, payload); err != nil {
+ panic(err) // let the recovery middleware deal with this
+ }
+ }
+}
diff --git a/restapi/operations/configuration/export_config_urlbuilder.go b/restapi/operations/configuration/export_config_urlbuilder.go
new file mode 100644
index 000000000..63eb5c01b
--- /dev/null
+++ b/restapi/operations/configuration/export_config_urlbuilder.go
@@ -0,0 +1,104 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+ "errors"
+ "net/url"
+ golangswaggerpaths "path"
+)
+
+// ExportConfigURL generates an URL for the export config operation
+type ExportConfigURL struct {
+ _basePath string
+}
+
+// WithBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *ExportConfigURL) WithBasePath(bp string) *ExportConfigURL {
+ o.SetBasePath(bp)
+ return o
+}
+
+// SetBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *ExportConfigURL) SetBasePath(bp string) {
+ o._basePath = bp
+}
+
+// Build a url path and query string
+func (o *ExportConfigURL) Build() (*url.URL, error) {
+ var _result url.URL
+
+ var _path = "/configs/export"
+
+ _basePath := o._basePath
+ if _basePath == "" {
+ _basePath = "/api/v1"
+ }
+ _result.Path = golangswaggerpaths.Join(_basePath, _path)
+
+ return &_result, nil
+}
+
+// Must is a helper function to panic when the url builder returns an error
+func (o *ExportConfigURL) Must(u *url.URL, err error) *url.URL {
+ if err != nil {
+ panic(err)
+ }
+ if u == nil {
+ panic("url can't be nil")
+ }
+ return u
+}
+
+// String returns the string representation of the path with query string
+func (o *ExportConfigURL) String() string {
+ return o.Must(o.Build()).String()
+}
+
+// BuildFull builds a full url with scheme, host, path and query string
+func (o *ExportConfigURL) BuildFull(scheme, host string) (*url.URL, error) {
+ if scheme == "" {
+ return nil, errors.New("scheme is required for a full url on ExportConfigURL")
+ }
+ if host == "" {
+ return nil, errors.New("host is required for a full url on ExportConfigURL")
+ }
+
+ base, err := o.Build()
+ if err != nil {
+ return nil, err
+ }
+
+ base.Scheme = scheme
+ base.Host = host
+ return base, nil
+}
+
+// StringFull returns the string representation of a complete url
+func (o *ExportConfigURL) StringFull(scheme, host string) string {
+ return o.Must(o.BuildFull(scheme, host)).String()
+}
diff --git a/restapi/operations/configuration/post_configs_import.go b/restapi/operations/configuration/post_configs_import.go
new file mode 100644
index 000000000..d10a13de3
--- /dev/null
+++ b/restapi/operations/configuration/post_configs_import.go
@@ -0,0 +1,88 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+ "net/http"
+
+ "github.com/go-openapi/runtime/middleware"
+
+ "github.com/minio/console/models"
+)
+
+// PostConfigsImportHandlerFunc turns a function with the right signature into a post configs import handler
+type PostConfigsImportHandlerFunc func(PostConfigsImportParams, *models.Principal) middleware.Responder
+
+// Handle executing the request and returning a response
+func (fn PostConfigsImportHandlerFunc) Handle(params PostConfigsImportParams, principal *models.Principal) middleware.Responder {
+ return fn(params, principal)
+}
+
+// PostConfigsImportHandler interface for that can handle valid post configs import params
+type PostConfigsImportHandler interface {
+ Handle(PostConfigsImportParams, *models.Principal) middleware.Responder
+}
+
+// NewPostConfigsImport creates a new http.Handler for the post configs import operation
+func NewPostConfigsImport(ctx *middleware.Context, handler PostConfigsImportHandler) *PostConfigsImport {
+ return &PostConfigsImport{Context: ctx, Handler: handler}
+}
+
+/*
+ PostConfigsImport swagger:route POST /configs/import Configuration postConfigsImport
+
+Uploads an Object.
+*/
+type PostConfigsImport struct {
+ Context *middleware.Context
+ Handler PostConfigsImportHandler
+}
+
+func (o *PostConfigsImport) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+ route, rCtx, _ := o.Context.RouteInfo(r)
+ if rCtx != nil {
+ *r = *rCtx
+ }
+ var Params = NewPostConfigsImportParams()
+ uprinc, aCtx, err := o.Context.Authorize(r, route)
+ if err != nil {
+ o.Context.Respond(rw, r, route.Produces, route, err)
+ return
+ }
+ if aCtx != nil {
+ *r = *aCtx
+ }
+ var principal *models.Principal
+ if uprinc != nil {
+ principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
+ }
+
+ if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
+ o.Context.Respond(rw, r, route.Produces, route, err)
+ return
+ }
+
+ res := o.Handler.Handle(Params, principal) // actually handle the request
+ o.Context.Respond(rw, r, route.Produces, route, res)
+
+}
diff --git a/restapi/operations/configuration/post_configs_import_parameters.go b/restapi/operations/configuration/post_configs_import_parameters.go
new file mode 100644
index 000000000..d4cda04dd
--- /dev/null
+++ b/restapi/operations/configuration/post_configs_import_parameters.go
@@ -0,0 +1,103 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "io"
+ "mime/multipart"
+ "net/http"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/runtime"
+ "github.com/go-openapi/runtime/middleware"
+)
+
+// PostConfigsImportMaxParseMemory sets the maximum size in bytes for
+// the multipart form parser for this operation.
+//
+// The default value is 32 MB.
+// The multipart parser stores up to this + 10MB.
+var PostConfigsImportMaxParseMemory int64 = 32 << 20
+
+// NewPostConfigsImportParams creates a new PostConfigsImportParams object
+//
+// There are no default values defined in the spec.
+func NewPostConfigsImportParams() PostConfigsImportParams {
+
+ return PostConfigsImportParams{}
+}
+
+// PostConfigsImportParams contains all the bound params for the post configs import operation
+// typically these are obtained from a http.Request
+//
+// swagger:parameters PostConfigsImport
+type PostConfigsImportParams struct {
+
+ // HTTP Request Object
+ HTTPRequest *http.Request `json:"-"`
+
+ /*
+ Required: true
+ In: formData
+ */
+ File io.ReadCloser
+}
+
+// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
+// for simple values it will use straight method calls.
+//
+// To ensure default values, the struct must have been initialized with NewPostConfigsImportParams() beforehand.
+func (o *PostConfigsImportParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
+ var res []error
+
+ o.HTTPRequest = r
+
+ if err := r.ParseMultipartForm(PostConfigsImportMaxParseMemory); err != nil {
+ if err != http.ErrNotMultipart {
+ return errors.New(400, "%v", err)
+ } else if err := r.ParseForm(); err != nil {
+ return errors.New(400, "%v", err)
+ }
+ }
+
+ file, fileHeader, err := r.FormFile("file")
+ if err != nil {
+ res = append(res, errors.New(400, "reading file %q failed: %v", "file", err))
+ } else if err := o.bindFile(file, fileHeader); err != nil {
+ // Required: true
+ res = append(res, err)
+ } else {
+ o.File = &runtime.File{Data: file, Header: fileHeader}
+ }
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+// bindFile binds file parameter File.
+//
+// The only supported validations on files are MinLength and MaxLength
+func (o *PostConfigsImportParams) bindFile(file multipart.File, header *multipart.FileHeader) error {
+ return nil
+}
diff --git a/restapi/operations/configuration/post_configs_import_responses.go b/restapi/operations/configuration/post_configs_import_responses.go
new file mode 100644
index 000000000..682995124
--- /dev/null
+++ b/restapi/operations/configuration/post_configs_import_responses.go
@@ -0,0 +1,115 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "net/http"
+
+ "github.com/go-openapi/runtime"
+
+ "github.com/minio/console/models"
+)
+
+// PostConfigsImportOKCode is the HTTP code returned for type PostConfigsImportOK
+const PostConfigsImportOKCode int = 200
+
+/*
+PostConfigsImportOK A successful response.
+
+swagger:response postConfigsImportOK
+*/
+type PostConfigsImportOK struct {
+}
+
+// NewPostConfigsImportOK creates PostConfigsImportOK with default headers values
+func NewPostConfigsImportOK() *PostConfigsImportOK {
+
+ return &PostConfigsImportOK{}
+}
+
+// WriteResponse to the client
+func (o *PostConfigsImportOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+ rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
+
+ rw.WriteHeader(200)
+}
+
+/*
+PostConfigsImportDefault Generic error response.
+
+swagger:response postConfigsImportDefault
+*/
+type PostConfigsImportDefault struct {
+ _statusCode int
+
+ /*
+ In: Body
+ */
+ Payload *models.Error `json:"body,omitempty"`
+}
+
+// NewPostConfigsImportDefault creates PostConfigsImportDefault with default headers values
+func NewPostConfigsImportDefault(code int) *PostConfigsImportDefault {
+ if code <= 0 {
+ code = 500
+ }
+
+ return &PostConfigsImportDefault{
+ _statusCode: code,
+ }
+}
+
+// WithStatusCode adds the status to the post configs import default response
+func (o *PostConfigsImportDefault) WithStatusCode(code int) *PostConfigsImportDefault {
+ o._statusCode = code
+ return o
+}
+
+// SetStatusCode sets the status to the post configs import default response
+func (o *PostConfigsImportDefault) SetStatusCode(code int) {
+ o._statusCode = code
+}
+
+// WithPayload adds the payload to the post configs import default response
+func (o *PostConfigsImportDefault) WithPayload(payload *models.Error) *PostConfigsImportDefault {
+ o.Payload = payload
+ return o
+}
+
+// SetPayload sets the payload to the post configs import default response
+func (o *PostConfigsImportDefault) SetPayload(payload *models.Error) {
+ o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *PostConfigsImportDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+
+ rw.WriteHeader(o._statusCode)
+ if o.Payload != nil {
+ payload := o.Payload
+ if err := producer.Produce(rw, payload); err != nil {
+ panic(err) // let the recovery middleware deal with this
+ }
+ }
+}
diff --git a/restapi/operations/configuration/post_configs_import_urlbuilder.go b/restapi/operations/configuration/post_configs_import_urlbuilder.go
new file mode 100644
index 000000000..f25a7de3a
--- /dev/null
+++ b/restapi/operations/configuration/post_configs_import_urlbuilder.go
@@ -0,0 +1,104 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2023 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+package configuration
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the generate command
+
+import (
+ "errors"
+ "net/url"
+ golangswaggerpaths "path"
+)
+
+// PostConfigsImportURL generates an URL for the post configs import operation
+type PostConfigsImportURL struct {
+ _basePath string
+}
+
+// WithBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *PostConfigsImportURL) WithBasePath(bp string) *PostConfigsImportURL {
+ o.SetBasePath(bp)
+ return o
+}
+
+// SetBasePath sets the base path for this url builder, only required when it's different from the
+// base path specified in the swagger spec.
+// When the value of the base path is an empty string
+func (o *PostConfigsImportURL) SetBasePath(bp string) {
+ o._basePath = bp
+}
+
+// Build a url path and query string
+func (o *PostConfigsImportURL) Build() (*url.URL, error) {
+ var _result url.URL
+
+ var _path = "/configs/import"
+
+ _basePath := o._basePath
+ if _basePath == "" {
+ _basePath = "/api/v1"
+ }
+ _result.Path = golangswaggerpaths.Join(_basePath, _path)
+
+ return &_result, nil
+}
+
+// Must is a helper function to panic when the url builder returns an error
+func (o *PostConfigsImportURL) Must(u *url.URL, err error) *url.URL {
+ if err != nil {
+ panic(err)
+ }
+ if u == nil {
+ panic("url can't be nil")
+ }
+ return u
+}
+
+// String returns the string representation of the path with query string
+func (o *PostConfigsImportURL) String() string {
+ return o.Must(o.Build()).String()
+}
+
+// BuildFull builds a full url with scheme, host, path and query string
+func (o *PostConfigsImportURL) BuildFull(scheme, host string) (*url.URL, error) {
+ if scheme == "" {
+ return nil, errors.New("scheme is required for a full url on PostConfigsImportURL")
+ }
+ if host == "" {
+ return nil, errors.New("host is required for a full url on PostConfigsImportURL")
+ }
+
+ base, err := o.Build()
+ if err != nil {
+ return nil, err
+ }
+
+ base.Scheme = scheme
+ base.Host = host
+ return base, nil
+}
+
+// StringFull returns the string representation of a complete url
+func (o *PostConfigsImportURL) StringFull(scheme, host string) string {
+ return o.Must(o.BuildFull(scheme, host)).String()
+}
diff --git a/restapi/operations/console_api.go b/restapi/operations/console_api.go
index f47ca9e69..b4ce990be 100644
--- a/restapi/operations/console_api.go
+++ b/restapi/operations/console_api.go
@@ -217,6 +217,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
BucketEnableBucketEncryptionHandler: bucket.EnableBucketEncryptionHandlerFunc(func(params bucket.EnableBucketEncryptionParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation bucket.EnableBucketEncryption has not yet been implemented")
}),
+ ConfigurationExportConfigHandler: configuration.ExportConfigHandlerFunc(func(params configuration.ExportConfigParams, principal *models.Principal) middleware.Responder {
+ return middleware.NotImplemented("operation configuration.ExportConfig has not yet been implemented")
+ }),
BucketGetBucketEncryptionInfoHandler: bucket.GetBucketEncryptionInfoHandlerFunc(func(params bucket.GetBucketEncryptionInfoParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation bucket.GetBucketEncryptionInfo has not yet been implemented")
}),
@@ -421,6 +424,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
ObjectPostBucketsBucketNameObjectsUploadHandler: object.PostBucketsBucketNameObjectsUploadHandlerFunc(func(params object.PostBucketsBucketNameObjectsUploadParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation object.PostBucketsBucketNameObjectsUpload has not yet been implemented")
}),
+ ConfigurationPostConfigsImportHandler: configuration.PostConfigsImportHandlerFunc(func(params configuration.PostConfigsImportParams, principal *models.Principal) middleware.Responder {
+ return middleware.NotImplemented("operation configuration.PostConfigsImport has not yet been implemented")
+ }),
ProfileProfilingStartHandler: profile.ProfilingStartHandlerFunc(func(params profile.ProfilingStartParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation profile.ProfilingStart has not yet been implemented")
}),
@@ -696,6 +702,8 @@ type ConsoleAPI struct {
TieringEditTierCredentialsHandler tiering.EditTierCredentialsHandler
// BucketEnableBucketEncryptionHandler sets the operation handler for the enable bucket encryption operation
BucketEnableBucketEncryptionHandler bucket.EnableBucketEncryptionHandler
+ // ConfigurationExportConfigHandler sets the operation handler for the export config operation
+ ConfigurationExportConfigHandler configuration.ExportConfigHandler
// BucketGetBucketEncryptionInfoHandler sets the operation handler for the get bucket encryption info operation
BucketGetBucketEncryptionInfoHandler bucket.GetBucketEncryptionInfoHandler
// BucketGetBucketLifecycleHandler sets the operation handler for the get bucket lifecycle operation
@@ -832,6 +840,8 @@ type ConsoleAPI struct {
PolicyPolicyInfoHandler policy.PolicyInfoHandler
// ObjectPostBucketsBucketNameObjectsUploadHandler sets the operation handler for the post buckets bucket name objects upload operation
ObjectPostBucketsBucketNameObjectsUploadHandler object.PostBucketsBucketNameObjectsUploadHandler
+ // ConfigurationPostConfigsImportHandler sets the operation handler for the post configs import operation
+ ConfigurationPostConfigsImportHandler configuration.PostConfigsImportHandler
// ProfileProfilingStartHandler sets the operation handler for the profiling start operation
ProfileProfilingStartHandler profile.ProfilingStartHandler
// ProfileProfilingStopHandler sets the operation handler for the profiling stop operation
@@ -1136,6 +1146,9 @@ func (o *ConsoleAPI) Validate() error {
if o.BucketEnableBucketEncryptionHandler == nil {
unregistered = append(unregistered, "bucket.EnableBucketEncryptionHandler")
}
+ if o.ConfigurationExportConfigHandler == nil {
+ unregistered = append(unregistered, "configuration.ExportConfigHandler")
+ }
if o.BucketGetBucketEncryptionInfoHandler == nil {
unregistered = append(unregistered, "bucket.GetBucketEncryptionInfoHandler")
}
@@ -1340,6 +1353,9 @@ func (o *ConsoleAPI) Validate() error {
if o.ObjectPostBucketsBucketNameObjectsUploadHandler == nil {
unregistered = append(unregistered, "object.PostBucketsBucketNameObjectsUploadHandler")
}
+ if o.ConfigurationPostConfigsImportHandler == nil {
+ unregistered = append(unregistered, "configuration.PostConfigsImportHandler")
+ }
if o.ProfileProfilingStartHandler == nil {
unregistered = append(unregistered, "profile.ProfilingStartHandler")
}
@@ -1748,6 +1764,10 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
+ o.handlers["GET"]["/configs/export"] = configuration.NewExportConfig(o.context, o.ConfigurationExportConfigHandler)
+ if o.handlers["GET"] == nil {
+ o.handlers["GET"] = make(map[string]http.Handler)
+ }
o.handlers["GET"]["/buckets/{bucket_name}/encryption/info"] = bucket.NewGetBucketEncryptionInfo(o.context, o.BucketGetBucketEncryptionInfoHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
@@ -2020,6 +2040,10 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
+ o.handlers["POST"]["/configs/import"] = configuration.NewPostConfigsImport(o.context, o.ConfigurationPostConfigsImportHandler)
+ if o.handlers["POST"] == nil {
+ o.handlers["POST"] = make(map[string]http.Handler)
+ }
o.handlers["POST"]["/profiling/start"] = profile.NewProfilingStart(o.context, o.ProfileProfilingStartHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
diff --git a/swagger-console.yml b/swagger-console.yml
index b5f6ff684..dcded1ea1 100644
--- a/swagger-console.yml
+++ b/swagger-console.yml
@@ -2271,6 +2271,40 @@ paths:
tags:
- Configuration
+ /configs/export:
+ get:
+ summary: Export the current config from MinIO server
+ operationId: ExportConfig
+ responses:
+ 200:
+ description: A successful response.
+ schema:
+ $ref: "#/definitions/configExportResponse"
+ default:
+ description: Generic error response.
+ schema:
+ $ref: "#/definitions/error"
+ tags:
+ - Configuration
+ /configs/import:
+ post:
+ summary: Uploads a file to import MinIO server config.
+ consumes:
+ - multipart/form-data
+ parameters:
+ - name: file
+ in: formData
+ required: true
+ type: file
+ responses:
+ 200:
+ description: A successful response.
+ default:
+ description: Generic error response.
+ schema:
+ $ref: "#/definitions/error"
+ tags:
+ - Configuration
/service/restart:
post:
summary: Restart Service
@@ -5223,6 +5257,15 @@ definitions:
description: Returns wheter server needs to restart to apply changes or not
type: boolean
+ configExportResponse:
+ type: object
+ properties:
+ value:
+ description: Returns base64 encoded value
+ type: string
+ status:
+ type: string
+
license:
type: object
properties: