diff --git a/models/operator_subnet_register_api_key.go b/models/operator_subnet_register_api_key.go new file mode 100644 index 000000000..a223b2df7 --- /dev/null +++ b/models/operator_subnet_register_api_key.go @@ -0,0 +1,67 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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" +) + +// OperatorSubnetRegisterAPIKey operator subnet register API key +// +// swagger:model operatorSubnetRegisterAPIKey +type OperatorSubnetRegisterAPIKey struct { + + // registered + Registered bool `json:"registered,omitempty"` +} + +// Validate validates this operator subnet register API key +func (m *OperatorSubnetRegisterAPIKey) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this operator subnet register API key based on context it is used +func (m *OperatorSubnetRegisterAPIKey) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *OperatorSubnetRegisterAPIKey) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *OperatorSubnetRegisterAPIKey) UnmarshalBinary(b []byte) error { + var res OperatorSubnetRegisterAPIKey + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/operator_subnet_register_api_key_response.go b/models/operator_subnet_register_api_key_response.go new file mode 100644 index 000000000..bedc870da --- /dev/null +++ b/models/operator_subnet_register_api_key_response.go @@ -0,0 +1,67 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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" +) + +// OperatorSubnetRegisterAPIKeyResponse operator subnet register API key response +// +// swagger:model operatorSubnetRegisterAPIKeyResponse +type OperatorSubnetRegisterAPIKeyResponse struct { + + // registered + Registered bool `json:"registered,omitempty"` +} + +// Validate validates this operator subnet register API key response +func (m *OperatorSubnetRegisterAPIKeyResponse) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this operator subnet register API key response based on context it is used +func (m *OperatorSubnetRegisterAPIKeyResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *OperatorSubnetRegisterAPIKeyResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *OperatorSubnetRegisterAPIKeyResponse) UnmarshalBinary(b []byte) error { + var res OperatorSubnetRegisterAPIKeyResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/operatorapi/embedded_spec.go b/operatorapi/embedded_spec.go index b20ee6bcd..15964df99 100644 --- a/operatorapi/embedded_spec.go +++ b/operatorapi/embedded_spec.go @@ -1937,6 +1937,29 @@ func init() { } } }, + "/subnet/apikey/info": { + "get": { + "tags": [ + "OperatorAPI" + ], + "summary": "Subnet API key info", + "operationId": "OperatorSubnetAPIKeyInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/operatorSubnetRegisterAPIKeyResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/subnet/apikey/register": { "post": { "tags": [ @@ -1956,7 +1979,10 @@ func init() { ], "responses": { "200": { - "description": "A successful response." + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/operatorSubnetRegisterAPIKeyResponse" + } }, "default": { "description": "Generic error response.", @@ -3729,6 +3755,14 @@ func init() { } } }, + "operatorSubnetRegisterAPIKeyResponse": { + "type": "object", + "properties": { + "registered": { + "type": "boolean" + } + } + }, "parityResponse": { "type": "array", "items": { @@ -6873,6 +6907,29 @@ func init() { } } }, + "/subnet/apikey/info": { + "get": { + "tags": [ + "OperatorAPI" + ], + "summary": "Subnet API key info", + "operationId": "OperatorSubnetAPIKeyInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/operatorSubnetRegisterAPIKeyResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/subnet/apikey/register": { "post": { "tags": [ @@ -6892,7 +6949,10 @@ func init() { ], "responses": { "200": { - "description": "A successful response." + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/operatorSubnetRegisterAPIKeyResponse" + } }, "default": { "description": "Generic error response.", @@ -9452,6 +9512,14 @@ func init() { } } }, + "operatorSubnetRegisterAPIKeyResponse": { + "type": "object", + "properties": { + "registered": { + "type": "boolean" + } + } + }, "parityResponse": { "type": "array", "items": { diff --git a/operatorapi/operations/operator_api.go b/operatorapi/operations/operator_api.go index 233024448..007bf3398 100644 --- a/operatorapi/operations/operator_api.go +++ b/operatorapi/operations/operator_api.go @@ -166,6 +166,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI { AuthLogoutHandler: auth.LogoutHandlerFunc(func(params auth.LogoutParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation auth.Logout has not yet been implemented") }), + OperatorAPIOperatorSubnetAPIKeyInfoHandler: operator_api.OperatorSubnetAPIKeyInfoHandlerFunc(func(params operator_api.OperatorSubnetAPIKeyInfoParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation operator_api.OperatorSubnetAPIKeyInfo has not yet been implemented") + }), OperatorAPIOperatorSubnetAPIKeyHandler: operator_api.OperatorSubnetAPIKeyHandlerFunc(func(params operator_api.OperatorSubnetAPIKeyParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation operator_api.OperatorSubnetAPIKey has not yet been implemented") }), @@ -364,6 +367,8 @@ type OperatorAPI struct { AuthLoginOperatorHandler auth.LoginOperatorHandler // AuthLogoutHandler sets the operation handler for the logout operation AuthLogoutHandler auth.LogoutHandler + // OperatorAPIOperatorSubnetAPIKeyInfoHandler sets the operation handler for the operator subnet API key info operation + OperatorAPIOperatorSubnetAPIKeyInfoHandler operator_api.OperatorSubnetAPIKeyInfoHandler // OperatorAPIOperatorSubnetAPIKeyHandler sets the operation handler for the operator subnet Api key operation OperatorAPIOperatorSubnetAPIKeyHandler operator_api.OperatorSubnetAPIKeyHandler // OperatorAPIOperatorSubnetLoginHandler sets the operation handler for the operator subnet login operation @@ -601,6 +606,9 @@ func (o *OperatorAPI) Validate() error { if o.AuthLogoutHandler == nil { unregistered = append(unregistered, "auth.LogoutHandler") } + if o.OperatorAPIOperatorSubnetAPIKeyInfoHandler == nil { + unregistered = append(unregistered, "operator_api.OperatorSubnetAPIKeyInfoHandler") + } if o.OperatorAPIOperatorSubnetAPIKeyHandler == nil { unregistered = append(unregistered, "operator_api.OperatorSubnetAPIKeyHandler") } @@ -919,6 +927,10 @@ func (o *OperatorAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/subnet/apikey/info"] = operator_api.NewOperatorSubnetAPIKeyInfo(o.context, o.OperatorAPIOperatorSubnetAPIKeyInfoHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/subnet/apikey"] = operator_api.NewOperatorSubnetAPIKey(o.context, o.OperatorAPIOperatorSubnetAPIKeyHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) diff --git a/operatorapi/operations/operator_api/operator_subnet_api_key_info.go b/operatorapi/operations/operator_api/operator_subnet_api_key_info.go new file mode 100644 index 000000000..445ebfb2d --- /dev/null +++ b/operatorapi/operations/operator_api/operator_subnet_api_key_info.go @@ -0,0 +1,88 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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 operator_api + +// 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" +) + +// OperatorSubnetAPIKeyInfoHandlerFunc turns a function with the right signature into a operator subnet API key info handler +type OperatorSubnetAPIKeyInfoHandlerFunc func(OperatorSubnetAPIKeyInfoParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn OperatorSubnetAPIKeyInfoHandlerFunc) Handle(params OperatorSubnetAPIKeyInfoParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// OperatorSubnetAPIKeyInfoHandler interface for that can handle valid operator subnet API key info params +type OperatorSubnetAPIKeyInfoHandler interface { + Handle(OperatorSubnetAPIKeyInfoParams, *models.Principal) middleware.Responder +} + +// NewOperatorSubnetAPIKeyInfo creates a new http.Handler for the operator subnet API key info operation +func NewOperatorSubnetAPIKeyInfo(ctx *middleware.Context, handler OperatorSubnetAPIKeyInfoHandler) *OperatorSubnetAPIKeyInfo { + return &OperatorSubnetAPIKeyInfo{Context: ctx, Handler: handler} +} + +/* OperatorSubnetAPIKeyInfo swagger:route GET /subnet/apikey/info OperatorAPI operatorSubnetApiKeyInfo + +Subnet API key info + +*/ +type OperatorSubnetAPIKeyInfo struct { + Context *middleware.Context + Handler OperatorSubnetAPIKeyInfoHandler +} + +func (o *OperatorSubnetAPIKeyInfo) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewOperatorSubnetAPIKeyInfoParams() + 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/operatorapi/operations/operator_api/operator_subnet_api_key_info_parameters.go b/operatorapi/operations/operator_api/operator_subnet_api_key_info_parameters.go new file mode 100644 index 000000000..917df19b2 --- /dev/null +++ b/operatorapi/operations/operator_api/operator_subnet_api_key_info_parameters.go @@ -0,0 +1,63 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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 operator_api + +// 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" +) + +// NewOperatorSubnetAPIKeyInfoParams creates a new OperatorSubnetAPIKeyInfoParams object +// +// There are no default values defined in the spec. +func NewOperatorSubnetAPIKeyInfoParams() OperatorSubnetAPIKeyInfoParams { + + return OperatorSubnetAPIKeyInfoParams{} +} + +// OperatorSubnetAPIKeyInfoParams contains all the bound params for the operator subnet API key info operation +// typically these are obtained from a http.Request +// +// swagger:parameters OperatorSubnetAPIKeyInfo +type OperatorSubnetAPIKeyInfoParams 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 NewOperatorSubnetAPIKeyInfoParams() beforehand. +func (o *OperatorSubnetAPIKeyInfoParams) 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/operatorapi/operations/operator_api/operator_subnet_api_key_info_responses.go b/operatorapi/operations/operator_api/operator_subnet_api_key_info_responses.go new file mode 100644 index 000000000..2be3f72e4 --- /dev/null +++ b/operatorapi/operations/operator_api/operator_subnet_api_key_info_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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 operator_api + +// 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" +) + +// OperatorSubnetAPIKeyInfoOKCode is the HTTP code returned for type OperatorSubnetAPIKeyInfoOK +const OperatorSubnetAPIKeyInfoOKCode int = 200 + +/*OperatorSubnetAPIKeyInfoOK A successful response. + +swagger:response operatorSubnetApiKeyInfoOK +*/ +type OperatorSubnetAPIKeyInfoOK struct { + + /* + In: Body + */ + Payload *models.OperatorSubnetRegisterAPIKeyResponse `json:"body,omitempty"` +} + +// NewOperatorSubnetAPIKeyInfoOK creates OperatorSubnetAPIKeyInfoOK with default headers values +func NewOperatorSubnetAPIKeyInfoOK() *OperatorSubnetAPIKeyInfoOK { + + return &OperatorSubnetAPIKeyInfoOK{} +} + +// WithPayload adds the payload to the operator subnet Api key info o k response +func (o *OperatorSubnetAPIKeyInfoOK) WithPayload(payload *models.OperatorSubnetRegisterAPIKeyResponse) *OperatorSubnetAPIKeyInfoOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the operator subnet Api key info o k response +func (o *OperatorSubnetAPIKeyInfoOK) SetPayload(payload *models.OperatorSubnetRegisterAPIKeyResponse) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *OperatorSubnetAPIKeyInfoOK) 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 + } + } +} + +/*OperatorSubnetAPIKeyInfoDefault Generic error response. + +swagger:response operatorSubnetApiKeyInfoDefault +*/ +type OperatorSubnetAPIKeyInfoDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewOperatorSubnetAPIKeyInfoDefault creates OperatorSubnetAPIKeyInfoDefault with default headers values +func NewOperatorSubnetAPIKeyInfoDefault(code int) *OperatorSubnetAPIKeyInfoDefault { + if code <= 0 { + code = 500 + } + + return &OperatorSubnetAPIKeyInfoDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the operator subnet API key info default response +func (o *OperatorSubnetAPIKeyInfoDefault) WithStatusCode(code int) *OperatorSubnetAPIKeyInfoDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the operator subnet API key info default response +func (o *OperatorSubnetAPIKeyInfoDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the operator subnet API key info default response +func (o *OperatorSubnetAPIKeyInfoDefault) WithPayload(payload *models.Error) *OperatorSubnetAPIKeyInfoDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the operator subnet API key info default response +func (o *OperatorSubnetAPIKeyInfoDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *OperatorSubnetAPIKeyInfoDefault) 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/operatorapi/operations/operator_api/operator_subnet_api_key_info_urlbuilder.go b/operatorapi/operations/operator_api/operator_subnet_api_key_info_urlbuilder.go new file mode 100644 index 000000000..3388c4c42 --- /dev/null +++ b/operatorapi/operations/operator_api/operator_subnet_api_key_info_urlbuilder.go @@ -0,0 +1,104 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2022 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 operator_api + +// 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" +) + +// OperatorSubnetAPIKeyInfoURL generates an URL for the operator subnet API key info operation +type OperatorSubnetAPIKeyInfoURL 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 *OperatorSubnetAPIKeyInfoURL) WithBasePath(bp string) *OperatorSubnetAPIKeyInfoURL { + 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 *OperatorSubnetAPIKeyInfoURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *OperatorSubnetAPIKeyInfoURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/subnet/apikey/info" + + _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 *OperatorSubnetAPIKeyInfoURL) 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 *OperatorSubnetAPIKeyInfoURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *OperatorSubnetAPIKeyInfoURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on OperatorSubnetAPIKeyInfoURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on OperatorSubnetAPIKeyInfoURL") + } + + 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 *OperatorSubnetAPIKeyInfoURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/operatorapi/operations/operator_api/operator_subnet_register_api_key_responses.go b/operatorapi/operations/operator_api/operator_subnet_register_api_key_responses.go index ddbb9c5d5..01aea79c3 100644 --- a/operatorapi/operations/operator_api/operator_subnet_register_api_key_responses.go +++ b/operatorapi/operations/operator_api/operator_subnet_register_api_key_responses.go @@ -38,6 +38,11 @@ const OperatorSubnetRegisterAPIKeyOKCode int = 200 swagger:response operatorSubnetRegisterApiKeyOK */ type OperatorSubnetRegisterAPIKeyOK struct { + + /* + In: Body + */ + Payload *models.OperatorSubnetRegisterAPIKeyResponse `json:"body,omitempty"` } // NewOperatorSubnetRegisterAPIKeyOK creates OperatorSubnetRegisterAPIKeyOK with default headers values @@ -46,12 +51,27 @@ func NewOperatorSubnetRegisterAPIKeyOK() *OperatorSubnetRegisterAPIKeyOK { return &OperatorSubnetRegisterAPIKeyOK{} } +// WithPayload adds the payload to the operator subnet register Api key o k response +func (o *OperatorSubnetRegisterAPIKeyOK) WithPayload(payload *models.OperatorSubnetRegisterAPIKeyResponse) *OperatorSubnetRegisterAPIKeyOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the operator subnet register Api key o k response +func (o *OperatorSubnetRegisterAPIKeyOK) SetPayload(payload *models.OperatorSubnetRegisterAPIKeyResponse) { + o.Payload = payload +} + // WriteResponse to the client func (o *OperatorSubnetRegisterAPIKeyOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses - 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 + } + } } /*OperatorSubnetRegisterAPIKeyDefault Generic error response. diff --git a/operatorapi/operator_subnet.go b/operatorapi/operator_subnet.go index 7ce5012ae..70a94900b 100644 --- a/operatorapi/operator_subnet.go +++ b/operatorapi/operator_subnet.go @@ -19,15 +19,24 @@ package operatorapi import ( "context" "errors" - - xhttp "github.com/minio/console/pkg/http" - "github.com/minio/console/pkg/subnet" + "os" "github.com/go-openapi/runtime/middleware" + "github.com/minio/console/cluster" "github.com/minio/console/models" "github.com/minio/console/operatorapi/operations" "github.com/minio/console/operatorapi/operations/operator_api" + xhttp "github.com/minio/console/pkg/http" + "github.com/minio/console/pkg/subnet" "github.com/minio/console/restapi" + v2 "github.com/minio/operator/pkg/apis/minio.min.io/v2" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + apiKeySecretDefault = "operator-subnet" + apiKeySecretEnvVar = "API_KEY_SECRET_NAME" ) func registerOperatorSubnetHandlers(api *operations.OperatorAPI) { @@ -38,6 +47,7 @@ func registerOperatorSubnetHandlers(api *operations.OperatorAPI) { } return operator_api.NewOperatorSubnetLoginOK().WithPayload(res) }) + api.OperatorAPIOperatorSubnetLoginMFAHandler = operator_api.OperatorSubnetLoginMFAHandlerFunc(func(params operator_api.OperatorSubnetLoginMFAParams, session *models.Principal) middleware.Responder { res, err := getOperatorSubnetLoginMFAResponse(session, params) if err != nil { @@ -45,6 +55,7 @@ func registerOperatorSubnetHandlers(api *operations.OperatorAPI) { } return operator_api.NewOperatorSubnetLoginMFAOK().WithPayload(res) }) + api.OperatorAPIOperatorSubnetAPIKeyHandler = operator_api.OperatorSubnetAPIKeyHandlerFunc(func(params operator_api.OperatorSubnetAPIKeyParams, session *models.Principal) middleware.Responder { res, err := getOperatorSubnetAPIKeyResponse(session, params) if err != nil { @@ -52,9 +63,20 @@ func registerOperatorSubnetHandlers(api *operations.OperatorAPI) { } return operator_api.NewOperatorSubnetAPIKeyOK().WithPayload(res) }) + api.OperatorAPIOperatorSubnetRegisterAPIKeyHandler = operator_api.OperatorSubnetRegisterAPIKeyHandlerFunc(func(params operator_api.OperatorSubnetRegisterAPIKeyParams, session *models.Principal) middleware.Responder { - // TODO: Implement - return operator_api.NewOperatorSubnetRegisterAPIKeyOK() + res, err := getOperatorSubnetRegisterAPIKeyResponse(session, params) + if err != nil { + return operator_api.NewOperatorSubnetRegisterAPIKeyDefault(int(err.Code)).WithPayload(err) + } + return operator_api.NewOperatorSubnetRegisterAPIKeyOK().WithPayload(res) + }) + api.OperatorAPIOperatorSubnetAPIKeyInfoHandler = operator_api.OperatorSubnetAPIKeyInfoHandlerFunc(func(params operator_api.OperatorSubnetAPIKeyInfoParams, session *models.Principal) middleware.Responder { + res, err := getOperatorSubnetAPIKeyInfoResponse(session, params) + if err != nil { + return operator_api.NewOperatorSubnetAPIKeyInfoDefault(int(err.Code)).WithPayload(err) + } + return operator_api.NewOperatorSubnetAPIKeyInfoOK().WithPayload(res) }) } @@ -101,3 +123,81 @@ func getOperatorSubnetAPIKeyResponse(session *models.Principal, params operator_ } return &models.OperatorSubnetAPIKey{APIKey: apiKey}, nil } + +func getOperatorSubnetRegisterAPIKeyResponse(session *models.Principal, params operator_api.OperatorSubnetRegisterAPIKeyParams) (*models.OperatorSubnetRegisterAPIKeyResponse, *models.Error) { + ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) + defer cancel() + clientSet, err := cluster.K8sClient(session.STSSessionToken) + if err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + tenants, err := getTenantsToRegister(ctx, session) + if err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + k8sClient := &k8sClient{client: clientSet} + return registerTenants(ctx, tenants.Items, params.Body.APIKey, k8sClient) +} + +func getTenantsToRegister(ctx context.Context, session *models.Principal) (*v2.TenantList, error) { + opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken) + if err != nil { + return nil, err + } + opClient := &operatorClient{client: opClientClientSet} + return opClient.TenantList(ctx, "", metav1.ListOptions{}) +} + +func registerTenants(ctx context.Context, tenants []v2.Tenant, apiKey string, k8sClient K8sClientI) (*models.OperatorSubnetRegisterAPIKeyResponse, *models.Error) { + for _, tenant := range tenants { + if err := registerTenant(ctx, tenant, apiKey, k8sClient); err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + } + if err := createSubnetAPIKeySecret(ctx, apiKey, k8sClient); err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + return &models.OperatorSubnetRegisterAPIKeyResponse{Registered: true}, nil +} + +func registerTenant(ctx context.Context, tenant v2.Tenant, apiKey string, k8sClient K8sClientI) error { + svcURL := tenant.GetTenantServiceURL() + mAdmin, err := getTenantAdminClient(ctx, k8sClient, &tenant, svcURL) + if err != nil { + return err + } + adminClient := restapi.AdminClient{Client: mAdmin} + _, err = restapi.SubnetRegisterWithAPIKey(ctx, adminClient, apiKey) + return err +} + +func createSubnetAPIKeySecret(ctx context.Context, apiKey string, k8sClient K8sClientI) error { + apiKeySecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{Name: getAPIKeySecretName()}, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{"api-key": []byte(apiKey)}, + } + _, err := k8sClient.createSecret(ctx, "default", apiKeySecret, metav1.CreateOptions{}) + return err +} + +func getOperatorSubnetAPIKeyInfoResponse(session *models.Principal, params operator_api.OperatorSubnetAPIKeyInfoParams) (*models.OperatorSubnetRegisterAPIKeyResponse, *models.Error) { + ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) + defer cancel() + clientSet, err := cluster.K8sClient(session.STSSessionToken) + if err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + k8sClient := &k8sClient{client: clientSet} + if _, err := k8sClient.getSecret(ctx, "default", getAPIKeySecretName(), metav1.GetOptions{}); err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + return &models.OperatorSubnetRegisterAPIKeyResponse{Registered: true}, nil +} + +func getAPIKeySecretName() string { + if s := os.Getenv(apiKeySecretEnvVar); s != "" { + return s + } + return apiKeySecretDefault +} diff --git a/operatorapi/operator_subnet_test.go b/operatorapi/operator_subnet_test.go index cc391c42a..cafd42726 100644 --- a/operatorapi/operator_subnet_test.go +++ b/operatorapi/operator_subnet_test.go @@ -17,6 +17,7 @@ package operatorapi import ( + "context" "fmt" "net/http" "net/http/httptest" @@ -28,19 +29,26 @@ import ( "github.com/minio/console/operatorapi/operations" "github.com/minio/console/operatorapi/operations/operator_api" "github.com/minio/console/pkg/subnet" + v2 "github.com/minio/operator/pkg/apis/minio.min.io/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type OperatorSubnetTestSuite struct { suite.Suite - assert *assert.Assertions - loginServer *httptest.Server - loginWithError bool - loginMFAServer *httptest.Server - loginMFAWithError bool - getAPIKeyServer *httptest.Server - getAPIKeyWithError bool + assert *assert.Assertions + loginServer *httptest.Server + loginWithError bool + loginMFAServer *httptest.Server + loginMFAWithError bool + getAPIKeyServer *httptest.Server + getAPIKeyWithError bool + registerAPIKeyServer *httptest.Server + registerAPIKeyWithError bool + k8sClient k8sClientMock } func (suite *OperatorSubnetTestSuite) SetupSuite() { @@ -48,6 +56,20 @@ func (suite *OperatorSubnetTestSuite) SetupSuite() { suite.loginServer = httptest.NewServer(http.HandlerFunc(suite.loginHandler)) suite.loginMFAServer = httptest.NewServer(http.HandlerFunc(suite.loginMFAHandler)) suite.getAPIKeyServer = httptest.NewServer(http.HandlerFunc(suite.getAPIKeyHandler)) + suite.registerAPIKeyServer = httptest.NewServer(http.HandlerFunc(suite.registerAPIKeyHandler)) + suite.k8sClient = k8sClientMock{} + CreateSecretMock = func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) { + return &corev1.Secret{}, nil + } + k8sclientGetSecretMock = func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + data := make(map[string][]byte) + data["secretkey"] = []byte("secret") + data["accesskey"] = []byte("access") + sec := &corev1.Secret{ + Data: data, + } + return sec, nil + } } func (suite *OperatorSubnetTestSuite) loginHandler( @@ -80,6 +102,16 @@ func (suite *OperatorSubnetTestSuite) getAPIKeyHandler( } } +func (suite *OperatorSubnetTestSuite) registerAPIKeyHandler( + w http.ResponseWriter, r *http.Request, +) { + if suite.registerAPIKeyWithError { + w.WriteHeader(400) + } else { + fmt.Fprintf(w, `{"api_key": "mockAPIKey"}`) + } +} + func (suite *OperatorSubnetTestSuite) TearDownSuite() { } @@ -183,6 +215,90 @@ func (suite *OperatorSubnetTestSuite) initSubnetAPIKeyRequest() (params operator return params, api } +// TODO: Improve register tests (make code more testable) +// func (suite *OperatorSubnetTestSuite) TestOperatorSubnetRegisterAPIKeyHandlerWithServerError() { +// params, api := suite.initSubnetRegisterAPIKeyRequest() +// suite.registerAPIKeyWithError = true +// os.Setenv(subnet.ConsoleSubnetURL, suite.registerAPIKeyServer.URL) +// response := api.OperatorAPIOperatorSubnetRegisterAPIKeyHandler.Handle(params, &models.Principal{}) +// _, ok := response.(*operator_api.OperatorSubnetRegisterAPIKeyDefault) +// suite.assert.True(ok) +// os.Unsetenv(subnet.ConsoleSubnetURL) +// } + +// func (suite *OperatorSubnetTestSuite) TestOperatorSubnetRegisterAPIKeyHandlerWithError() { +// ctx := context.Background() +// suite.registerAPIKeyWithError = false +// os.Setenv(subnet.ConsoleSubnetURL, suite.registerAPIKeyServer.URL) +// res, err := registerTenants([]v2.Tenant{{ +// Spec: v2.TenantSpec{CredsSecret: &corev1.LocalObjectReference{Name: "secret-name"}}, +// }}, "mockAPIKey", ctx, suite.k8sClient) +// suite.assert.Nil(res) +// suite.assert.NotNil(err) +// os.Unsetenv(subnet.ConsoleSubnetURL) +// } + +// func (suite *OperatorSubnetTestSuite) TestOperatorSubnetRegisterAPIKeyHandlerGetTenants() { +// ctx := context.Background() +// res, err := getTenantsToRegister(ctx, &models.Principal{}) +// suite.assert.NotNil(res) +// suite.assert.Nil(err) +// } + +func (suite *OperatorSubnetTestSuite) TestOperatorSubnetRegisterAPIKeyHandlerWithUnreachableTenant() { + ctx := context.Background() + res, err := registerTenants(ctx, []v2.Tenant{{ + Spec: v2.TenantSpec{CredsSecret: &corev1.LocalObjectReference{Name: "secret-name"}}, + }}, "mockAPIKey", suite.k8sClient) + suite.assert.Nil(res) + suite.assert.NotNil(err) +} + +func (suite *OperatorSubnetTestSuite) TestOperatorSubnetRegisterAPIKeyHandlerZeroTenants() { + ctx := context.Background() + res, err := registerTenants(ctx, []v2.Tenant{}, "mockAPIKey", suite.k8sClient) + suite.assert.NotNil(res) + suite.assert.Nil(err) +} + +// func (suite *OperatorSubnetTestSuite) initSubnetRegisterAPIKeyRequest() (params operator_api.OperatorSubnetRegisterAPIKeyParams, api operations.OperatorAPI) { +// registerOperatorSubnetHandlers(&api) +// params.Body = &models.OperatorSubnetAPIKey{APIKey: "mockAPIKey"} +// params.HTTPRequest = &http.Request{} +// return params, api +// } + +func (suite *OperatorSubnetTestSuite) TestOperatorSubnetAPIKeyInfoHandlerWithNoSecret() { + params, api := suite.initSubnetAPIKeyInfoRequest() + os.Setenv(apiKeySecretEnvVar, "mock-operator-subnet") + response := api.OperatorAPIOperatorSubnetAPIKeyInfoHandler.Handle(params, &models.Principal{}) + _, ok := response.(*operator_api.OperatorSubnetAPIKeyInfoDefault) + suite.assert.True(ok) + os.Unsetenv(apiKeySecretEnvVar) +} + +// func (suite *OperatorSubnetTestSuite) TestOperatorSubnetAPIKeyInfoHandlerWithSecret() { +// params, api := suite.initSubnetAPIKeyInfoRequest() +// os.Setenv(apiKeySecretEnvVar, "mock-operator-subnet") +// session := &models.Principal{} +// clientSet, _ := cluster.K8sClient(session.STSSessionToken) +// k8sClient := &k8sClient{client: clientSet} +// ctx := context.Background() +// secret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: getAPIKeySecretName()}} +// k8sClient.createSecret(ctx, "default", secret, metav1.CreateOptions{}) +// response := api.OperatorAPIOperatorSubnetAPIKeyInfoHandler.Handle(params, session) +// _, ok := response.(*operator_api.OperatorSubnetAPIKeyInfoOK) +// suite.assert.True(ok) +// k8sClient.deleteSecret(ctx, "default", getAPIKeySecretName(), metav1.DeleteOptions{}) +// os.Unsetenv(apiKeySecretEnvVar) +// } + +func (suite *OperatorSubnetTestSuite) initSubnetAPIKeyInfoRequest() (params operator_api.OperatorSubnetAPIKeyInfoParams, api operations.OperatorAPI) { + registerOperatorSubnetHandlers(&api) + params.HTTPRequest = &http.Request{} + return params, api +} + func TestOperatorSubnet(t *testing.T) { suite.Run(t, new(OperatorSubnetTestSuite)) } diff --git a/restapi/admin_subnet.go b/restapi/admin_subnet.go index c73c7e6cb..766978900 100644 --- a/restapi/admin_subnet.go +++ b/restapi/admin_subnet.go @@ -90,7 +90,7 @@ func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKe if err != nil { return false, err } - registerResult, err := subnet.Register(httpClient, serverInfo, apiKey, "", "") + registerResult, err := subnet.Register(GetConsoleHTTPClient(), serverInfo, apiKey, "", "") if err != nil { return false, err } diff --git a/swagger-operator.yml b/swagger-operator.yml index e48179a4e..fd6c0571c 100644 --- a/swagger-operator.yml +++ b/swagger-operator.yml @@ -1472,6 +1472,23 @@ paths: responses: 200: description: A successful response. + schema: + $ref: "#/definitions/operatorSubnetRegisterAPIKeyResponse" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - OperatorAPI + /subnet/apikey/info: + get: + summary: Subnet API key info + operationId: OperatorSubnetAPIKeyInfo + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/operatorSubnetRegisterAPIKeyResponse" default: description: Generic error response. schema: @@ -3570,3 +3587,9 @@ definitions: properties: apiKey: type: string + + operatorSubnetRegisterAPIKeyResponse: + type: object + properties: + registered: + type: boolean