Compare commits

..

6 Commits

Author SHA1 Message Date
adfost
2988de4025 adding edit service account api/ui (#1545)
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
2022-02-10 17:18:57 -08:00
Daniel Valdivia
c6f2ddfd7e Release v0.14.5 (#1550)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-02-10 17:06:43 -08:00
Alex
6a7f042d6c Fixed logic for add lifecycle rules (#1553)
- Removed support to fixed date lifecycle rules according resolution of https://github.com/minio/console/issues/1527

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-02-10 16:50:27 -08:00
Alex
5fd82ca6e9 Added delete bucket lifecycle rule capability (#1547)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>

Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
2022-02-10 16:25:59 -08:00
Lenin Alevski
829404b33c Fix session.permission npe (#1551)
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
2022-02-10 15:45:28 -08:00
Daniel Valdivia
610ec0bed4 Fix NPE on permissions (#1548)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
2022-02-10 13:45:18 -08:00
62 changed files with 1754 additions and 228 deletions

View File

@@ -106,3 +106,11 @@ clean:
docker:
@docker buildx build --output=type=docker --platform linux/amd64 -t $(TAG) --build-arg build_version=$(BUILD_VERSION) --build-arg build_time='$(BUILD_TIME)' .
release: swagger-gen
@echo "Generating Release: $(RELEASE)"
@make assets
@yq -i e '.spec.template.spec.containers[0].image |= "minio/console:$(RELEASE)"' k8s/operator-console/base/console-deployment.yaml
@yq -i e 'select(.kind == "Deployment").spec.template.spec.containers[0].image |= "minio/console:$(RELEASE)"' k8s/operator-console/standalone/console-deployment.yaml
@git add -u .
@git add portal-ui/build/

View File

@@ -50,21 +50,6 @@ func TestAddServiceAccount(t *testing.T) {
requestDataAddServiceAccount := map[string]interface{}{
"accessKey": "testuser1",
"secretKey": "password",
"policy": "{" +
"\n \"Version\": \"2012-10-17\"," +
"\n \"Statement\": [" +
"\n {" +
"\n \"Effect\": \"Allow\"," +
"\n \"Action\": [" +
"\n \"s3:GetBucketLocation\"," +
"\n \"s3:GetObject\"" +
"\n ]," +
"\n \"Resource\": [" +
"\n \"arn:aws:s3:::*\"" +
"\n ]" +
"\n }" +
"\n ]" +
"\n}",
}
fmt.Println("..............................TestServiceAccountPolicy(): Prepare the POST")
@@ -95,7 +80,51 @@ func TestAddServiceAccount(t *testing.T) {
assert.Equal(201, response.StatusCode, "Status Code is incorrect")
}
fmt.Println("...................................TestServiceAccountPolicy(): Remove user")
requestDataPolicy := map[string]interface{}{"policy": "{" +
"\n \"Version\": \"2012-10-17\"," +
"\n \"Statement\": [" +
"\n {" +
"\n \"Effect\": \"Allow\"," +
"\n \"Action\": [" +
"\n \"s3:GetBucketLocation\"," +
"\n \"s3:GetObject\"" +
"\n ]," +
"\n \"Resource\": [" +
"\n \"arn:aws:s3:::*\"" +
"\n ]" +
"\n }" +
"\n ]" +
"\n}",
}
fmt.Println("..............................TestServiceAccountPolicy(): Prepare the PUT")
requestDataJSON, _ = json.Marshal(requestDataPolicy)
requestDataBody = bytes.NewReader(requestDataJSON)
request, err = http.NewRequest(
"PUT", "http://localhost:9090/api/v1/service-accounts/testuser1/policy", requestDataBody)
if err != nil {
log.Println(err)
return
}
request.Header.Add("Cookie", fmt.Sprintf("token=%s", token))
request.Header.Add("Content-Type", "application/json")
fmt.Println(".................................TestServiceAccountPolicy(): Make the PUT")
response, err = client.Do(request)
if err != nil {
log.Println(err)
return
}
fmt.Println("..................................TestServiceAccountPolicy(): Verification")
fmt.Println(".................................TestServiceAccountPolicy(): PUT response")
fmt.Println(response)
fmt.Println("....................................TestServiceAccountPolicy(): PUT error")
fmt.Println(err)
if response != nil {
fmt.Println("POST StatusCode:", response.StatusCode)
assert.Equal(200, response.StatusCode, "Status Code is incorrect")
}
fmt.Println("...................................TestServiceAccountPolicy(): Check policy")
// Test policy
fmt.Println(".......................TestAddUserServiceAccount(): Create Data to add user")

View File

@@ -15,7 +15,7 @@ spec:
serviceAccountName: console-sa
containers:
- name: console
image: minio/console:v0.14.4
image: 'minio/console:v0.14.5'
imagePullPolicy: "IfNotPresent"
env:
- name: CONSOLE_OPERATOR_MODE

View File

@@ -32,7 +32,7 @@ spec:
spec:
containers:
- name: console
image: minio/console:v0.14.4
image: 'minio/console:v0.14.5'
imagePullPolicy: "IfNotPresent"
env:
- name: CONSOLE_MINIO_SERVER

View File

@@ -24,9 +24,12 @@ package models
import (
"context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddBucketLifecycle add bucket lifecycle
@@ -69,10 +72,65 @@ type AddBucketLifecycle struct {
// Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM
TransitionDays int32 `json:"transition_days,omitempty"`
// ILM Rule type (Expiry or transition)
// Enum: [expiry transition]
Type string `json:"type,omitempty"`
}
// Validate validates this add bucket lifecycle
func (m *AddBucketLifecycle) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateType(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
var addBucketLifecycleTypeTypePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["expiry","transition"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
addBucketLifecycleTypeTypePropEnum = append(addBucketLifecycleTypeTypePropEnum, v)
}
}
const (
// AddBucketLifecycleTypeExpiry captures enum value "expiry"
AddBucketLifecycleTypeExpiry string = "expiry"
// AddBucketLifecycleTypeTransition captures enum value "transition"
AddBucketLifecycleTypeTransition string = "transition"
)
// prop value enum
func (m *AddBucketLifecycle) validateTypeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, addBucketLifecycleTypeTypePropEnum, true); err != nil {
return err
}
return nil
}
func (m *AddBucketLifecycle) validateType(formats strfmt.Registry) error {
if swag.IsZero(m.Type) { // not required
return nil
}
// value enum
if err := m.validateTypeEnum("type", "body", m.Type); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
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/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddServiceAccountPolicyRequest add service account policy request
//
// swagger:model addServiceAccountPolicyRequest
type AddServiceAccountPolicyRequest struct {
// policy
// Required: true
Policy *string `json:"policy"`
}
// Validate validates this add service account policy request
func (m *AddServiceAccountPolicyRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePolicy(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AddServiceAccountPolicyRequest) validatePolicy(formats strfmt.Registry) error {
if err := validate.Required("policy", "body", m.Policy); err != nil {
return err
}
return nil
}
// ContextValidate validates this add service account policy request based on context it is used
func (m *AddServiceAccountPolicyRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *AddServiceAccountPolicyRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddServiceAccountPolicyRequest) UnmarshalBinary(b []byte) error {
var res AddServiceAccountPolicyRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,95 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
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"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// LifecycleRuleType lifecycle rule type
//
// swagger:model lifecycleRuleType
type LifecycleRuleType string
func NewLifecycleRuleType(value LifecycleRuleType) *LifecycleRuleType {
return &value
}
// Pointer returns a pointer to a freshly-allocated LifecycleRuleType.
func (m LifecycleRuleType) Pointer() *LifecycleRuleType {
return &m
}
const (
// LifecycleRuleTypeExpiry captures enum value "expiry"
LifecycleRuleTypeExpiry LifecycleRuleType = "expiry"
// LifecycleRuleTypeTransition captures enum value "transition"
LifecycleRuleTypeTransition LifecycleRuleType = "transition"
)
// for schema
var lifecycleRuleTypeEnum []interface{}
func init() {
var res []LifecycleRuleType
if err := json.Unmarshal([]byte(`["expiry","transition"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
lifecycleRuleTypeEnum = append(lifecycleRuleTypeEnum, v)
}
}
func (m LifecycleRuleType) validateLifecycleRuleTypeEnum(path, location string, value LifecycleRuleType) error {
if err := validate.EnumCase(path, location, value, lifecycleRuleTypeEnum, true); err != nil {
return err
}
return nil
}
// Validate validates this lifecycle rule type
func (m LifecycleRuleType) Validate(formats strfmt.Registry) error {
var res []error
// value enum
if err := m.validateLifecycleRuleTypeEnum("", "body", m); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validates this lifecycle rule type based on context it is used
func (m LifecycleRuleType) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}

View File

@@ -1,7 +1,7 @@
{
"files": {
"main.css": "./static/css/main.c4c1effe.css",
"main.js": "./static/js/main.e494763b.js",
"main.js": "./static/js/main.ab27ce1f.js",
"static/js/2178.7830bed4.chunk.js": "./static/js/2178.7830bed4.chunk.js",
"static/js/5282.e51b8c66.chunk.js": "./static/js/5282.e51b8c66.chunk.js",
"static/js/1409.a1f80372.chunk.js": "./static/js/1409.a1f80372.chunk.js",
@@ -47,8 +47,8 @@
"static/js/428.4625197b.chunk.js": "./static/js/428.4625197b.chunk.js",
"static/js/1069.57853a28.chunk.js": "./static/js/1069.57853a28.chunk.js",
"static/js/9080.516d04de.chunk.js": "./static/js/9080.516d04de.chunk.js",
"static/js/2094.ef1fbd5b.chunk.js": "./static/js/2094.ef1fbd5b.chunk.js",
"static/js/7950.041ee61e.chunk.js": "./static/js/7950.041ee61e.chunk.js",
"static/js/2094.8b6cdedb.chunk.js": "./static/js/2094.8b6cdedb.chunk.js",
"static/js/7950.a1c8a17e.chunk.js": "./static/js/7950.a1c8a17e.chunk.js",
"static/js/8967.ec9d9b6b.chunk.js": "./static/js/8967.ec9d9b6b.chunk.js",
"static/js/8961.1587a077.chunk.js": "./static/js/8961.1587a077.chunk.js",
"static/js/3967.94160f6f.chunk.js": "./static/js/3967.94160f6f.chunk.js",
@@ -86,7 +86,7 @@
"static/js/1973.34c45ee7.chunk.js": "./static/js/1973.34c45ee7.chunk.js",
"static/js/7187.b3ba71a1.chunk.js": "./static/js/7187.b3ba71a1.chunk.js",
"static/js/6173.0154f085.chunk.js": "./static/js/6173.0154f085.chunk.js",
"static/js/7146.699d8257.chunk.js": "./static/js/7146.699d8257.chunk.js",
"static/js/953.7e3f4f84.chunk.js": "./static/js/953.7e3f4f84.chunk.js",
"static/js/9924.0c2cdee6.chunk.js": "./static/js/9924.0c2cdee6.chunk.js",
"static/js/9193.840c0a00.chunk.js": "./static/js/9193.840c0a00.chunk.js",
"static/js/7451.3135dd72.chunk.js": "./static/js/7451.3135dd72.chunk.js",
@@ -134,7 +134,7 @@
"static/js/8016.b0ab3b67.chunk.js": "./static/js/8016.b0ab3b67.chunk.js",
"static/js/4817.2c511e72.chunk.js": "./static/js/4817.2c511e72.chunk.js",
"static/js/2253.d527f443.chunk.js": "./static/js/2253.d527f443.chunk.js",
"static/js/5482.c80a5ebb.chunk.js": "./static/js/5482.c80a5ebb.chunk.js",
"static/js/5482.dcaee6b1.chunk.js": "./static/js/5482.dcaee6b1.chunk.js",
"static/js/3538.60e98cef.chunk.js": "./static/js/3538.60e98cef.chunk.js",
"static/js/8749.fa0fb710.chunk.js": "./static/js/8749.fa0fb710.chunk.js",
"static/js/7348.b037b952.chunk.js": "./static/js/7348.b037b952.chunk.js",
@@ -145,6 +145,7 @@
"static/js/2594.77f64a1f.chunk.js": "./static/js/2594.77f64a1f.chunk.js",
"static/js/440.5bb0a106.chunk.js": "./static/js/440.5bb0a106.chunk.js",
"static/js/3045.0dea1c04.chunk.js": "./static/js/3045.0dea1c04.chunk.js",
"static/js/8750.02521688.chunk.js": "./static/js/8750.02521688.chunk.js",
"static/js/938.8f6a5aa1.chunk.js": "./static/js/938.8f6a5aa1.chunk.js",
"static/js/4105.4a4541e7.chunk.js": "./static/js/4105.4a4541e7.chunk.js",
"static/js/9876.3e5a4f83.chunk.js": "./static/js/9876.3e5a4f83.chunk.js",
@@ -158,7 +159,7 @@
"static/js/3453.cadd9dca.chunk.js": "./static/js/3453.cadd9dca.chunk.js",
"index.html": "./index.html",
"main.c4c1effe.css.map": "./static/css/main.c4c1effe.css.map",
"main.e494763b.js.map": "./static/js/main.e494763b.js.map",
"main.ab27ce1f.js.map": "./static/js/main.ab27ce1f.js.map",
"2178.7830bed4.chunk.js.map": "./static/js/2178.7830bed4.chunk.js.map",
"5282.e51b8c66.chunk.js.map": "./static/js/5282.e51b8c66.chunk.js.map",
"1409.a1f80372.chunk.js.map": "./static/js/1409.a1f80372.chunk.js.map",
@@ -204,8 +205,8 @@
"428.4625197b.chunk.js.map": "./static/js/428.4625197b.chunk.js.map",
"1069.57853a28.chunk.js.map": "./static/js/1069.57853a28.chunk.js.map",
"9080.516d04de.chunk.js.map": "./static/js/9080.516d04de.chunk.js.map",
"2094.ef1fbd5b.chunk.js.map": "./static/js/2094.ef1fbd5b.chunk.js.map",
"7950.041ee61e.chunk.js.map": "./static/js/7950.041ee61e.chunk.js.map",
"2094.8b6cdedb.chunk.js.map": "./static/js/2094.8b6cdedb.chunk.js.map",
"7950.a1c8a17e.chunk.js.map": "./static/js/7950.a1c8a17e.chunk.js.map",
"8967.ec9d9b6b.chunk.js.map": "./static/js/8967.ec9d9b6b.chunk.js.map",
"8961.1587a077.chunk.js.map": "./static/js/8961.1587a077.chunk.js.map",
"3967.94160f6f.chunk.js.map": "./static/js/3967.94160f6f.chunk.js.map",
@@ -243,7 +244,7 @@
"1973.34c45ee7.chunk.js.map": "./static/js/1973.34c45ee7.chunk.js.map",
"7187.b3ba71a1.chunk.js.map": "./static/js/7187.b3ba71a1.chunk.js.map",
"6173.0154f085.chunk.js.map": "./static/js/6173.0154f085.chunk.js.map",
"7146.699d8257.chunk.js.map": "./static/js/7146.699d8257.chunk.js.map",
"953.7e3f4f84.chunk.js.map": "./static/js/953.7e3f4f84.chunk.js.map",
"9924.0c2cdee6.chunk.js.map": "./static/js/9924.0c2cdee6.chunk.js.map",
"9193.840c0a00.chunk.js.map": "./static/js/9193.840c0a00.chunk.js.map",
"7451.3135dd72.chunk.js.map": "./static/js/7451.3135dd72.chunk.js.map",
@@ -291,7 +292,7 @@
"8016.b0ab3b67.chunk.js.map": "./static/js/8016.b0ab3b67.chunk.js.map",
"4817.2c511e72.chunk.js.map": "./static/js/4817.2c511e72.chunk.js.map",
"2253.d527f443.chunk.js.map": "./static/js/2253.d527f443.chunk.js.map",
"5482.c80a5ebb.chunk.js.map": "./static/js/5482.c80a5ebb.chunk.js.map",
"5482.dcaee6b1.chunk.js.map": "./static/js/5482.dcaee6b1.chunk.js.map",
"3538.60e98cef.chunk.js.map": "./static/js/3538.60e98cef.chunk.js.map",
"8749.fa0fb710.chunk.js.map": "./static/js/8749.fa0fb710.chunk.js.map",
"7348.b037b952.chunk.js.map": "./static/js/7348.b037b952.chunk.js.map",
@@ -302,6 +303,7 @@
"2594.77f64a1f.chunk.js.map": "./static/js/2594.77f64a1f.chunk.js.map",
"440.5bb0a106.chunk.js.map": "./static/js/440.5bb0a106.chunk.js.map",
"3045.0dea1c04.chunk.js.map": "./static/js/3045.0dea1c04.chunk.js.map",
"8750.02521688.chunk.js.map": "./static/js/8750.02521688.chunk.js.map",
"938.8f6a5aa1.chunk.js.map": "./static/js/938.8f6a5aa1.chunk.js.map",
"4105.4a4541e7.chunk.js.map": "./static/js/4105.4a4541e7.chunk.js.map",
"9876.3e5a4f83.chunk.js.map": "./static/js/9876.3e5a4f83.chunk.js.map",
@@ -316,6 +318,6 @@
},
"entrypoints": [
"static/css/main.c4c1effe.css",
"static/js/main.e494763b.js"
"static/js/main.ab27ce1f.js"
]
}

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.e494763b.js"></script><link href="./static/css/main.c4c1effe.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" fill="none" r="20.2" stroke-width="3.6"></circle></svg></div></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="/"/><meta content="width=device-width,initial-scale=1" name="viewport"/><meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color"/><meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color"/><meta content="MinIO Console" name="description"/><link href="./styles/root-styles.css" rel="stylesheet"/><link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180"/><link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"/><link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/><link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"/><link href="./manifest.json" rel="manifest"/><link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon"/><title>MinIO Console</title><script defer="defer" src="./static/js/main.ab27ce1f.js"></script><link href="./static/css/main.c4c1effe.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"><div id="loader-block"><svg class="loader-svg-container" viewBox="22 22 44 44"><circle class="loader-style MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate" cx="44" cy="44" fill="none" r="20.2" stroke-width="3.6"></circle></svg></div></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -179,6 +179,7 @@ const Account = ({ classes, displayErrorMessage }: IServiceAccountsProps) => {
const closePolicyModal = () => {
setPolicyOpen(false);
setLoading(true);
};
const confirmDeleteServiceAccount = (selectedServiceAccount: string) => {

View File

@@ -85,6 +85,18 @@ const ServiceAccountPolicy = ({
}
}, [loading, setLoading, setModalErrorSnackMessage, selectedAccessKey]);
const setPolicy = (event: React.FormEvent, newPolicy: string) => {
event.preventDefault();
api
.invoke("PUT", `/api/v1/service-accounts/${selectedAccessKey}/policy`, {policy: newPolicy})
.then((res) => {
closeModalAndRefresh();
})
.catch((err: ErrorResponseHandler) => {
setModalErrorSnackMessage(err);
});
};
return (
<ModalWrapper
title="Service Account Policy"
@@ -94,6 +106,13 @@ const ServiceAccountPolicy = ({
}}
titleIcon={<ChangeAccessPolicyIcon />}
>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
setPolicy(e, policyDefinition);
}}
>
<Grid container>
<Grid item xs={12} className={classes.codeMirrorContainer}>
<CodeMirrorWrapper
@@ -103,7 +122,6 @@ const ServiceAccountPolicy = ({
setPolicyDefinition(value);
}}
editorHeight={"350px"}
readOnly={true}
/>
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
@@ -118,8 +136,19 @@ const ServiceAccountPolicy = ({
>
Cancel
</Button>
<Button
type="submit"
variant="contained"
color="primary"
disabled={
loading
}
>
Set
</Button>
</Grid>
</Grid>
</form>
</ModalWrapper>
);
};

View File

@@ -166,6 +166,7 @@ const AddLifecycleModal = ({
}
const lifecycleInsert = {
type: ilmType,
prefix,
tags,
expired_object_delete_marker: expiredObjectDM,

View File

@@ -42,6 +42,7 @@ import SecureComponent, {
} from "../../../../common/SecureComponent/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import RBIconButton from "./SummaryItems/RBIconButton";
import DeleteBucketLifecycleRule from "./DeleteBucketLifecycleRule";
const styles = (theme: Theme) =>
createStyles({
@@ -73,6 +74,9 @@ const BucketLifecyclePanel = ({
const [editLifecycleOpen, setEditLifecycleOpen] = useState<boolean>(false);
const [selectedLifecycleRule, setSelectedLifecycleRule] =
useState<LifeCycleItem | null>(null);
const [deleteLifecycleOpen, setDeleteLifecycleOpen] =
useState<boolean>(false);
const [selectedID, setSelectedID] = useState<string | null>(null);
const bucketName = match.params["bucketName"];
@@ -99,6 +103,7 @@ const BucketLifecyclePanel = ({
})
.catch((err: ErrorResponseHandler) => {
console.error(err);
setLifecycleRecords([]);
setLoadingLifecycle(false);
});
} else {
@@ -127,6 +132,15 @@ const BucketLifecyclePanel = ({
}
};
const closeDelLCRefresh = (refresh: boolean) => {
setDeleteLifecycleOpen(false);
setSelectedID(null);
if (refresh) {
setLoadingLifecycle(true);
}
};
const expirationRender = (expiration: any) => {
if (expiration.days) {
return `${expiration.days} day${expiration.days > 1 ? "s" : ""}`;
@@ -194,6 +208,14 @@ const BucketLifecyclePanel = ({
setEditLifecycleOpen(true);
},
},
{
type: "delete",
onClick(valueToDelete: string): any {
setSelectedID(valueToDelete);
setDeleteLifecycleOpen(true);
},
sendOnlyId: true,
},
];
return (
@@ -213,6 +235,14 @@ const BucketLifecyclePanel = ({
closeModalAndRefresh={closeAddLCAndRefresh}
/>
)}
{deleteLifecycleOpen && selectedID && (
<DeleteBucketLifecycleRule
id={selectedID}
bucket={bucketName}
deleteOpen={deleteLifecycleOpen}
onCloseAndRefresh={closeDelLCRefresh}
/>
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<PanelTitle>Lifecycle Rules</PanelTitle>

View File

@@ -0,0 +1,93 @@
// 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 <http://www.gnu.org/licenses/>.
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { DialogContentText } from "@mui/material";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
import { ErrorResponseHandler } from "../../../../common/types";
import { setErrorSnackMessage } from "../../../../actions";
import { ConfirmDeleteIcon } from "../../../../icons";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import api from "../../../../common/api";
interface IDeleteLifecycleRule {
deleteOpen: boolean;
onCloseAndRefresh: (refresh: boolean) => any;
bucket: string;
id: string;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
...modalBasic,
});
const DeleteBucketLifecycleRule = ({
onCloseAndRefresh,
deleteOpen,
bucket,
id,
setErrorSnackMessage,
}: IDeleteLifecycleRule) => {
const [deletingRule, setDeletingRule] = useState<boolean>(false);
useEffect(() => {
if (deletingRule) {
api
.invoke("DELETE", `/api/v1/buckets/${bucket}/lifecycle/${id}`)
.then((res) => {
setDeletingRule(false);
onCloseAndRefresh(true);
})
.catch((err: ErrorResponseHandler) => {
setDeletingRule(false);
setErrorSnackMessage(err);
});
}
}, [deletingRule, bucket, id, onCloseAndRefresh, setErrorSnackMessage]);
const onConfirmDelete = () => {
setDeletingRule(true);
};
return (
<ConfirmDialog
title={`Delete Lifecycle Rule`}
confirmText={"Delete"}
isOpen={deleteOpen}
isLoading={deletingRule}
onConfirm={onConfirmDelete}
titleIcon={<ConfirmDeleteIcon />}
onClose={() => onCloseAndRefresh(false)}
confirmationContent={
<DialogContentText>
Are you sure you want to delete the <strong>{id}</strong> rule?
</DialogContentText>
}
/>
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(DeleteBucketLifecycleRule));

View File

@@ -141,7 +141,6 @@ const EditLifecycleConfiguration = ({
}, [ilmType, expiryDays, transitionDays, storageClass]);
useEffect(() => {
console.log("lifecycle::", lifecycle);
if (lifecycle.status === "Enabled") {
setEnabled(true);
}

View File

@@ -191,7 +191,9 @@ const ListBuckets = ({
};
const createBucketButtonResources: string[] =
Array.from(Object.keys(session.permissions)) || [];
session && session.permissions
? Array.from(Object.keys(session.permissions)) || []
: [];
return (
<Fragment>

View File

@@ -220,7 +220,9 @@ const Console = ({
path: IAM_PAGES.ADD_BUCKETS,
customPermissionFnc: () => {
const createBucketResources: string[] =
Array.from(Object.keys(session.permissions)) || [];
session && session.permissions
? Array.from(Object.keys(session.permissions)) || []
: [];
return hasPermission(
createBucketResources,
IAM_PAGES_PERMISSIONS[IAM_PAGES.ADD_BUCKETS]

View File

@@ -99,6 +99,7 @@ type MinioAdmin interface {
listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error)
deleteServiceAccount(ctx context.Context, serviceAccount string) error
infoServiceAccount(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error)
updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error
// Remote Buckets
listRemoteBuckets(ctx context.Context, bucket, arnType string) (targets []madmin.BucketTarget, err error)
getRemoteBucket(ctx context.Context, bucket, arnType string) (targets *madmin.BucketTarget, err error)
@@ -312,6 +313,11 @@ func (ac AdminClient) infoServiceAccount(ctx context.Context, serviceAccount str
return ac.Client.InfoServiceAccount(ctx, serviceAccount)
}
// implements madmin.UpdateServiceAccount()
func (ac AdminClient) updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error {
return ac.Client.UpdateServiceAccount(ctx, serviceAccount, opts)
}
// AccountInfo implements madmin.AccountInfo()
func (ac AdminClient) AccountInfo(ctx context.Context) (madmin.AccountInfo, error) {
return ac.Client.AccountInfo(ctx, madmin.AccountOpts{})

View File

@@ -1061,6 +1061,38 @@ func init() {
}
}
}
},
"delete": {
"tags": [
"UserAPI"
],
"summary": "Delete Lifecycle rule",
"operationId": "DeleteBucketLifecycleRule",
"parameters": [
{
"type": "string",
"name": "bucket_name",
"in": "path",
"required": true
},
{
"type": "string",
"name": "lifecycle_id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/buckets/{bucket_name}/object-locking": {
@@ -3152,6 +3184,40 @@ func init() {
}
}
}
},
"put": {
"tags": [
"UserAPI"
],
"summary": "Set Service Account Policy",
"operationId": "SetServiceAccountPolicy",
"parameters": [
{
"type": "string",
"name": "access_key",
"in": "path",
"required": true
},
{
"name": "policy",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/addServiceAccountPolicyRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/service/restart": {
@@ -3831,6 +3897,14 @@ func init() {
"type": "integer",
"format": "int32",
"default": 0
},
"type": {
"description": "ILM Rule type (Expiry or transition)",
"type": "string",
"enum": [
"expiry",
"transition"
]
}
}
},
@@ -3878,6 +3952,17 @@ func init() {
}
}
},
"addServiceAccountPolicyRequest": {
"type": "object",
"required": [
"policy"
],
"properties": {
"policy": {
"type": "string"
}
}
},
"addUserRequest": {
"type": "object",
"required": [
@@ -7234,6 +7319,38 @@ func init() {
}
}
}
},
"delete": {
"tags": [
"UserAPI"
],
"summary": "Delete Lifecycle rule",
"operationId": "DeleteBucketLifecycleRule",
"parameters": [
{
"type": "string",
"name": "bucket_name",
"in": "path",
"required": true
},
{
"type": "string",
"name": "lifecycle_id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/buckets/{bucket_name}/object-locking": {
@@ -9325,6 +9442,40 @@ func init() {
}
}
}
},
"put": {
"tags": [
"UserAPI"
],
"summary": "Set Service Account Policy",
"operationId": "SetServiceAccountPolicy",
"parameters": [
{
"type": "string",
"name": "access_key",
"in": "path",
"required": true
},
{
"name": "policy",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/addServiceAccountPolicyRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/service/restart": {
@@ -10122,6 +10273,14 @@ func init() {
"type": "integer",
"format": "int32",
"default": 0
},
"type": {
"description": "ILM Rule type (Expiry or transition)",
"type": "string",
"enum": [
"expiry",
"transition"
]
}
}
},
@@ -10169,6 +10328,17 @@ func init() {
}
}
},
"addServiceAccountPolicyRequest": {
"type": "object",
"required": [
"policy"
],
"properties": {
"policy": {
"type": "string"
}
}
},
"addUserRequest": {
"type": "object",
"required": [

View File

@@ -137,6 +137,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
UserAPIDeleteBucketEventHandler: user_api.DeleteBucketEventHandlerFunc(func(params user_api.DeleteBucketEventParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation user_api.DeleteBucketEvent has not yet been implemented")
}),
UserAPIDeleteBucketLifecycleRuleHandler: user_api.DeleteBucketLifecycleRuleHandlerFunc(func(params user_api.DeleteBucketLifecycleRuleParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation user_api.DeleteBucketLifecycleRule has not yet been implemented")
}),
UserAPIDeleteBucketReplicationRuleHandler: user_api.DeleteBucketReplicationRuleHandlerFunc(func(params user_api.DeleteBucketReplicationRuleParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation user_api.DeleteBucketReplicationRule has not yet been implemented")
}),
@@ -353,6 +356,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
AdminAPISetPolicyMultipleHandler: admin_api.SetPolicyMultipleHandlerFunc(func(params admin_api.SetPolicyMultipleParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.SetPolicyMultiple has not yet been implemented")
}),
UserAPISetServiceAccountPolicyHandler: user_api.SetServiceAccountPolicyHandlerFunc(func(params user_api.SetServiceAccountPolicyParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation user_api.SetServiceAccountPolicy has not yet been implemented")
}),
UserAPIShareObjectHandler: user_api.ShareObjectHandlerFunc(func(params user_api.ShareObjectParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation user_api.ShareObject has not yet been implemented")
}),
@@ -492,6 +498,8 @@ type ConsoleAPI struct {
UserAPIDeleteBucketHandler user_api.DeleteBucketHandler
// UserAPIDeleteBucketEventHandler sets the operation handler for the delete bucket event operation
UserAPIDeleteBucketEventHandler user_api.DeleteBucketEventHandler
// UserAPIDeleteBucketLifecycleRuleHandler sets the operation handler for the delete bucket lifecycle rule operation
UserAPIDeleteBucketLifecycleRuleHandler user_api.DeleteBucketLifecycleRuleHandler
// UserAPIDeleteBucketReplicationRuleHandler sets the operation handler for the delete bucket replication rule operation
UserAPIDeleteBucketReplicationRuleHandler user_api.DeleteBucketReplicationRuleHandler
// UserAPIDeleteMultipleObjectsHandler sets the operation handler for the delete multiple objects operation
@@ -636,6 +644,8 @@ type ConsoleAPI struct {
AdminAPISetPolicyHandler admin_api.SetPolicyHandler
// AdminAPISetPolicyMultipleHandler sets the operation handler for the set policy multiple operation
AdminAPISetPolicyMultipleHandler admin_api.SetPolicyMultipleHandler
// UserAPISetServiceAccountPolicyHandler sets the operation handler for the set service account policy operation
UserAPISetServiceAccountPolicyHandler user_api.SetServiceAccountPolicyHandler
// UserAPIShareObjectHandler sets the operation handler for the share object operation
UserAPIShareObjectHandler user_api.ShareObjectHandler
// AdminAPISubnetInfoHandler sets the operation handler for the subnet info operation
@@ -819,6 +829,9 @@ func (o *ConsoleAPI) Validate() error {
if o.UserAPIDeleteBucketEventHandler == nil {
unregistered = append(unregistered, "user_api.DeleteBucketEventHandler")
}
if o.UserAPIDeleteBucketLifecycleRuleHandler == nil {
unregistered = append(unregistered, "user_api.DeleteBucketLifecycleRuleHandler")
}
if o.UserAPIDeleteBucketReplicationRuleHandler == nil {
unregistered = append(unregistered, "user_api.DeleteBucketReplicationRuleHandler")
}
@@ -1035,6 +1048,9 @@ func (o *ConsoleAPI) Validate() error {
if o.AdminAPISetPolicyMultipleHandler == nil {
unregistered = append(unregistered, "admin_api.SetPolicyMultipleHandler")
}
if o.UserAPISetServiceAccountPolicyHandler == nil {
unregistered = append(unregistered, "user_api.SetServiceAccountPolicyHandler")
}
if o.UserAPIShareObjectHandler == nil {
unregistered = append(unregistered, "user_api.ShareObjectHandler")
}
@@ -1272,6 +1288,10 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["DELETE"] == nil {
o.handlers["DELETE"] = make(map[string]http.Handler)
}
o.handlers["DELETE"]["/buckets/{bucket_name}/lifecycle/{lifecycle_id}"] = user_api.NewDeleteBucketLifecycleRule(o.context, o.UserAPIDeleteBucketLifecycleRuleHandler)
if o.handlers["DELETE"] == nil {
o.handlers["DELETE"] = make(map[string]http.Handler)
}
o.handlers["DELETE"]["/buckets/{bucket_name}/replication/{rule_id}"] = user_api.NewDeleteBucketReplicationRule(o.context, o.UserAPIDeleteBucketReplicationRuleHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
@@ -1557,6 +1577,10 @@ func (o *ConsoleAPI) initHandlerCache() {
o.handlers["PUT"] = make(map[string]http.Handler)
}
o.handlers["PUT"]["/set-policy-multi"] = admin_api.NewSetPolicyMultiple(o.context, o.AdminAPISetPolicyMultipleHandler)
if o.handlers["PUT"] == nil {
o.handlers["PUT"] = make(map[string]http.Handler)
}
o.handlers["PUT"]["/service-accounts/{access_key}/policy"] = user_api.NewSetServiceAccountPolicy(o.context, o.UserAPISetServiceAccountPolicyHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
)
// DeleteBucketLifecycleRuleHandlerFunc turns a function with the right signature into a delete bucket lifecycle rule handler
type DeleteBucketLifecycleRuleHandlerFunc func(DeleteBucketLifecycleRuleParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn DeleteBucketLifecycleRuleHandlerFunc) Handle(params DeleteBucketLifecycleRuleParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// DeleteBucketLifecycleRuleHandler interface for that can handle valid delete bucket lifecycle rule params
type DeleteBucketLifecycleRuleHandler interface {
Handle(DeleteBucketLifecycleRuleParams, *models.Principal) middleware.Responder
}
// NewDeleteBucketLifecycleRule creates a new http.Handler for the delete bucket lifecycle rule operation
func NewDeleteBucketLifecycleRule(ctx *middleware.Context, handler DeleteBucketLifecycleRuleHandler) *DeleteBucketLifecycleRule {
return &DeleteBucketLifecycleRule{Context: ctx, Handler: handler}
}
/* DeleteBucketLifecycleRule swagger:route DELETE /buckets/{bucket_name}/lifecycle/{lifecycle_id} UserAPI deleteBucketLifecycleRule
Delete Lifecycle rule
*/
type DeleteBucketLifecycleRule struct {
Context *middleware.Context
Handler DeleteBucketLifecycleRuleHandler
}
func (o *DeleteBucketLifecycleRule) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewDeleteBucketLifecycleRuleParams()
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)
}

View File

@@ -0,0 +1,112 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
"github.com/go-openapi/strfmt"
)
// NewDeleteBucketLifecycleRuleParams creates a new DeleteBucketLifecycleRuleParams object
//
// There are no default values defined in the spec.
func NewDeleteBucketLifecycleRuleParams() DeleteBucketLifecycleRuleParams {
return DeleteBucketLifecycleRuleParams{}
}
// DeleteBucketLifecycleRuleParams contains all the bound params for the delete bucket lifecycle rule operation
// typically these are obtained from a http.Request
//
// swagger:parameters DeleteBucketLifecycleRule
type DeleteBucketLifecycleRuleParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
BucketName string
/*
Required: true
In: path
*/
LifecycleID string
}
// 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 NewDeleteBucketLifecycleRuleParams() beforehand.
func (o *DeleteBucketLifecycleRuleParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rBucketName, rhkBucketName, _ := route.Params.GetOK("bucket_name")
if err := o.bindBucketName(rBucketName, rhkBucketName, route.Formats); err != nil {
res = append(res, err)
}
rLifecycleID, rhkLifecycleID, _ := route.Params.GetOK("lifecycle_id")
if err := o.bindLifecycleID(rLifecycleID, rhkLifecycleID, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindBucketName binds and validates parameter BucketName from path.
func (o *DeleteBucketLifecycleRuleParams) bindBucketName(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.BucketName = raw
return nil
}
// bindLifecycleID binds and validates parameter LifecycleID from path.
func (o *DeleteBucketLifecycleRuleParams) bindLifecycleID(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.LifecycleID = raw
return nil
}

View File

@@ -0,0 +1,113 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
)
// DeleteBucketLifecycleRuleNoContentCode is the HTTP code returned for type DeleteBucketLifecycleRuleNoContent
const DeleteBucketLifecycleRuleNoContentCode int = 204
/*DeleteBucketLifecycleRuleNoContent A successful response.
swagger:response deleteBucketLifecycleRuleNoContent
*/
type DeleteBucketLifecycleRuleNoContent struct {
}
// NewDeleteBucketLifecycleRuleNoContent creates DeleteBucketLifecycleRuleNoContent with default headers values
func NewDeleteBucketLifecycleRuleNoContent() *DeleteBucketLifecycleRuleNoContent {
return &DeleteBucketLifecycleRuleNoContent{}
}
// WriteResponse to the client
func (o *DeleteBucketLifecycleRuleNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(204)
}
/*DeleteBucketLifecycleRuleDefault Generic error response.
swagger:response deleteBucketLifecycleRuleDefault
*/
type DeleteBucketLifecycleRuleDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewDeleteBucketLifecycleRuleDefault creates DeleteBucketLifecycleRuleDefault with default headers values
func NewDeleteBucketLifecycleRuleDefault(code int) *DeleteBucketLifecycleRuleDefault {
if code <= 0 {
code = 500
}
return &DeleteBucketLifecycleRuleDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the delete bucket lifecycle rule default response
func (o *DeleteBucketLifecycleRuleDefault) WithStatusCode(code int) *DeleteBucketLifecycleRuleDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the delete bucket lifecycle rule default response
func (o *DeleteBucketLifecycleRuleDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the delete bucket lifecycle rule default response
func (o *DeleteBucketLifecycleRuleDefault) WithPayload(payload *models.Error) *DeleteBucketLifecycleRuleDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the delete bucket lifecycle rule default response
func (o *DeleteBucketLifecycleRuleDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *DeleteBucketLifecycleRuleDefault) 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
}
}
}

View File

@@ -0,0 +1,124 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
"strings"
)
// DeleteBucketLifecycleRuleURL generates an URL for the delete bucket lifecycle rule operation
type DeleteBucketLifecycleRuleURL struct {
BucketName string
LifecycleID string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// 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 *DeleteBucketLifecycleRuleURL) WithBasePath(bp string) *DeleteBucketLifecycleRuleURL {
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 *DeleteBucketLifecycleRuleURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *DeleteBucketLifecycleRuleURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/buckets/{bucket_name}/lifecycle/{lifecycle_id}"
bucketName := o.BucketName
if bucketName != "" {
_path = strings.Replace(_path, "{bucket_name}", bucketName, -1)
} else {
return nil, errors.New("bucketName is required on DeleteBucketLifecycleRuleURL")
}
lifecycleID := o.LifecycleID
if lifecycleID != "" {
_path = strings.Replace(_path, "{lifecycle_id}", lifecycleID, -1)
} else {
return nil, errors.New("lifecycleId is required on DeleteBucketLifecycleRuleURL")
}
_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 *DeleteBucketLifecycleRuleURL) 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 *DeleteBucketLifecycleRuleURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *DeleteBucketLifecycleRuleURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on DeleteBucketLifecycleRuleURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on DeleteBucketLifecycleRuleURL")
}
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 *DeleteBucketLifecycleRuleURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
)
// SetServiceAccountPolicyHandlerFunc turns a function with the right signature into a set service account policy handler
type SetServiceAccountPolicyHandlerFunc func(SetServiceAccountPolicyParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn SetServiceAccountPolicyHandlerFunc) Handle(params SetServiceAccountPolicyParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// SetServiceAccountPolicyHandler interface for that can handle valid set service account policy params
type SetServiceAccountPolicyHandler interface {
Handle(SetServiceAccountPolicyParams, *models.Principal) middleware.Responder
}
// NewSetServiceAccountPolicy creates a new http.Handler for the set service account policy operation
func NewSetServiceAccountPolicy(ctx *middleware.Context, handler SetServiceAccountPolicyHandler) *SetServiceAccountPolicy {
return &SetServiceAccountPolicy{Context: ctx, Handler: handler}
}
/* SetServiceAccountPolicy swagger:route PUT /service-accounts/{access_key}/policy UserAPI setServiceAccountPolicy
Set Service Account Policy
*/
type SetServiceAccountPolicy struct {
Context *middleware.Context
Handler SetServiceAccountPolicyHandler
}
func (o *SetServiceAccountPolicy) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewSetServiceAccountPolicyParams()
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)
}

View File

@@ -0,0 +1,127 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"io"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
"github.com/minio/console/models"
)
// NewSetServiceAccountPolicyParams creates a new SetServiceAccountPolicyParams object
//
// There are no default values defined in the spec.
func NewSetServiceAccountPolicyParams() SetServiceAccountPolicyParams {
return SetServiceAccountPolicyParams{}
}
// SetServiceAccountPolicyParams contains all the bound params for the set service account policy operation
// typically these are obtained from a http.Request
//
// swagger:parameters SetServiceAccountPolicy
type SetServiceAccountPolicyParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
AccessKey string
/*
Required: true
In: body
*/
Policy *models.AddServiceAccountPolicyRequest
}
// 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 NewSetServiceAccountPolicyParams() beforehand.
func (o *SetServiceAccountPolicyParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rAccessKey, rhkAccessKey, _ := route.Params.GetOK("access_key")
if err := o.bindAccessKey(rAccessKey, rhkAccessKey, route.Formats); err != nil {
res = append(res, err)
}
if runtime.HasBody(r) {
defer r.Body.Close()
var body models.AddServiceAccountPolicyRequest
if err := route.Consumer.Consume(r.Body, &body); err != nil {
if err == io.EOF {
res = append(res, errors.Required("policy", "body", ""))
} else {
res = append(res, errors.NewParseError("policy", "body", "", err))
}
} else {
// validate body object
if err := body.Validate(route.Formats); err != nil {
res = append(res, err)
}
ctx := validate.WithOperationRequest(context.Background())
if err := body.ContextValidate(ctx, route.Formats); err != nil {
res = append(res, err)
}
if len(res) == 0 {
o.Policy = &body
}
}
} else {
res = append(res, errors.Required("policy", "body", ""))
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindAccessKey binds and validates parameter AccessKey from path.
func (o *SetServiceAccountPolicyParams) bindAccessKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.AccessKey = raw
return nil
}

View File

@@ -0,0 +1,113 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
)
// SetServiceAccountPolicyOKCode is the HTTP code returned for type SetServiceAccountPolicyOK
const SetServiceAccountPolicyOKCode int = 200
/*SetServiceAccountPolicyOK A successful response.
swagger:response setServiceAccountPolicyOK
*/
type SetServiceAccountPolicyOK struct {
}
// NewSetServiceAccountPolicyOK creates SetServiceAccountPolicyOK with default headers values
func NewSetServiceAccountPolicyOK() *SetServiceAccountPolicyOK {
return &SetServiceAccountPolicyOK{}
}
// WriteResponse to the client
func (o *SetServiceAccountPolicyOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(200)
}
/*SetServiceAccountPolicyDefault Generic error response.
swagger:response setServiceAccountPolicyDefault
*/
type SetServiceAccountPolicyDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewSetServiceAccountPolicyDefault creates SetServiceAccountPolicyDefault with default headers values
func NewSetServiceAccountPolicyDefault(code int) *SetServiceAccountPolicyDefault {
if code <= 0 {
code = 500
}
return &SetServiceAccountPolicyDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the set service account policy default response
func (o *SetServiceAccountPolicyDefault) WithStatusCode(code int) *SetServiceAccountPolicyDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the set service account policy default response
func (o *SetServiceAccountPolicyDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the set service account policy default response
func (o *SetServiceAccountPolicyDefault) WithPayload(payload *models.Error) *SetServiceAccountPolicyDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the set service account policy default response
func (o *SetServiceAccountPolicyDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SetServiceAccountPolicyDefault) 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
}
}
}

View File

@@ -0,0 +1,116 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2021 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 <http://www.gnu.org/licenses/>.
//
package user_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"
"strings"
)
// SetServiceAccountPolicyURL generates an URL for the set service account policy operation
type SetServiceAccountPolicyURL struct {
AccessKey string
_basePath string
// avoid unkeyed usage
_ struct{}
}
// 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 *SetServiceAccountPolicyURL) WithBasePath(bp string) *SetServiceAccountPolicyURL {
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 *SetServiceAccountPolicyURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *SetServiceAccountPolicyURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/service-accounts/{access_key}/policy"
accessKey := o.AccessKey
if accessKey != "" {
_path = strings.Replace(_path, "{access_key}", accessKey, -1)
} else {
return nil, errors.New("accessKey is required on SetServiceAccountPolicyURL")
}
_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 *SetServiceAccountPolicyURL) 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 *SetServiceAccountPolicyURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *SetServiceAccountPolicyURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on SetServiceAccountPolicyURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on SetServiceAccountPolicyURL")
}
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 *SetServiceAccountPolicyURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -19,6 +19,7 @@ package restapi
import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"time"
@@ -61,6 +62,14 @@ func registerBucketsLifecycleHandlers(api *operations.ConsoleAPI) {
return user_api.NewUpdateBucketLifecycleOK()
})
api.UserAPIDeleteBucketLifecycleRuleHandler = user_api.DeleteBucketLifecycleRuleHandlerFunc(func(params user_api.DeleteBucketLifecycleRuleParams, session *models.Principal) middleware.Responder {
err := getDeleteBucketLifecycleRule(session, params)
if err != nil {
return user_api.NewDeleteBucketLifecycleRuleDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewDeleteBucketLifecycleRuleNoContent()
})
}
// getBucketLifecycle() gets lifecycle lists for a bucket from MinIO API and returns their implementations
@@ -152,57 +161,28 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api
opts := ilm.LifecycleOptions{}
// Verify if transition items are set
if params.Body.ExpiryDate == "" && params.Body.ExpiryDays == 0 {
if params.Body.TransitionDate != "" && params.Body.TransitionDays != 0 {
return errors.New("only one transition configuration can be set (days or date)")
}
if params.Body.ExpiryDate != "" || params.Body.ExpiryDays != 0 {
return errors.New("expiry cannot be set when transition is being configured")
}
if params.Body.NoncurrentversionExpirationDays != 0 {
return errors.New("non current version Expiration Days cannot be set when transition is being configured")
}
if params.Body.TransitionDate != "" {
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
TransitionDate: params.Body.TransitionDate,
StorageClass: strings.ToUpper(params.Body.StorageClass),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
}
} else if params.Body.TransitionDays != 0 {
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)),
StorageClass: strings.ToUpper(params.Body.StorageClass),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
}
}
} else if params.Body.TransitionDate == "" && params.Body.TransitionDays == 0 {
// Verify if expiry items are set
if params.Body.ExpiryDate != "" && params.Body.ExpiryDays != 0 {
// Verify if transition rule is requested
if params.Body.Type == models.AddBucketLifecycleTypeTransition {
if params.Body.TransitionDays == 0 && params.Body.NoncurrentversionTransitionDays == 0 {
return errors.New("only one expiry configuration can be set (days or date)")
}
if params.Body.TransitionDate != "" || params.Body.TransitionDays != 0 {
return errors.New("transition cannot be set when expiry is being configured")
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)),
StorageClass: strings.ToUpper(params.Body.StorageClass),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
IsTransitionDaysSet: params.Body.TransitionDays != 0,
IsNoncurrentVersionTransitionDaysSet: params.Body.NoncurrentversionTransitionDays != 0,
}
} else if params.Body.Type == models.AddBucketLifecycleTypeExpiry {
// Verify if expiry items are set
if params.Body.NoncurrentversionTransitionDays != 0 {
return errors.New("non current version Transition Days cannot be set when expiry is being configured")
}
@@ -211,33 +191,20 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api
return errors.New("non current version Transition Storage Class cannot be set when expiry is being configured")
}
if params.Body.ExpiryDate != "" {
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiryDate: params.Body.ExpiryDate,
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
}
} else if params.Body.ExpiryDays != 0 {
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
}
opts = ilm.LifecycleOptions{
ID: id,
Prefix: params.Body.Prefix,
Status: !params.Body.Disable,
IsTagsSet: params.Body.Tags != "",
Tags: params.Body.Tags,
ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)),
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
}
} else {
// Non set, we return error
return errors.New("no valid configuration is set")
return errors.New("no valid configuration requested")
}
var err2 *probe.Error
@@ -326,7 +293,7 @@ func editBucketLifecycle(ctx context.Context, client MinioClient, params user_ap
} else {
// Non set, we return error
return errors.New("transition and expiry cannot be set for the same rule")
return errors.New("no valid configuration requested")
}
var err2 *probe.Error
@@ -338,7 +305,7 @@ func editBucketLifecycle(ctx context.Context, client MinioClient, params user_ap
return client.setBucketLifecycle(ctx, params.BucketName, lfcCfg)
}
// getEditBucketLifecycleRule returns the response of bucket lyfecycle tier edit
// getEditBucketLifecycleRule returns the response of bucket lifecycle tier edit
func getEditBucketLifecycleRule(session *models.Principal, params user_api.UpdateBucketLifecycleParams) *models.Error {
ctx := context.Background()
mClient, err := newMinioClient(session)
@@ -356,3 +323,56 @@ func getEditBucketLifecycleRule(session *models.Principal, params user_api.Updat
return nil
}
// deleteBucketLifecycle deletes lifecycle rule by passing an empty rule to a selected ID
func deleteBucketLifecycle(ctx context.Context, client MinioClient, params user_api.DeleteBucketLifecycleRuleParams) error {
// Configuration that is already set.
lfcCfg, err := client.getLifecycleRules(ctx, params.BucketName)
if err != nil {
if e := err; minio.ToErrorResponse(e).Code == "NoSuchLifecycleConfiguration" {
lfcCfg = lifecycle.NewConfiguration()
} else {
return err
}
}
if len(lfcCfg.Rules) == 0 {
return errors.New("no rules available to delete")
}
var newRules []lifecycle.Rule
for _, rule := range lfcCfg.Rules {
if rule.ID != params.LifecycleID {
newRules = append(newRules, rule)
}
}
if len(newRules) == len(lfcCfg.Rules) && len(lfcCfg.Rules) > 0 {
// rule doesn't exist
return fmt.Errorf("lifecycle rule for id '%s' doesn't exist", params.LifecycleID)
}
lfcCfg.Rules = newRules
return client.setBucketLifecycle(ctx, params.BucketName, lfcCfg)
}
// getDeleteBucketLifecycleRule returns the response of bucket lifecycle tier delete
func getDeleteBucketLifecycleRule(session *models.Principal, params user_api.DeleteBucketLifecycleRuleParams) *models.Error {
ctx := context.Background()
mClient, err := newMinioClient(session)
if err != nil {
return prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
err = deleteBucketLifecycle(ctx, minioClient, params)
if err != nil {
return prepareError(err)
}
return nil
}

View File

@@ -163,9 +163,12 @@ func TestSetLifecycleRule(t *testing.T) {
return &mockLifecycle, nil
}
expiryRule := "expiry"
insertMock := user_api.AddBucketLifecycleParams{
BucketName: "testBucket",
Body: &models.AddBucketLifecycle{
Type: expiryRule,
Disable: false,
ExpiredObjectDeleteMarker: false,
ExpiryDays: int32(16),
@@ -290,3 +293,75 @@ func TestUpdateLifecycleRule(t *testing.T) {
assert.Equal(errors.New("error setting lifecycle"), err2, fmt.Sprintf("Failed on %s: Error returned", function))
}
func TestDeleteLifecycleRule(t *testing.T) {
assert := assert.New(t)
// mock minIO client
minClient := minioClientMock{}
function := "deleteBucketLifecycle()"
ctx := context.Background()
minioSetBucketLifecycleMock = func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error {
return nil
}
// Test-1 : deleteBucketLifecycle() get list of events for a particular bucket only one config (get lifecycle mock)
// mock create request
mockLifecycle := lifecycle.Configuration{
Rules: []lifecycle.Rule{
{
ID: "TESTRULE",
Expiration: lifecycle.Expiration{Days: 15},
Status: "Enabled",
RuleFilter: lifecycle.Filter{Tag: lifecycle.Tag{Key: "tag1", Value: "val1"}, And: lifecycle.And{Prefix: "prefix1"}},
},
{
ID: "TESTRULE2",
Transition: lifecycle.Transition{Days: 10, StorageClass: "TESTSTCLASS"},
Status: "Enabled",
RuleFilter: lifecycle.Filter{Tag: lifecycle.Tag{Key: "tag1", Value: "val1"}, And: lifecycle.And{Prefix: "prefix1"}},
},
},
}
minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) {
return &mockLifecycle, nil
}
// Test-2 : deleteBucketLifecycle() try to delete an available rule
availableParams := user_api.DeleteBucketLifecycleRuleParams{
LifecycleID: "TESTRULE2",
BucketName: "testBucket",
}
err := deleteBucketLifecycle(ctx, minClient, availableParams)
assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function))
// Test-3 : deleteBucketLifecycle() returns error trying to delete a non available rule
nonAvailableParams := user_api.DeleteBucketLifecycleRuleParams{
LifecycleID: "INVALIDTESTRULE",
BucketName: "testBucket",
}
err2 := deleteBucketLifecycle(ctx, minClient, nonAvailableParams)
assert.Equal(fmt.Errorf("lifecycle rule for id '%s' doesn't exist", nonAvailableParams.LifecycleID), err2, fmt.Sprintf("Failed on %s: Error returned", function))
// Test-4 : deleteBucketLifecycle() returns error trying to delete a rule when no rules are available
mockLifecycle2 := lifecycle.Configuration{
Rules: []lifecycle.Rule{},
}
minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) {
return &mockLifecycle2, nil
}
err3 := deleteBucketLifecycle(ctx, minClient, nonAvailableParams)
assert.Equal(errors.New("no rules available to delete"), err3, fmt.Sprintf("Failed on %s: Error returned", function))
}

View File

@@ -25,12 +25,12 @@ import (
"strings"
"time"
"github.com/minio/console/restapi/operations/admin_api"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
"github.com/minio/console/restapi/operations/user_api"
"github.com/minio/madmin-go"
iampolicy "github.com/minio/pkg/iam/policy"
)
@@ -100,6 +100,14 @@ func registerServiceAccountsHandlers(api *operations.ConsoleAPI) {
return user_api.NewGetServiceAccountPolicyOK().WithPayload(serviceAccounts)
})
api.UserAPISetServiceAccountPolicyHandler = user_api.SetServiceAccountPolicyHandlerFunc(func(params user_api.SetServiceAccountPolicyParams, session *models.Principal) middleware.Responder {
err := getSetServiceAccountPolicyResponse(session, params.AccessKey, *params.Policy.Policy)
if err != nil {
return user_api.NewSetServiceAccountPolicyDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewSetServiceAccountPolicyOK()
})
// Delete multiple service accounts
api.UserAPIDeleteMultipleServiceAccountsHandler = user_api.DeleteMultipleServiceAccountsHandlerFunc(func(params user_api.DeleteMultipleServiceAccountsParams, session *models.Principal) middleware.Responder {
if err := getDeleteMultipleServiceAccountsResponse(session, params.SelectedSA); err != nil {
@@ -396,6 +404,33 @@ func getServiceAccountPolicyResponse(session *models.Principal, accessKey string
return serviceAccounts, nil
}
// setServiceAccountPolicy sets policy for a service account
func setServiceAccountPolicy(ctx context.Context, userClient MinioAdmin, accessKey string, policy string) error {
err := userClient.updateServiceAccount(ctx, accessKey, madmin.UpdateServiceAccountReq{NewPolicy: json.RawMessage(policy)})
return err
}
// getSetServiceAccountPolicyResponse authenticates the user and calls
// getSetServiceAccountPolicy to set the policy for a service account
func getSetServiceAccountPolicyResponse(session *models.Principal, accessKey string, policy string) *models.Error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
userAdmin, err := NewMinioAdminClient(session)
if err != nil {
return prepareError(err)
}
// create a MinIO user Admin Client interface implementation
// defining the client to be used
userAdminClient := AdminClient{Client: userAdmin}
err = setServiceAccountPolicy(ctx, userAdminClient, accessKey, policy)
if err != nil {
return prepareError(err)
}
return nil
}
// getDeleteMultipleServiceAccountsResponse authenticates the user and calls deleteServiceAccount for each account listed in selectedSAs
func getDeleteMultipleServiceAccountsResponse(session *models.Principal, selectedSAs []string) *models.Error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)

View File

@@ -33,6 +33,7 @@ var minioAddServiceAccountMock func(ctx context.Context, policy *iampolicy.Polic
var minioListServiceAccountsMock func(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error)
var minioDeleteServiceAccountMock func(ctx context.Context, serviceAccount string) error
var minioInfoServiceAccountMock func(ctx context.Context, serviceAccount string) (madmin.InfoServiceAccountResp, error)
var minioUpdateServiceAccountMock func(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error
// mock function of AddServiceAccount()
func (ac adminClientMock) addServiceAccount(ctx context.Context, policy *iampolicy.Policy, user string, accessKey string, secretKey string) (madmin.Credentials, error) {
@@ -54,6 +55,11 @@ func (ac adminClientMock) infoServiceAccount(ctx context.Context, serviceAccount
return minioInfoServiceAccountMock(ctx, serviceAccount)
}
// mock function of UpdateServiceAccount()
func (ac adminClientMock) updateServiceAccount(ctx context.Context, serviceAccount string, opts madmin.UpdateServiceAccountReq) error {
return minioUpdateServiceAccountMock(ctx, serviceAccount, opts)
}
func TestAddServiceAccount(t *testing.T) {
assert := assert.New(t)
// mock minIO client

View File

@@ -1143,6 +1143,28 @@ paths:
tags:
- UserAPI
delete:
summary: Delete Lifecycle rule
operationId: DeleteBucketLifecycleRule
parameters:
- name: bucket_name
in: path
required: true
type: string
- name: lifecycle_id
in: path
required: true
type: string
responses:
204:
description: A successful response.
default:
description: Generic error response.
schema:
$ref: "#/definitions/error"
tags:
- UserAPI
/buckets/{bucket_name}/rewind/{date}:
get:
summary: Get objects in a bucket for a rewind date
@@ -1302,6 +1324,28 @@ paths:
$ref: "#/definitions/error"
tags:
- UserAPI
put:
summary: Set Service Account Policy
operationId: SetServiceAccountPolicy
parameters:
- name: access_key
in: path
required: true
type: string
- name: policy
in: body
required: true
schema:
$ref: "#/definitions/addServiceAccountPolicyRequest"
responses:
200:
description: A successful response.
default:
description: Generic error response.
schema:
$ref: "#/definitions/error"
tags:
- UserAPI
/users:
get:
@@ -2870,6 +2914,15 @@ definitions:
type: string
policy:
type: string
addServiceAccountPolicyRequest:
type: object
required:
- policy
properties:
policy:
type: string
listPoliciesResponse:
type: object
properties:
@@ -3866,6 +3919,12 @@ definitions:
addBucketLifecycle:
type: object
properties:
type:
description: ILM Rule type (Expiry or transition)
type: string
enum:
- expiry
- transition
prefix:
description: Non required field, it matches a prefix to perform ILM operations on it
type: string