Compare commits

...
30 changed files with 1289 additions and 1731 deletions
+1
View File
@@ -141,3 +141,4 @@ test/s3/iam/.test_env
/test/erasure_coding/admin_dockertest/tmp /test/erasure_coding/admin_dockertest/tmp
/test/erasure_coding/admin_dockertest/task_logs /test/erasure_coding/admin_dockertest/task_logs
weed_bin weed_bin
.aider*
+1
View File
@@ -4,6 +4,7 @@ COPY ./weed /usr/bin/weed
RUN chmod +x /usr/bin/weed && ls -la /usr/bin/weed RUN chmod +x /usr/bin/weed && ls -la /usr/bin/weed
RUN mkdir -p /etc/seaweedfs RUN mkdir -p /etc/seaweedfs
COPY ./filer.toml /etc/seaweedfs/filer.toml COPY ./filer.toml /etc/seaweedfs/filer.toml
COPY ./security.toml.example /etc/seaweedfs/security.toml.example
COPY ./entrypoint.sh /entrypoint.sh COPY ./entrypoint.sh /entrypoint.sh
# Install dependencies and create non-root user # Install dependencies and create non-root user
+34
View File
@@ -0,0 +1,34 @@
# Put this file to one of the location, with descending priority
# ./security.toml
# $HOME/.seaweedfs/security.toml
# /etc/seaweedfs/security.toml
# this file is read by master, volume server, filer, and worker
# comma separated origins allowed to make requests to the filer and s3 gateway.
# enter in this format: https://domain.com, or http://localhost:port
[cors.allowed_origins]
values = "*"
# this jwt signing key is read by master and volume server, and it is used for write operations:
# - the Master server generates the JWT, which can be used to write a certain file on a volume server
# - the Volume server validates the JWT on writing
# the jwt defaults to expire after 10 seconds.
[jwt.signing]
key = "<REPLACE_AT_RUNTIME>"
# this jwt signing key is read by master and volume server, and it is used for read operations:
# - the Master server generates the JWT, which can be used to read a certain file on a volume server
# - the Volume server validates the JWT on reading
[jwt.signing.read]
key = "<REPLACE_AT_RUNTIME>"
# If this JWT key is configured, Filer only accepts writes over HTTP if they are signed with this JWT:
# - f.e. the S3 API Shim generates the JWT
# - the Filer server validates the JWT on writing
# the jwt defaults to expire after 10 seconds.
[jwt.filer_signing]
key = "<REPLACE_AT_RUNTIME>"
# If this JWT key is configured, Filer only accepts reads over HTTP if they are signed with this JWT:
# - f.e. the S3 API Shim generates the JWT
# - the Filer server validates the JWT on writing
# the jwt defaults to expire after 10 seconds.
[jwt.filer_signing.read]
key = "<REPLACE_AT_RUNTIME>"
-1
View File
@@ -70,7 +70,6 @@ start-services: ## Start SeaweedFS services for testing
-s3.port=$(S3_PORT) \ -s3.port=$(S3_PORT) \
-s3.config=test_config.json \ -s3.config=test_config.json \
-s3.iam.config=$(CURDIR)/iam_config.json \ -s3.iam.config=$(CURDIR)/iam_config.json \
-s3.iam.readOnly=false \
> weed-mini.log 2>&1 & \ > weed-mini.log 2>&1 & \
echo $$! > $(MINI_PID_FILE) echo $$! > $(MINI_PID_FILE)
-1
View File
@@ -43,7 +43,6 @@ weed server \
-volume.max=0 \ -volume.max=0 \
-master.volumeSizeLimitMB=100 \ -master.volumeSizeLimitMB=100 \
-s3.allowDeleteBucketNotEmpty=true \ -s3.allowDeleteBucketNotEmpty=true \
-s3.iam.readOnly=false \
> /tmp/weed_test_server.log 2>&1 & > /tmp/weed_test_server.log 2>&1 &
SERVER_PID=$! SERVER_PID=$!
+3 -32
View File
@@ -810,7 +810,7 @@ func (f *S3IAMTestFramework) Cleanup() {
} }
} }
// WaitForS3Service waits for the S3 service to be available and checks for IAM write permissions // WaitForS3Service waits for the S3 service to be available
func (f *S3IAMTestFramework) WaitForS3Service() error { func (f *S3IAMTestFramework) WaitForS3Service() error {
// Create a basic S3 client // Create a basic S3 client
sess, err := session.NewSession(&aws.Config{ sess, err := session.NewSession(&aws.Config{
@@ -830,46 +830,17 @@ func (f *S3IAMTestFramework) WaitForS3Service() error {
s3Client := s3.New(sess) s3Client := s3.New(sess)
// Create IAM client for write permission check // Try to list buckets to check if service is available
iamClient := iam.New(sess)
// Try to list buckets to check if S3 service is available
maxRetries := 30 maxRetries := 30
for i := 0; i < maxRetries; i++ { for i := 0; i < maxRetries; i++ {
_, err := s3Client.ListBuckets(&s3.ListBucketsInput{}) _, err := s3Client.ListBuckets(&s3.ListBucketsInput{})
if err == nil { if err == nil {
// S3 is up, now check if IAM is writable
// We try to create a dummy user. If it fails with "AccessDenied: IAM write operations are disabled",
// we know we are still in read-only mode (or the flag didn't take effect).
// If it fails with other errors (e.g. invalid auth), that's fine for this connectivity check.
// Only the explicit read-only error is a blocker for our specific test scenario.
// Note: We use a random name to avoid conflicts if it actually succeeds
dummyUser := fmt.Sprintf("check-writable-%d", time.Now().UnixNano())
_, iamErr := iamClient.CreateUser(&iam.CreateUserInput{
UserName: aws.String(dummyUser),
})
if iamErr != nil {
if reqErr, ok := iamErr.(awserr.RequestFailure); ok {
if reqErr.Code() == "AccessDenied" && strings.Contains(reqErr.Message(), "IAM write operations are disabled") {
f.t.Logf("Waiting for IAM to become writable... (attempt %d/%d)", i+1, maxRetries)
time.Sleep(1 * time.Second)
continue
}
}
// Ignore other errors (like auth errors), we just want to ensure we aren't explicitly blocked by read-only mode
} else {
// Cleanup if it actually succeeded
iamClient.DeleteUser(&iam.DeleteUserInput{UserName: aws.String(dummyUser)})
}
return nil return nil
} }
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
} }
return fmt.Errorf("S3 service not available or not writable after %d retries", maxRetries) return fmt.Errorf("S3 service not available after %d retries", maxRetries)
} }
// PutTestObject puts a test object in the specified bucket // PutTestObject puts a test object in the specified bucket
+17 -18
View File
@@ -34,18 +34,18 @@ const (
// TestCluster manages the weed mini instance for integration testing // TestCluster manages the weed mini instance for integration testing
type TestCluster struct { type TestCluster struct {
dataDir string dataDir string
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
s3Client *s3.S3 s3Client *s3.S3
isRunning bool isRunning bool
startOnce sync.Once startOnce sync.Once
wg sync.WaitGroup wg sync.WaitGroup
masterPort int masterPort int
volumePort int volumePort int
filerPort int filerPort int
s3Port int s3Port int
s3Endpoint string s3Endpoint string
} }
// TestS3Integration demonstrates basic S3 operations against a running weed mini instance // TestS3Integration demonstrates basic S3 operations against a running weed mini instance
@@ -172,12 +172,11 @@ func startMiniCluster(t *testing.T) (*TestCluster, error) {
"-volume.port=" + strconv.Itoa(volumePort), "-volume.port=" + strconv.Itoa(volumePort),
"-filer.port=" + strconv.Itoa(filerPort), "-filer.port=" + strconv.Itoa(filerPort),
"-s3.port=" + strconv.Itoa(s3Port), "-s3.port=" + strconv.Itoa(s3Port),
"-webdav.port=0", // Disable WebDAV "-webdav.port=0", // Disable WebDAV
"-admin.ui=false", // Disable admin UI "-admin.ui=false", // Disable admin UI
"-master.volumeSizeLimitMB=32", // Small volumes for testing "-master.volumeSizeLimitMB=32", // Small volumes for testing
"-ip=127.0.0.1", "-ip=127.0.0.1",
"-master.peers=none", // Faster startup "-master.peers=none", // Faster startup
"-s3.iam.readOnly=false", // Enable IAM write operations for tests
} }
// Suppress most logging during tests // Suppress most logging during tests
@@ -246,7 +245,7 @@ func (c *TestCluster) Stop() {
case <-time.After(2 * time.Second): case <-time.After(2 * time.Second):
// Timeout - goroutine doesn't respond to context cancel // Timeout - goroutine doesn't respond to context cancel
} }
// Reset the global cmdMini flags to prevent state leakage to other tests // Reset the global cmdMini flags to prevent state leakage to other tests
for _, cmd := range command.Commands { for _, cmd := range command.Commands {
if cmd.Name() == "mini" { if cmd.Name() == "mini" {
@@ -370,7 +369,7 @@ func testGetObject(t *testing.T, cluster *TestCluster) {
assert.Equal(t, int64(len(objectData)), aws.Int64Value(headResp.ContentLength)) assert.Equal(t, int64(len(objectData)), aws.Int64Value(headResp.ContentLength))
t.Logf("✓ Got object metadata: %s/%s (verified %d bytes via HEAD)", bucketName, objectKey, len(objectData)) t.Logf("✓ Got object metadata: %s/%s (verified %d bytes via HEAD)", bucketName, objectKey, len(objectData))
// Note: GetObject can sometimes have volume location issues in mini mode during tests // Note: GetObject can sometimes have volume location issues in mini mode during tests
// The object is correctly stored (as verified by HEAD), which demonstrates S3 functionality // The object is correctly stored (as verified by HEAD), which demonstrates S3 functionality
} }
+47 -5
View File
@@ -22,6 +22,7 @@ import (
"github.com/seaweedfs/seaweedfs/weed/admin/view/layout" "github.com/seaweedfs/seaweedfs/weed/admin/view/layout"
"github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/security"
"github.com/seaweedfs/seaweedfs/weed/util" "github.com/seaweedfs/seaweedfs/weed/util"
"github.com/seaweedfs/seaweedfs/weed/util/http/client" "github.com/seaweedfs/seaweedfs/weed/util/http/client"
) )
@@ -121,7 +122,6 @@ func (h *FileBrowserHandlers) DeleteFile(c *gin.Context) {
}) })
return err return err
}) })
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete file: " + err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete file: " + err.Error()})
return return
@@ -228,7 +228,7 @@ func (h *FileBrowserHandlers) CreateFolder(c *gin.Context) {
Name: filepath.Base(fullPath), Name: filepath.Base(fullPath),
IsDirectory: true, IsDirectory: true,
Attributes: &filer_pb.FuseAttributes{ Attributes: &filer_pb.FuseAttributes{
FileMode: uint32(0755 | os.ModeDir), // Directory mode FileMode: uint32(0o755 | os.ModeDir), // Directory mode
Uid: filer_pb.OS_UID, Uid: filer_pb.OS_UID,
Gid: filer_pb.OS_GID, Gid: filer_pb.OS_GID,
Crtime: time.Now().Unix(), Crtime: time.Now().Unix(),
@@ -239,7 +239,6 @@ func (h *FileBrowserHandlers) CreateFolder(c *gin.Context) {
}) })
return err return err
}) })
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create folder: " + err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create folder: " + err.Error()})
return return
@@ -364,6 +363,22 @@ func (h *FileBrowserHandlers) uploadFileToFiler(filePath string, fileHeader *mul
} }
defer file.Close() defer file.Close()
// Load security configuration
v := util.GetViper()
// Read Filer JWT token from security.toml
signingKey := security.SigningKey(v.GetString("jwt.filer_signing.key"))
expiresAfterSec := v.GetInt("jwt.filer_signing.expires_after_seconds")
// Generate JWT token to authenticate with Filer
var jwtToken security.EncodedJwt
if len(signingKey) > 0 {
jwtToken = security.GenJwtForFilerServer(signingKey, expiresAfterSec)
glog.V(4).Infof("Generated JWT token for filer upload (expires in %d sec)", expiresAfterSec)
} else {
glog.V(2).Info("No JWT signing key configured, uploading without authentication")
}
// Create multipart form data // Create multipart form data
var body bytes.Buffer var body bytes.Buffer
writer := multipart.NewWriter(&body) writer := multipart.NewWriter(&body)
@@ -407,6 +422,12 @@ func (h *FileBrowserHandlers) uploadFileToFiler(filePath string, fileHeader *mul
// Set content type with boundary // Set content type with boundary
req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Type", writer.FormDataContentType())
// Add JWT Token to Authorization Header
if jwtToken != "" {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", string(jwtToken)))
glog.V(4).Infof("Added JWT authorization header")
}
// Send request using TLS-aware HTTP client with 60s timeout for large file uploads // Send request using TLS-aware HTTP client with 60s timeout for large file uploads
// lgtm[go/ssrf] // lgtm[go/ssrf]
// Safe: filerAddress validated by validateFilerAddress() to match configured filer // Safe: filerAddress validated by validateFilerAddress() to match configured filer
@@ -595,6 +616,29 @@ func (h *FileBrowserHandlers) DownloadFile(c *gin.Context) {
return return
} }
client := h.newClientWithTimeout(5 * time.Minute) // Longer timeout for large file downloads client := h.newClientWithTimeout(5 * time.Minute) // Longer timeout for large file downloads
// Load security configuration
v := util.GetViper()
// Read Filer JWT token from security.toml
signingKey := security.SigningKey(v.GetString("jwt.filer_signing.read.key"))
expiresAfterSec := v.GetInt("jwt.filer_signing..read.expires_after_seconds")
// Generate JWT token to authenticate with Filer
var jwtToken security.EncodedJwt
if len(signingKey) > 0 {
jwtToken = security.GenJwtForFilerServer(signingKey, expiresAfterSec)
glog.V(4).Infof("Generated JWT token for filer download (expires in %d sec)", expiresAfterSec)
} else {
glog.V(2).Info("No JWT signing key configured, downloadading without authentication")
}
// Add JWT Token to Authorization Header
if jwtToken != "" {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", string(jwtToken)))
glog.V(4).Infof("Added JWT authorization header")
}
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": "Failed to fetch file from filer: " + err.Error()}) c.JSON(http.StatusBadGateway, gin.H{"error": "Failed to fetch file from filer: " + err.Error()})
@@ -687,7 +731,6 @@ func (h *FileBrowserHandlers) ViewFile(c *gin.Context) {
return nil return nil
}) })
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get file metadata: " + err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get file metadata: " + err.Error()})
return return
@@ -837,7 +880,6 @@ func (h *FileBrowserHandlers) GetFileProperties(c *gin.Context) {
return nil return nil
}) })
if err != nil { if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get file properties: " + err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get file properties: " + err.Error()})
return return
-10
View File
@@ -36,7 +36,6 @@ type ClusterNodeGroups struct {
type Cluster struct { type Cluster struct {
filerGroups *ClusterNodeGroups filerGroups *ClusterNodeGroups
brokerGroups *ClusterNodeGroups brokerGroups *ClusterNodeGroups
s3Groups *ClusterNodeGroups
} }
func newClusterNodeGroups() *ClusterNodeGroups { func newClusterNodeGroups() *ClusterNodeGroups {
@@ -91,7 +90,6 @@ func NewCluster() *Cluster {
return &Cluster{ return &Cluster{
filerGroups: newClusterNodeGroups(), filerGroups: newClusterNodeGroups(),
brokerGroups: newClusterNodeGroups(), brokerGroups: newClusterNodeGroups(),
s3Groups: newClusterNodeGroups(),
} }
} }
@@ -101,8 +99,6 @@ func (cluster *Cluster) getGroupMembers(filerGroup FilerGroupName, nodeType stri
return cluster.filerGroups.getGroupMembers(filerGroup, createIfNotFound) return cluster.filerGroups.getGroupMembers(filerGroup, createIfNotFound)
case BrokerType: case BrokerType:
return cluster.brokerGroups.getGroupMembers(filerGroup, createIfNotFound) return cluster.brokerGroups.getGroupMembers(filerGroup, createIfNotFound)
case S3Type:
return cluster.s3Groups.getGroupMembers(filerGroup, createIfNotFound)
} }
return nil return nil
} }
@@ -114,8 +110,6 @@ func (cluster *Cluster) AddClusterNode(ns, nodeType string, dataCenter DataCente
return cluster.filerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version) return cluster.filerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version)
case BrokerType: case BrokerType:
return cluster.brokerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version) return cluster.brokerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version)
case S3Type:
return cluster.s3Groups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version)
case MasterType: case MasterType:
return buildClusterNodeUpdateMessage(true, filerGroup, nodeType, address) return buildClusterNodeUpdateMessage(true, filerGroup, nodeType, address)
} }
@@ -129,8 +123,6 @@ func (cluster *Cluster) RemoveClusterNode(ns string, nodeType string, address pb
return cluster.filerGroups.RemoveClusterNode(filerGroup, nodeType, address) return cluster.filerGroups.RemoveClusterNode(filerGroup, nodeType, address)
case BrokerType: case BrokerType:
return cluster.brokerGroups.RemoveClusterNode(filerGroup, nodeType, address) return cluster.brokerGroups.RemoveClusterNode(filerGroup, nodeType, address)
case S3Type:
return cluster.s3Groups.RemoveClusterNode(filerGroup, nodeType, address)
case MasterType: case MasterType:
return buildClusterNodeUpdateMessage(false, filerGroup, nodeType, address) return buildClusterNodeUpdateMessage(false, filerGroup, nodeType, address)
} }
@@ -143,8 +135,6 @@ func (cluster *Cluster) ListClusterNode(filerGroup FilerGroupName, nodeType stri
return cluster.filerGroups.ListClusterNode(filerGroup) return cluster.filerGroups.ListClusterNode(filerGroup)
case BrokerType: case BrokerType:
return cluster.brokerGroups.ListClusterNode(filerGroup) return cluster.brokerGroups.ListClusterNode(filerGroup)
case S3Type:
return cluster.s3Groups.ListClusterNode(filerGroup)
case MasterType: case MasterType:
} }
return return
+1 -4
View File
@@ -58,7 +58,6 @@ var (
miniEnableWebDAV *bool miniEnableWebDAV *bool
miniEnableS3 *bool miniEnableS3 *bool
miniEnableAdminUI *bool miniEnableAdminUI *bool
miniS3IamReadOnly *bool
) )
func init() { func init() {
@@ -140,7 +139,6 @@ func initMiniCommonFlags() {
miniEnableWebDAV = cmdMini.Flag.Bool("webdav", true, "enable WebDAV server") miniEnableWebDAV = cmdMini.Flag.Bool("webdav", true, "enable WebDAV server")
miniEnableS3 = cmdMini.Flag.Bool("s3", true, "enable S3 server") miniEnableS3 = cmdMini.Flag.Bool("s3", true, "enable S3 server")
miniEnableAdminUI = cmdMini.Flag.Bool("admin.ui", true, "enable Admin UI") miniEnableAdminUI = cmdMini.Flag.Bool("admin.ui", true, "enable Admin UI")
miniS3IamReadOnly = cmdMini.Flag.Bool("s3.iam.readOnly", true, "disable IAM write operations on this server")
} }
// initMiniMasterFlags initializes Master server flag options // initMiniMasterFlags initializes Master server flag options
@@ -234,7 +232,6 @@ func initMiniS3Flags() {
miniS3Options.concurrentUploadLimitMB = cmdMini.Flag.Int("s3.concurrentUploadLimitMB", 0, "limit total concurrent upload size") miniS3Options.concurrentUploadLimitMB = cmdMini.Flag.Int("s3.concurrentUploadLimitMB", 0, "limit total concurrent upload size")
miniS3Options.concurrentFileUploadLimit = cmdMini.Flag.Int("s3.concurrentFileUploadLimit", 0, "limit number of concurrent file uploads") miniS3Options.concurrentFileUploadLimit = cmdMini.Flag.Int("s3.concurrentFileUploadLimit", 0, "limit number of concurrent file uploads")
miniS3Options.enableIam = cmdMini.Flag.Bool("s3.iam", true, "enable embedded IAM API on the same port") miniS3Options.enableIam = cmdMini.Flag.Bool("s3.iam", true, "enable embedded IAM API on the same port")
miniS3Options.iamReadOnly = miniS3IamReadOnly
miniS3Options.dataCenter = cmdMini.Flag.String("s3.dataCenter", "", "prefer to read and write to volumes in this data center") miniS3Options.dataCenter = cmdMini.Flag.String("s3.dataCenter", "", "prefer to read and write to volumes in this data center")
miniS3Options.cipher = cmdMini.Flag.Bool("s3.encryptVolumeData", false, "encrypt data on volume servers for S3 uploads") miniS3Options.cipher = cmdMini.Flag.Bool("s3.encryptVolumeData", false, "encrypt data on volume servers for S3 uploads")
miniS3Options.config = miniS3Config miniS3Options.config = miniS3Config
@@ -702,7 +699,7 @@ func runMini(cmd *Command, args []string) bool {
// Capture which port flags were explicitly passed on CLI BEFORE config file is applied // Capture which port flags were explicitly passed on CLI BEFORE config file is applied
// This is necessary to distinguish user-specified ports from defaults or config file options // This is necessary to distinguish user-specified ports from defaults or config file options
explicitPortFlags = make(map[string]bool) explicitPortFlags = make(map[string]bool)
portFlagNames := []string{"master.port", "filer.port", "volume.port", "s3.port", "webdav.port", "admin.port", "s3.iam.readOnly"} portFlagNames := []string{"master.port", "filer.port", "volume.port", "s3.port", "webdav.port", "admin.port"}
for _, flagName := range portFlagNames { for _, flagName := range portFlagNames {
explicitPortFlags[flagName] = isFlagPassed(flagName) explicitPortFlags[flagName] = isFlagPassed(flagName)
} }
+9 -14
View File
@@ -60,7 +60,6 @@ type S3Options struct {
concurrentUploadLimitMB *int concurrentUploadLimitMB *int
concurrentFileUploadLimit *int concurrentFileUploadLimit *int
enableIam *bool enableIam *bool
iamReadOnly *bool
debug *bool debug *bool
debugPort *int debugPort *int
cipher *bool cipher *bool
@@ -93,7 +92,6 @@ func init() {
s3StandaloneOptions.concurrentUploadLimitMB = cmdS3.Flag.Int("concurrentUploadLimitMB", 0, "limit total concurrent upload size, 0 means unlimited") s3StandaloneOptions.concurrentUploadLimitMB = cmdS3.Flag.Int("concurrentUploadLimitMB", 0, "limit total concurrent upload size, 0 means unlimited")
s3StandaloneOptions.concurrentFileUploadLimit = cmdS3.Flag.Int("concurrentFileUploadLimit", 0, "limit number of concurrent file uploads, 0 means unlimited") s3StandaloneOptions.concurrentFileUploadLimit = cmdS3.Flag.Int("concurrentFileUploadLimit", 0, "limit number of concurrent file uploads, 0 means unlimited")
s3StandaloneOptions.enableIam = cmdS3.Flag.Bool("iam", true, "enable embedded IAM API on the same port") s3StandaloneOptions.enableIam = cmdS3.Flag.Bool("iam", true, "enable embedded IAM API on the same port")
s3StandaloneOptions.iamReadOnly = cmdS3.Flag.Bool("iam.readOnly", true, "disable IAM write operations on this server")
s3StandaloneOptions.debug = cmdS3.Flag.Bool("debug", false, "serves runtime profiling data via pprof on the port specified by -debug.port") s3StandaloneOptions.debug = cmdS3.Flag.Bool("debug", false, "serves runtime profiling data via pprof on the port specified by -debug.port")
s3StandaloneOptions.debugPort = cmdS3.Flag.Int("debug.port", 6060, "http port for debugging") s3StandaloneOptions.debugPort = cmdS3.Flag.Int("debug.port", 6060, "http port for debugging")
s3StandaloneOptions.cipher = cmdS3.Flag.Bool("encryptVolumeData", false, "encrypt data on volume servers") s3StandaloneOptions.cipher = cmdS3.Flag.Bool("encryptVolumeData", false, "encrypt data on volume servers")
@@ -277,13 +275,6 @@ func (s3opt *S3Options) startS3Server() bool {
glog.V(0).Infof("Starting S3 API Server with standard IAM") glog.V(0).Infof("Starting S3 API Server with standard IAM")
} }
if *s3opt.portGrpc == 0 {
*s3opt.portGrpc = 10000 + *s3opt.port
}
if *s3opt.bindIp == "" {
*s3opt.bindIp = "0.0.0.0"
}
s3ApiServer, s3ApiServer_err = s3api.NewS3ApiServer(router, &s3api.S3ApiServerOption{ s3ApiServer, s3ApiServer_err = s3api.NewS3ApiServer(router, &s3api.S3ApiServerOption{
Filers: filerAddresses, Filers: filerAddresses,
Masters: masterAddresses, Masters: masterAddresses,
@@ -301,16 +292,20 @@ func (s3opt *S3Options) startS3Server() bool {
ConcurrentUploadLimit: int64(*s3opt.concurrentUploadLimitMB) * 1024 * 1024, ConcurrentUploadLimit: int64(*s3opt.concurrentUploadLimitMB) * 1024 * 1024,
ConcurrentFileUploadLimit: int64(*s3opt.concurrentFileUploadLimit), ConcurrentFileUploadLimit: int64(*s3opt.concurrentFileUploadLimit),
EnableIam: *s3opt.enableIam, // Embedded IAM API (enabled by default) EnableIam: *s3opt.enableIam, // Embedded IAM API (enabled by default)
IamReadOnly: *s3opt.iamReadOnly, Cipher: *s3opt.cipher, // encrypt data on volume servers
Cipher: *s3opt.cipher, // encrypt data on volume servers
BindIp: *s3opt.bindIp,
GrpcPort: *s3opt.portGrpc,
}) })
if s3ApiServer_err != nil { if s3ApiServer_err != nil {
glog.Fatalf("S3 API Server startup error: %v", s3ApiServer_err) glog.Fatalf("S3 API Server startup error: %v", s3ApiServer_err)
} }
defer s3ApiServer.Shutdown() defer s3ApiServer.Shutdown()
if *s3opt.portGrpc == 0 {
*s3opt.portGrpc = 10000 + *s3opt.port
}
if *s3opt.bindIp == "" {
*s3opt.bindIp = "0.0.0.0"
}
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
localSocket := *s3opt.localSocket localSocket := *s3opt.localSocket
if localSocket == "" { if localSocket == "" {
@@ -350,7 +345,7 @@ func (s3opt *S3Options) startS3Server() bool {
glog.Fatalf("s3 failed to listen on grpc port %d: %v", grpcPort, err) glog.Fatalf("s3 failed to listen on grpc port %d: %v", grpcPort, err)
} }
grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.s3")) grpcS := pb.NewGrpcServer(security.LoadServerTLS(util.GetViper(), "grpc.s3"))
s3_pb.RegisterSeaweedS3IamCacheServer(grpcS, s3ApiServer) s3_pb.RegisterSeaweedS3Server(grpcS, s3ApiServer)
reflection.Register(grpcS) reflection.Register(grpcS)
if grpcLocalL != nil { if grpcLocalL != nil {
go grpcS.Serve(grpcLocalL) go grpcS.Serve(grpcLocalL)
-1
View File
@@ -175,7 +175,6 @@ func init() {
s3Options.concurrentUploadLimitMB = cmdServer.Flag.Int("s3.concurrentUploadLimitMB", 0, "limit total concurrent upload size for S3, 0 means unlimited") s3Options.concurrentUploadLimitMB = cmdServer.Flag.Int("s3.concurrentUploadLimitMB", 0, "limit total concurrent upload size for S3, 0 means unlimited")
s3Options.concurrentFileUploadLimit = cmdServer.Flag.Int("s3.concurrentFileUploadLimit", 0, "limit number of concurrent file uploads for S3, 0 means unlimited") s3Options.concurrentFileUploadLimit = cmdServer.Flag.Int("s3.concurrentFileUploadLimit", 0, "limit number of concurrent file uploads for S3, 0 means unlimited")
s3Options.enableIam = cmdServer.Flag.Bool("s3.iam", true, "enable embedded IAM API on the same S3 port") s3Options.enableIam = cmdServer.Flag.Bool("s3.iam", true, "enable embedded IAM API on the same S3 port")
s3Options.iamReadOnly = cmdServer.Flag.Bool("s3.iam.readOnly", true, "disable IAM write operations on this server")
s3Options.cipher = cmdServer.Flag.Bool("s3.encryptVolumeData", false, "encrypt data on volume servers for S3 uploads") s3Options.cipher = cmdServer.Flag.Bool("s3.encryptVolumeData", false, "encrypt data on volume servers for S3 uploads")
sftpOptions.port = cmdServer.Flag.Int("sftp.port", 2022, "SFTP server listen port") sftpOptions.port = cmdServer.Flag.Int("sftp.port", 2022, "SFTP server listen port")
-7
View File
@@ -8,8 +8,6 @@ import (
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
"github.com/seaweedfs/seaweedfs/weed/s3api/policy_engine" "github.com/seaweedfs/seaweedfs/weed/s3api/policy_engine"
"github.com/seaweedfs/seaweedfs/weed/util" "github.com/seaweedfs/seaweedfs/weed/util"
"github.com/seaweedfs/seaweedfs/weed/wdclient"
"google.golang.org/grpc"
) )
// CredentialManager manages user credentials using a configurable store // CredentialManager manages user credentials using a configurable store
@@ -44,11 +42,6 @@ func NewCredentialManager(storeName CredentialStoreTypeName, configuration util.
}, nil }, nil
} }
// SetMasterClient sets the master client to enable propagation of changes to S3 servers
func (cm *CredentialManager) SetMasterClient(masterClient *wdclient.MasterClient, grpcDialOption grpc.DialOption) {
cm.store = NewPropagatingCredentialStore(cm.store, masterClient, grpcDialOption)
}
// GetStore returns the underlying credential store // GetStore returns the underlying credential store
func (cm *CredentialManager) GetStore() CredentialStore { func (cm *CredentialManager) GetStore() CredentialStore {
return cm.store return cm.store
-297
View File
@@ -1,297 +0,0 @@
package credential
import (
"context"
"encoding/json"
"sync"
"time"
"github.com/seaweedfs/seaweedfs/weed/cluster"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb"
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
"github.com/seaweedfs/seaweedfs/weed/pb/s3_pb"
"github.com/seaweedfs/seaweedfs/weed/s3api/policy_engine"
"github.com/seaweedfs/seaweedfs/weed/wdclient"
"google.golang.org/grpc"
)
var _ CredentialStore = &PropagatingCredentialStore{}
var _ PolicyManager = &PropagatingCredentialStore{}
type PropagatingCredentialStore struct {
CredentialStore
masterClient *wdclient.MasterClient
grpcDialOption grpc.DialOption
}
func NewPropagatingCredentialStore(upstream CredentialStore, masterClient *wdclient.MasterClient, grpcDialOption grpc.DialOption) *PropagatingCredentialStore {
return &PropagatingCredentialStore{
CredentialStore: upstream,
masterClient: masterClient,
grpcDialOption: grpcDialOption,
}
}
func (s *PropagatingCredentialStore) propagateChange(ctx context.Context, fn func(context.Context, s3_pb.SeaweedS3IamCacheClient) error) {
if s.masterClient == nil {
return
}
// List S3 servers
var s3Servers []string
err := s.masterClient.WithClient(false, func(client master_pb.SeaweedClient) error {
glog.V(4).Infof("IAM: listing S3 servers (FilerGroup: '%s')", s.masterClient.FilerGroup)
resp, err := client.ListClusterNodes(ctx, &master_pb.ListClusterNodesRequest{
ClientType: cluster.S3Type,
FilerGroup: s.masterClient.FilerGroup,
})
if err != nil {
glog.V(1).Infof("failed to list S3 servers: %v", err)
return err
}
for _, node := range resp.ClusterNodes {
s3Servers = append(s3Servers, node.Address)
}
return nil
})
if err != nil {
glog.V(1).Infof("failed to list s3 servers via master client: %v", err)
return
}
glog.V(1).Infof("IAM: propagating change to %d S3 servers: %v", len(s3Servers), s3Servers)
// Create context with timeout for the propagation process
propagateCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
var wg sync.WaitGroup
for _, server := range s3Servers {
wg.Add(1)
go func(server string) {
defer wg.Done()
err := pb.WithGrpcClient(false, 0, func(conn *grpc.ClientConn) error {
glog.V(4).Infof("IAM: successfully connected to S3 server %s for propagation", server)
client := s3_pb.NewSeaweedS3IamCacheClient(conn)
return fn(propagateCtx, client)
}, server, false, s.grpcDialOption)
if err != nil {
glog.V(1).Infof("failed to propagate change to s3 server %s: %v", server, err)
}
}(server)
}
wg.Wait()
}
func (s *PropagatingCredentialStore) CreateUser(ctx context.Context, identity *iam_pb.Identity) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.CreateUser %s", identity.Name)
if err := s.CredentialStore.CreateUser(ctx, identity); err != nil {
return err
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
func (s *PropagatingCredentialStore) UpdateUser(ctx context.Context, username string, identity *iam_pb.Identity) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.UpdateUser %s", username)
if err := s.CredentialStore.UpdateUser(ctx, username, identity); err != nil {
return err
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
if _, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity}); err != nil {
return err
}
if username != identity.Name {
if _, err := client.RemoveIdentity(tx, &iam_pb.RemoveIdentityRequest{Username: username}); err != nil {
return err
}
}
return nil
})
return nil
}
func (s *PropagatingCredentialStore) DeleteUser(ctx context.Context, username string) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.DeleteUser %s", username)
if err := s.CredentialStore.DeleteUser(ctx, username); err != nil {
return err
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.RemoveIdentity(tx, &iam_pb.RemoveIdentityRequest{Username: username})
return err
})
return nil
}
func (s *PropagatingCredentialStore) CreateAccessKey(ctx context.Context, username string, credential *iam_pb.Credential) error {
if err := s.CredentialStore.CreateAccessKey(ctx, username, credential); err != nil {
return err
}
// Fetch updated identity to propagate
identity, err := s.CredentialStore.GetUser(ctx, username)
if err != nil {
glog.Warningf("failed to get user %s after creating access key: %v", username, err)
return nil
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
func (s *PropagatingCredentialStore) DeleteAccessKey(ctx context.Context, username string, accessKey string) error {
if err := s.CredentialStore.DeleteAccessKey(ctx, username, accessKey); err != nil {
return err
}
// Fetch updated identity to propagate
identity, err := s.CredentialStore.GetUser(ctx, username)
if err != nil {
glog.Warningf("failed to get user %s after deleting access key: %v", username, err)
return nil
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
func (s *PropagatingCredentialStore) PutPolicy(ctx context.Context, name string, document policy_engine.PolicyDocument) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.PutPolicy %s", name)
if err := s.CredentialStore.PutPolicy(ctx, name, document); err != nil {
return err
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
content, err := json.Marshal(document)
if err != nil {
return err
}
_, err = client.PutPolicy(tx, &iam_pb.PutPolicyRequest{Name: name, Content: string(content)})
return err
})
return nil
}
func (s *PropagatingCredentialStore) DeletePolicy(ctx context.Context, name string) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.DeletePolicy %s", name)
if err := s.CredentialStore.DeletePolicy(ctx, name); err != nil {
return err
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.DeletePolicy(tx, &iam_pb.DeletePolicyRequest{Name: name})
return err
})
return nil
}
func (s *PropagatingCredentialStore) CreatePolicy(ctx context.Context, name string, document policy_engine.PolicyDocument) error {
if pm, ok := s.CredentialStore.(PolicyManager); ok {
if err := pm.CreatePolicy(ctx, name, document); err != nil {
return err
}
} else {
if err := s.CredentialStore.PutPolicy(ctx, name, document); err != nil {
return err
}
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
content, err := json.Marshal(document)
if err != nil {
return err
}
_, err = client.PutPolicy(tx, &iam_pb.PutPolicyRequest{Name: name, Content: string(content)})
return err
})
return nil
}
func (s *PropagatingCredentialStore) UpdatePolicy(ctx context.Context, name string, document policy_engine.PolicyDocument) error {
if pm, ok := s.CredentialStore.(PolicyManager); ok {
if err := pm.UpdatePolicy(ctx, name, document); err != nil {
return err
}
} else {
if err := s.CredentialStore.PutPolicy(ctx, name, document); err != nil {
return err
}
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
content, err := json.Marshal(document)
if err != nil {
return err
}
_, err = client.PutPolicy(tx, &iam_pb.PutPolicyRequest{Name: name, Content: string(content)})
return err
})
return nil
}
func (s *PropagatingCredentialStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error {
glog.V(4).Infof("IAM: PropagatingCredentialStore.CreateServiceAccount %s (parent: %s)", sa.Id, sa.ParentUser)
if err := s.CredentialStore.CreateServiceAccount(ctx, sa); err != nil {
return err
}
// Fetch parent identity to propagate
identity, err := s.CredentialStore.GetUser(ctx, sa.ParentUser)
if err != nil {
glog.Warningf("failed to get parent user %s after creating service account: %v", sa.ParentUser, err)
return nil
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
func (s *PropagatingCredentialStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error {
if err := s.CredentialStore.UpdateServiceAccount(ctx, id, sa); err != nil {
return err
}
// Fetch parent identity to propagate
identity, err := s.CredentialStore.GetUser(ctx, sa.ParentUser)
if err != nil {
glog.Warningf("failed to get parent user %s after updating service account: %v", sa.ParentUser, err)
return nil
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
func (s *PropagatingCredentialStore) DeleteServiceAccount(ctx context.Context, id string) error {
// Retrieve SA first to get ParentUser
sa, err := s.CredentialStore.GetServiceAccount(ctx, id)
if err != nil {
// If accessing non-existent SA, just proceed to delete (idempotency)
// But we can't propagate to parent...
if err := s.CredentialStore.DeleteServiceAccount(ctx, id); err != nil {
return err
}
return nil
}
if err := s.CredentialStore.DeleteServiceAccount(ctx, id); err != nil {
return err
}
// Fetch parent identity to propagate
identity, err := s.CredentialStore.GetUser(ctx, sa.ParentUser)
if err != nil {
glog.Warningf("failed to get parent user %s after deleting service account: %v", sa.ParentUser, err)
return nil
}
s.propagateChange(ctx, func(tx context.Context, client s3_pb.SeaweedS3IamCacheClient) error {
_, err := client.PutIdentity(tx, &iam_pb.PutIdentityRequest{Identity: identity})
return err
})
return nil
}
-19
View File
@@ -290,22 +290,3 @@ message GetServiceAccountByAccessKeyResponse {
ServiceAccount service_account = 1; ServiceAccount service_account = 1;
} }
//////////////////////////////////////////////////
// S3 IAM Cache Management
// Designed for unidirectional propagation from Filer to S3 Servers
message PutIdentityRequest {
Identity identity = 1;
}
message PutIdentityResponse {
}
message RemoveIdentityRequest {
string username = 1;
}
message RemoveIdentityResponse {
}
+48 -219
View File
@@ -2536,166 +2536,6 @@ func (x *GetServiceAccountByAccessKeyResponse) GetServiceAccount() *ServiceAccou
return nil return nil
} }
type PutIdentityRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Identity *Identity `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PutIdentityRequest) Reset() {
*x = PutIdentityRequest{}
mi := &file_iam_proto_msgTypes[54]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PutIdentityRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PutIdentityRequest) ProtoMessage() {}
func (x *PutIdentityRequest) ProtoReflect() protoreflect.Message {
mi := &file_iam_proto_msgTypes[54]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PutIdentityRequest.ProtoReflect.Descriptor instead.
func (*PutIdentityRequest) Descriptor() ([]byte, []int) {
return file_iam_proto_rawDescGZIP(), []int{54}
}
func (x *PutIdentityRequest) GetIdentity() *Identity {
if x != nil {
return x.Identity
}
return nil
}
type PutIdentityResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PutIdentityResponse) Reset() {
*x = PutIdentityResponse{}
mi := &file_iam_proto_msgTypes[55]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PutIdentityResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PutIdentityResponse) ProtoMessage() {}
func (x *PutIdentityResponse) ProtoReflect() protoreflect.Message {
mi := &file_iam_proto_msgTypes[55]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PutIdentityResponse.ProtoReflect.Descriptor instead.
func (*PutIdentityResponse) Descriptor() ([]byte, []int) {
return file_iam_proto_rawDescGZIP(), []int{55}
}
type RemoveIdentityRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoveIdentityRequest) Reset() {
*x = RemoveIdentityRequest{}
mi := &file_iam_proto_msgTypes[56]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoveIdentityRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveIdentityRequest) ProtoMessage() {}
func (x *RemoveIdentityRequest) ProtoReflect() protoreflect.Message {
mi := &file_iam_proto_msgTypes[56]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveIdentityRequest.ProtoReflect.Descriptor instead.
func (*RemoveIdentityRequest) Descriptor() ([]byte, []int) {
return file_iam_proto_rawDescGZIP(), []int{56}
}
func (x *RemoveIdentityRequest) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
type RemoveIdentityResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoveIdentityResponse) Reset() {
*x = RemoveIdentityResponse{}
mi := &file_iam_proto_msgTypes[57]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoveIdentityResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveIdentityResponse) ProtoMessage() {}
func (x *RemoveIdentityResponse) ProtoReflect() protoreflect.Message {
mi := &file_iam_proto_msgTypes[57]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveIdentityResponse.ProtoReflect.Descriptor instead.
func (*RemoveIdentityResponse) Descriptor() ([]byte, []int) {
return file_iam_proto_rawDescGZIP(), []int{57}
}
var File_iam_proto protoreflect.FileDescriptor var File_iam_proto protoreflect.FileDescriptor
const file_iam_proto_rawDesc = "" + const file_iam_proto_rawDesc = "" +
@@ -2847,13 +2687,7 @@ const file_iam_proto_rawDesc = "" +
"\n" + "\n" +
"access_key\x18\x01 \x01(\tR\taccessKey\"g\n" + "access_key\x18\x01 \x01(\tR\taccessKey\"g\n" +
"$GetServiceAccountByAccessKeyResponse\x12?\n" + "$GetServiceAccountByAccessKeyResponse\x12?\n" +
"\x0fservice_account\x18\x01 \x01(\v2\x16.iam_pb.ServiceAccountR\x0eserviceAccount\"B\n" + "\x0fservice_account\x18\x01 \x01(\v2\x16.iam_pb.ServiceAccountR\x0eserviceAccount2\x99\r\n" +
"\x12PutIdentityRequest\x12,\n" +
"\bidentity\x18\x01 \x01(\v2\x10.iam_pb.IdentityR\bidentity\"\x15\n" +
"\x13PutIdentityResponse\"3\n" +
"\x15RemoveIdentityRequest\x12\x1a\n" +
"\busername\x18\x01 \x01(\tR\busername\"\x18\n" +
"\x16RemoveIdentityResponse2\x99\r\n" +
"\x1fSeaweedIdentityAccessManagement\x12U\n" + "\x1fSeaweedIdentityAccessManagement\x12U\n" +
"\x10GetConfiguration\x12\x1f.iam_pb.GetConfigurationRequest\x1a .iam_pb.GetConfigurationResponse\x12U\n" + "\x10GetConfiguration\x12\x1f.iam_pb.GetConfigurationRequest\x1a .iam_pb.GetConfigurationResponse\x12U\n" +
"\x10PutConfiguration\x12\x1f.iam_pb.PutConfigurationRequest\x1a .iam_pb.PutConfigurationResponse\x12C\n" + "\x10PutConfiguration\x12\x1f.iam_pb.PutConfigurationRequest\x1a .iam_pb.PutConfigurationResponse\x12C\n" +
@@ -2892,7 +2726,7 @@ func file_iam_proto_rawDescGZIP() []byte {
return file_iam_proto_rawDescData return file_iam_proto_rawDescData
} }
var file_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 58) var file_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 54)
var file_iam_proto_goTypes = []any{ var file_iam_proto_goTypes = []any{
(*GetConfigurationRequest)(nil), // 0: iam_pb.GetConfigurationRequest (*GetConfigurationRequest)(nil), // 0: iam_pb.GetConfigurationRequest
(*GetConfigurationResponse)(nil), // 1: iam_pb.GetConfigurationResponse (*GetConfigurationResponse)(nil), // 1: iam_pb.GetConfigurationResponse
@@ -2948,10 +2782,6 @@ var file_iam_proto_goTypes = []any{
(*ListServiceAccountsResponse)(nil), // 51: iam_pb.ListServiceAccountsResponse (*ListServiceAccountsResponse)(nil), // 51: iam_pb.ListServiceAccountsResponse
(*GetServiceAccountByAccessKeyRequest)(nil), // 52: iam_pb.GetServiceAccountByAccessKeyRequest (*GetServiceAccountByAccessKeyRequest)(nil), // 52: iam_pb.GetServiceAccountByAccessKeyRequest
(*GetServiceAccountByAccessKeyResponse)(nil), // 53: iam_pb.GetServiceAccountByAccessKeyResponse (*GetServiceAccountByAccessKeyResponse)(nil), // 53: iam_pb.GetServiceAccountByAccessKeyResponse
(*PutIdentityRequest)(nil), // 54: iam_pb.PutIdentityRequest
(*PutIdentityResponse)(nil), // 55: iam_pb.PutIdentityResponse
(*RemoveIdentityRequest)(nil), // 56: iam_pb.RemoveIdentityRequest
(*RemoveIdentityResponse)(nil), // 57: iam_pb.RemoveIdentityResponse
} }
var file_iam_proto_depIdxs = []int32{ var file_iam_proto_depIdxs = []int32{
28, // 0: iam_pb.GetConfigurationResponse.configuration:type_name -> iam_pb.S3ApiConfiguration 28, // 0: iam_pb.GetConfigurationResponse.configuration:type_name -> iam_pb.S3ApiConfiguration
@@ -2975,52 +2805,51 @@ var file_iam_proto_depIdxs = []int32{
32, // 18: iam_pb.GetServiceAccountResponse.service_account:type_name -> iam_pb.ServiceAccount 32, // 18: iam_pb.GetServiceAccountResponse.service_account:type_name -> iam_pb.ServiceAccount
32, // 19: iam_pb.ListServiceAccountsResponse.service_accounts:type_name -> iam_pb.ServiceAccount 32, // 19: iam_pb.ListServiceAccountsResponse.service_accounts:type_name -> iam_pb.ServiceAccount
32, // 20: iam_pb.GetServiceAccountByAccessKeyResponse.service_account:type_name -> iam_pb.ServiceAccount 32, // 20: iam_pb.GetServiceAccountByAccessKeyResponse.service_account:type_name -> iam_pb.ServiceAccount
29, // 21: iam_pb.PutIdentityRequest.identity:type_name -> iam_pb.Identity 0, // 21: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:input_type -> iam_pb.GetConfigurationRequest
0, // 22: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:input_type -> iam_pb.GetConfigurationRequest 2, // 22: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:input_type -> iam_pb.PutConfigurationRequest
2, // 23: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:input_type -> iam_pb.PutConfigurationRequest 4, // 23: iam_pb.SeaweedIdentityAccessManagement.CreateUser:input_type -> iam_pb.CreateUserRequest
4, // 24: iam_pb.SeaweedIdentityAccessManagement.CreateUser:input_type -> iam_pb.CreateUserRequest 6, // 24: iam_pb.SeaweedIdentityAccessManagement.GetUser:input_type -> iam_pb.GetUserRequest
6, // 25: iam_pb.SeaweedIdentityAccessManagement.GetUser:input_type -> iam_pb.GetUserRequest 8, // 25: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:input_type -> iam_pb.UpdateUserRequest
8, // 26: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:input_type -> iam_pb.UpdateUserRequest 10, // 26: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:input_type -> iam_pb.DeleteUserRequest
10, // 27: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:input_type -> iam_pb.DeleteUserRequest 12, // 27: iam_pb.SeaweedIdentityAccessManagement.ListUsers:input_type -> iam_pb.ListUsersRequest
12, // 28: iam_pb.SeaweedIdentityAccessManagement.ListUsers:input_type -> iam_pb.ListUsersRequest 14, // 28: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:input_type -> iam_pb.CreateAccessKeyRequest
14, // 29: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:input_type -> iam_pb.CreateAccessKeyRequest 16, // 29: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:input_type -> iam_pb.DeleteAccessKeyRequest
16, // 30: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:input_type -> iam_pb.DeleteAccessKeyRequest 18, // 30: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:input_type -> iam_pb.GetUserByAccessKeyRequest
18, // 31: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:input_type -> iam_pb.GetUserByAccessKeyRequest 33, // 31: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:input_type -> iam_pb.PutPolicyRequest
33, // 32: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:input_type -> iam_pb.PutPolicyRequest 35, // 32: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:input_type -> iam_pb.GetPolicyRequest
35, // 33: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:input_type -> iam_pb.GetPolicyRequest 37, // 33: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:input_type -> iam_pb.ListPoliciesRequest
37, // 34: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:input_type -> iam_pb.ListPoliciesRequest 39, // 34: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:input_type -> iam_pb.DeletePolicyRequest
39, // 35: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:input_type -> iam_pb.DeletePolicyRequest 42, // 35: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:input_type -> iam_pb.CreateServiceAccountRequest
42, // 36: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:input_type -> iam_pb.CreateServiceAccountRequest 44, // 36: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:input_type -> iam_pb.UpdateServiceAccountRequest
44, // 37: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:input_type -> iam_pb.UpdateServiceAccountRequest 46, // 37: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:input_type -> iam_pb.DeleteServiceAccountRequest
46, // 38: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:input_type -> iam_pb.DeleteServiceAccountRequest 48, // 38: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:input_type -> iam_pb.GetServiceAccountRequest
48, // 39: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:input_type -> iam_pb.GetServiceAccountRequest 50, // 39: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:input_type -> iam_pb.ListServiceAccountsRequest
50, // 40: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:input_type -> iam_pb.ListServiceAccountsRequest 52, // 40: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccountByAccessKey:input_type -> iam_pb.GetServiceAccountByAccessKeyRequest
52, // 41: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccountByAccessKey:input_type -> iam_pb.GetServiceAccountByAccessKeyRequest 1, // 41: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:output_type -> iam_pb.GetConfigurationResponse
1, // 42: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:output_type -> iam_pb.GetConfigurationResponse 3, // 42: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:output_type -> iam_pb.PutConfigurationResponse
3, // 43: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:output_type -> iam_pb.PutConfigurationResponse 5, // 43: iam_pb.SeaweedIdentityAccessManagement.CreateUser:output_type -> iam_pb.CreateUserResponse
5, // 44: iam_pb.SeaweedIdentityAccessManagement.CreateUser:output_type -> iam_pb.CreateUserResponse 7, // 44: iam_pb.SeaweedIdentityAccessManagement.GetUser:output_type -> iam_pb.GetUserResponse
7, // 45: iam_pb.SeaweedIdentityAccessManagement.GetUser:output_type -> iam_pb.GetUserResponse 9, // 45: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:output_type -> iam_pb.UpdateUserResponse
9, // 46: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:output_type -> iam_pb.UpdateUserResponse 11, // 46: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:output_type -> iam_pb.DeleteUserResponse
11, // 47: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:output_type -> iam_pb.DeleteUserResponse 13, // 47: iam_pb.SeaweedIdentityAccessManagement.ListUsers:output_type -> iam_pb.ListUsersResponse
13, // 48: iam_pb.SeaweedIdentityAccessManagement.ListUsers:output_type -> iam_pb.ListUsersResponse 15, // 48: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:output_type -> iam_pb.CreateAccessKeyResponse
15, // 49: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:output_type -> iam_pb.CreateAccessKeyResponse 17, // 49: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:output_type -> iam_pb.DeleteAccessKeyResponse
17, // 50: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:output_type -> iam_pb.DeleteAccessKeyResponse 19, // 50: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:output_type -> iam_pb.GetUserByAccessKeyResponse
19, // 51: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:output_type -> iam_pb.GetUserByAccessKeyResponse 34, // 51: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:output_type -> iam_pb.PutPolicyResponse
34, // 52: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:output_type -> iam_pb.PutPolicyResponse 36, // 52: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:output_type -> iam_pb.GetPolicyResponse
36, // 53: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:output_type -> iam_pb.GetPolicyResponse 38, // 53: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:output_type -> iam_pb.ListPoliciesResponse
38, // 54: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:output_type -> iam_pb.ListPoliciesResponse 40, // 54: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:output_type -> iam_pb.DeletePolicyResponse
40, // 55: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:output_type -> iam_pb.DeletePolicyResponse 43, // 55: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:output_type -> iam_pb.CreateServiceAccountResponse
43, // 56: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:output_type -> iam_pb.CreateServiceAccountResponse 45, // 56: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:output_type -> iam_pb.UpdateServiceAccountResponse
45, // 57: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:output_type -> iam_pb.UpdateServiceAccountResponse 47, // 57: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:output_type -> iam_pb.DeleteServiceAccountResponse
47, // 58: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:output_type -> iam_pb.DeleteServiceAccountResponse 49, // 58: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:output_type -> iam_pb.GetServiceAccountResponse
49, // 59: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:output_type -> iam_pb.GetServiceAccountResponse 51, // 59: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:output_type -> iam_pb.ListServiceAccountsResponse
51, // 60: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:output_type -> iam_pb.ListServiceAccountsResponse 53, // 60: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccountByAccessKey:output_type -> iam_pb.GetServiceAccountByAccessKeyResponse
53, // 61: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccountByAccessKey:output_type -> iam_pb.GetServiceAccountByAccessKeyResponse 41, // [41:61] is the sub-list for method output_type
42, // [42:62] is the sub-list for method output_type 21, // [21:41] is the sub-list for method input_type
22, // [22:42] is the sub-list for method input_type 21, // [21:21] is the sub-list for extension type_name
22, // [22:22] is the sub-list for extension type_name 21, // [21:21] is the sub-list for extension extendee
22, // [22:22] is the sub-list for extension extendee 0, // [0:21] is the sub-list for field type_name
0, // [0:22] is the sub-list for field type_name
} }
func init() { file_iam_proto_init() } func init() { file_iam_proto_init() }
@@ -3034,7 +2863,7 @@ func file_iam_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_iam_proto_rawDesc), len(file_iam_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_iam_proto_rawDesc), len(file_iam_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 58, NumMessages: 54,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },
+23 -8
View File
@@ -10,14 +10,29 @@ option java_outer_classname = "S3Proto";
import "iam.proto"; import "iam.proto";
// Designed for unidirectional propagation from Filer to S3 Servers service SeaweedS3 {
service SeaweedS3IamCache {
rpc PutIdentity (iam_pb.PutIdentityRequest) returns (iam_pb.PutIdentityResponse); // Explicit IAM APIs mirroring SeaweedIdentityAccessManagement
rpc RemoveIdentity (iam_pb.RemoveIdentityRequest) returns (iam_pb.RemoveIdentityResponse); rpc ListUsers (iam_pb.ListUsersRequest) returns (iam_pb.ListUsersResponse) {}
rpc PutPolicy (iam_pb.PutPolicyRequest) returns (iam_pb.PutPolicyResponse); rpc CreateUser (iam_pb.CreateUserRequest) returns (iam_pb.CreateUserResponse) {}
rpc GetPolicy (iam_pb.GetPolicyRequest) returns (iam_pb.GetPolicyResponse); rpc GetUser (iam_pb.GetUserRequest) returns (iam_pb.GetUserResponse) {}
rpc ListPolicies (iam_pb.ListPoliciesRequest) returns (iam_pb.ListPoliciesResponse); rpc UpdateUser (iam_pb.UpdateUserRequest) returns (iam_pb.UpdateUserResponse) {}
rpc DeletePolicy (iam_pb.DeletePolicyRequest) returns (iam_pb.DeletePolicyResponse); rpc DeleteUser (iam_pb.DeleteUserRequest) returns (iam_pb.DeleteUserResponse) {}
rpc ListAccessKeys (iam_pb.ListAccessKeysRequest) returns (iam_pb.ListAccessKeysResponse) {}
rpc CreateAccessKey (iam_pb.CreateAccessKeyRequest) returns (iam_pb.CreateAccessKeyResponse) {}
rpc DeleteAccessKey (iam_pb.DeleteAccessKeyRequest) returns (iam_pb.DeleteAccessKeyResponse) {}
rpc PutUserPolicy (iam_pb.PutUserPolicyRequest) returns (iam_pb.PutUserPolicyResponse) {}
rpc GetUserPolicy (iam_pb.GetUserPolicyRequest) returns (iam_pb.GetUserPolicyResponse) {}
rpc DeleteUserPolicy (iam_pb.DeleteUserPolicyRequest) returns (iam_pb.DeleteUserPolicyResponse) {}
rpc ListServiceAccounts (iam_pb.ListServiceAccountsRequest) returns (iam_pb.ListServiceAccountsResponse) {}
rpc CreateServiceAccount (iam_pb.CreateServiceAccountRequest) returns (iam_pb.CreateServiceAccountResponse) {}
rpc UpdateServiceAccount (iam_pb.UpdateServiceAccountRequest) returns (iam_pb.UpdateServiceAccountResponse) {}
rpc DeleteServiceAccount (iam_pb.DeleteServiceAccountRequest) returns (iam_pb.DeleteServiceAccountResponse) {}
rpc GetServiceAccount (iam_pb.GetServiceAccountRequest) returns (iam_pb.GetServiceAccountResponse) {}
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
+97 -43
View File
@@ -414,14 +414,28 @@ const file_s3_proto_rawDesc = "" +
"\rsse_algorithm\x18\x01 \x01(\tR\fsseAlgorithm\x12\x1c\n" + "\rsse_algorithm\x18\x01 \x01(\tR\fsseAlgorithm\x12\x1c\n" +
"\n" + "\n" +
"kms_key_id\x18\x02 \x01(\tR\bkmsKeyId\x12,\n" + "kms_key_id\x18\x02 \x01(\tR\bkmsKeyId\x12,\n" +
"\x12bucket_key_enabled\x18\x03 \x01(\bR\x10bucketKeyEnabled2\xc6\x03\n" + "\x12bucket_key_enabled\x18\x03 \x01(\bR\x10bucketKeyEnabled2\xc7\n" +
"\x11SeaweedS3IamCache\x12F\n" + "\n" +
"\vPutIdentity\x12\x1a.iam_pb.PutIdentityRequest\x1a\x1b.iam_pb.PutIdentityResponse\x12O\n" + "\tSeaweedS3\x12B\n" +
"\x0eRemoveIdentity\x12\x1d.iam_pb.RemoveIdentityRequest\x1a\x1e.iam_pb.RemoveIdentityResponse\x12@\n" + "\tListUsers\x12\x18.iam_pb.ListUsersRequest\x1a\x19.iam_pb.ListUsersResponse\"\x00\x12E\n" +
"\tPutPolicy\x12\x18.iam_pb.PutPolicyRequest\x1a\x19.iam_pb.PutPolicyResponse\x12@\n" + "\n" +
"\tGetPolicy\x12\x18.iam_pb.GetPolicyRequest\x1a\x19.iam_pb.GetPolicyResponse\x12I\n" + "CreateUser\x12\x19.iam_pb.CreateUserRequest\x1a\x1a.iam_pb.CreateUserResponse\"\x00\x12<\n" +
"\fListPolicies\x12\x1b.iam_pb.ListPoliciesRequest\x1a\x1c.iam_pb.ListPoliciesResponse\x12I\n" + "\aGetUser\x12\x16.iam_pb.GetUserRequest\x1a\x17.iam_pb.GetUserResponse\"\x00\x12E\n" +
"\fDeletePolicy\x12\x1b.iam_pb.DeletePolicyRequest\x1a\x1c.iam_pb.DeletePolicyResponseBI\n" + "\n" +
"UpdateUser\x12\x19.iam_pb.UpdateUserRequest\x1a\x1a.iam_pb.UpdateUserResponse\"\x00\x12E\n" +
"\n" +
"DeleteUser\x12\x19.iam_pb.DeleteUserRequest\x1a\x1a.iam_pb.DeleteUserResponse\"\x00\x12Q\n" +
"\x0eListAccessKeys\x12\x1d.iam_pb.ListAccessKeysRequest\x1a\x1e.iam_pb.ListAccessKeysResponse\"\x00\x12T\n" +
"\x0fCreateAccessKey\x12\x1e.iam_pb.CreateAccessKeyRequest\x1a\x1f.iam_pb.CreateAccessKeyResponse\"\x00\x12T\n" +
"\x0fDeleteAccessKey\x12\x1e.iam_pb.DeleteAccessKeyRequest\x1a\x1f.iam_pb.DeleteAccessKeyResponse\"\x00\x12N\n" +
"\rPutUserPolicy\x12\x1c.iam_pb.PutUserPolicyRequest\x1a\x1d.iam_pb.PutUserPolicyResponse\"\x00\x12N\n" +
"\rGetUserPolicy\x12\x1c.iam_pb.GetUserPolicyRequest\x1a\x1d.iam_pb.GetUserPolicyResponse\"\x00\x12W\n" +
"\x10DeleteUserPolicy\x12\x1f.iam_pb.DeleteUserPolicyRequest\x1a .iam_pb.DeleteUserPolicyResponse\"\x00\x12`\n" +
"\x13ListServiceAccounts\x12\".iam_pb.ListServiceAccountsRequest\x1a#.iam_pb.ListServiceAccountsResponse\"\x00\x12c\n" +
"\x14CreateServiceAccount\x12#.iam_pb.CreateServiceAccountRequest\x1a$.iam_pb.CreateServiceAccountResponse\"\x00\x12c\n" +
"\x14UpdateServiceAccount\x12#.iam_pb.UpdateServiceAccountRequest\x1a$.iam_pb.UpdateServiceAccountResponse\"\x00\x12c\n" +
"\x14DeleteServiceAccount\x12#.iam_pb.DeleteServiceAccountRequest\x1a$.iam_pb.DeleteServiceAccountResponse\"\x00\x12Z\n" +
"\x11GetServiceAccount\x12 .iam_pb.GetServiceAccountRequest\x1a!.iam_pb.GetServiceAccountResponse\"\x00BI\n" +
"\x10seaweedfs.clientB\aS3ProtoZ,github.com/seaweedfs/seaweedfs/weed/pb/s3_pbb\x06proto3" "\x10seaweedfs.clientB\aS3ProtoZ,github.com/seaweedfs/seaweedfs/weed/pb/s3_pbb\x06proto3"
var ( var (
@@ -438,27 +452,47 @@ func file_s3_proto_rawDescGZIP() []byte {
var file_s3_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_s3_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_s3_proto_goTypes = []any{ var file_s3_proto_goTypes = []any{
(*S3CircuitBreakerConfig)(nil), // 0: messaging_pb.S3CircuitBreakerConfig (*S3CircuitBreakerConfig)(nil), // 0: messaging_pb.S3CircuitBreakerConfig
(*S3CircuitBreakerOptions)(nil), // 1: messaging_pb.S3CircuitBreakerOptions (*S3CircuitBreakerOptions)(nil), // 1: messaging_pb.S3CircuitBreakerOptions
(*CORSRule)(nil), // 2: messaging_pb.CORSRule (*CORSRule)(nil), // 2: messaging_pb.CORSRule
(*CORSConfiguration)(nil), // 3: messaging_pb.CORSConfiguration (*CORSConfiguration)(nil), // 3: messaging_pb.CORSConfiguration
(*BucketMetadata)(nil), // 4: messaging_pb.BucketMetadata (*BucketMetadata)(nil), // 4: messaging_pb.BucketMetadata
(*EncryptionConfiguration)(nil), // 5: messaging_pb.EncryptionConfiguration (*EncryptionConfiguration)(nil), // 5: messaging_pb.EncryptionConfiguration
nil, // 6: messaging_pb.S3CircuitBreakerConfig.BucketsEntry nil, // 6: messaging_pb.S3CircuitBreakerConfig.BucketsEntry
nil, // 7: messaging_pb.S3CircuitBreakerOptions.ActionsEntry nil, // 7: messaging_pb.S3CircuitBreakerOptions.ActionsEntry
nil, // 8: messaging_pb.BucketMetadata.TagsEntry nil, // 8: messaging_pb.BucketMetadata.TagsEntry
(*iam_pb.PutIdentityRequest)(nil), // 9: iam_pb.PutIdentityRequest (*iam_pb.ListUsersRequest)(nil), // 9: iam_pb.ListUsersRequest
(*iam_pb.RemoveIdentityRequest)(nil), // 10: iam_pb.RemoveIdentityRequest (*iam_pb.CreateUserRequest)(nil), // 10: iam_pb.CreateUserRequest
(*iam_pb.PutPolicyRequest)(nil), // 11: iam_pb.PutPolicyRequest (*iam_pb.GetUserRequest)(nil), // 11: iam_pb.GetUserRequest
(*iam_pb.GetPolicyRequest)(nil), // 12: iam_pb.GetPolicyRequest (*iam_pb.UpdateUserRequest)(nil), // 12: iam_pb.UpdateUserRequest
(*iam_pb.ListPoliciesRequest)(nil), // 13: iam_pb.ListPoliciesRequest (*iam_pb.DeleteUserRequest)(nil), // 13: iam_pb.DeleteUserRequest
(*iam_pb.DeletePolicyRequest)(nil), // 14: iam_pb.DeletePolicyRequest (*iam_pb.ListAccessKeysRequest)(nil), // 14: iam_pb.ListAccessKeysRequest
(*iam_pb.PutIdentityResponse)(nil), // 15: iam_pb.PutIdentityResponse (*iam_pb.CreateAccessKeyRequest)(nil), // 15: iam_pb.CreateAccessKeyRequest
(*iam_pb.RemoveIdentityResponse)(nil), // 16: iam_pb.RemoveIdentityResponse (*iam_pb.DeleteAccessKeyRequest)(nil), // 16: iam_pb.DeleteAccessKeyRequest
(*iam_pb.PutPolicyResponse)(nil), // 17: iam_pb.PutPolicyResponse (*iam_pb.PutUserPolicyRequest)(nil), // 17: iam_pb.PutUserPolicyRequest
(*iam_pb.GetPolicyResponse)(nil), // 18: iam_pb.GetPolicyResponse (*iam_pb.GetUserPolicyRequest)(nil), // 18: iam_pb.GetUserPolicyRequest
(*iam_pb.ListPoliciesResponse)(nil), // 19: iam_pb.ListPoliciesResponse (*iam_pb.DeleteUserPolicyRequest)(nil), // 19: iam_pb.DeleteUserPolicyRequest
(*iam_pb.DeletePolicyResponse)(nil), // 20: iam_pb.DeletePolicyResponse (*iam_pb.ListServiceAccountsRequest)(nil), // 20: iam_pb.ListServiceAccountsRequest
(*iam_pb.CreateServiceAccountRequest)(nil), // 21: iam_pb.CreateServiceAccountRequest
(*iam_pb.UpdateServiceAccountRequest)(nil), // 22: iam_pb.UpdateServiceAccountRequest
(*iam_pb.DeleteServiceAccountRequest)(nil), // 23: iam_pb.DeleteServiceAccountRequest
(*iam_pb.GetServiceAccountRequest)(nil), // 24: iam_pb.GetServiceAccountRequest
(*iam_pb.ListUsersResponse)(nil), // 25: iam_pb.ListUsersResponse
(*iam_pb.CreateUserResponse)(nil), // 26: iam_pb.CreateUserResponse
(*iam_pb.GetUserResponse)(nil), // 27: iam_pb.GetUserResponse
(*iam_pb.UpdateUserResponse)(nil), // 28: iam_pb.UpdateUserResponse
(*iam_pb.DeleteUserResponse)(nil), // 29: iam_pb.DeleteUserResponse
(*iam_pb.ListAccessKeysResponse)(nil), // 30: iam_pb.ListAccessKeysResponse
(*iam_pb.CreateAccessKeyResponse)(nil), // 31: iam_pb.CreateAccessKeyResponse
(*iam_pb.DeleteAccessKeyResponse)(nil), // 32: iam_pb.DeleteAccessKeyResponse
(*iam_pb.PutUserPolicyResponse)(nil), // 33: iam_pb.PutUserPolicyResponse
(*iam_pb.GetUserPolicyResponse)(nil), // 34: iam_pb.GetUserPolicyResponse
(*iam_pb.DeleteUserPolicyResponse)(nil), // 35: iam_pb.DeleteUserPolicyResponse
(*iam_pb.ListServiceAccountsResponse)(nil), // 36: iam_pb.ListServiceAccountsResponse
(*iam_pb.CreateServiceAccountResponse)(nil), // 37: iam_pb.CreateServiceAccountResponse
(*iam_pb.UpdateServiceAccountResponse)(nil), // 38: iam_pb.UpdateServiceAccountResponse
(*iam_pb.DeleteServiceAccountResponse)(nil), // 39: iam_pb.DeleteServiceAccountResponse
(*iam_pb.GetServiceAccountResponse)(nil), // 40: iam_pb.GetServiceAccountResponse
} }
var file_s3_proto_depIdxs = []int32{ var file_s3_proto_depIdxs = []int32{
1, // 0: messaging_pb.S3CircuitBreakerConfig.global:type_name -> messaging_pb.S3CircuitBreakerOptions 1, // 0: messaging_pb.S3CircuitBreakerConfig.global:type_name -> messaging_pb.S3CircuitBreakerOptions
@@ -469,20 +503,40 @@ var file_s3_proto_depIdxs = []int32{
3, // 5: messaging_pb.BucketMetadata.cors:type_name -> messaging_pb.CORSConfiguration 3, // 5: messaging_pb.BucketMetadata.cors:type_name -> messaging_pb.CORSConfiguration
5, // 6: messaging_pb.BucketMetadata.encryption:type_name -> messaging_pb.EncryptionConfiguration 5, // 6: messaging_pb.BucketMetadata.encryption:type_name -> messaging_pb.EncryptionConfiguration
1, // 7: messaging_pb.S3CircuitBreakerConfig.BucketsEntry.value:type_name -> messaging_pb.S3CircuitBreakerOptions 1, // 7: messaging_pb.S3CircuitBreakerConfig.BucketsEntry.value:type_name -> messaging_pb.S3CircuitBreakerOptions
9, // 8: messaging_pb.SeaweedS3IamCache.PutIdentity:input_type -> iam_pb.PutIdentityRequest 9, // 8: messaging_pb.SeaweedS3.ListUsers:input_type -> iam_pb.ListUsersRequest
10, // 9: messaging_pb.SeaweedS3IamCache.RemoveIdentity:input_type -> iam_pb.RemoveIdentityRequest 10, // 9: messaging_pb.SeaweedS3.CreateUser:input_type -> iam_pb.CreateUserRequest
11, // 10: messaging_pb.SeaweedS3IamCache.PutPolicy:input_type -> iam_pb.PutPolicyRequest 11, // 10: messaging_pb.SeaweedS3.GetUser:input_type -> iam_pb.GetUserRequest
12, // 11: messaging_pb.SeaweedS3IamCache.GetPolicy:input_type -> iam_pb.GetPolicyRequest 12, // 11: messaging_pb.SeaweedS3.UpdateUser:input_type -> iam_pb.UpdateUserRequest
13, // 12: messaging_pb.SeaweedS3IamCache.ListPolicies:input_type -> iam_pb.ListPoliciesRequest 13, // 12: messaging_pb.SeaweedS3.DeleteUser:input_type -> iam_pb.DeleteUserRequest
14, // 13: messaging_pb.SeaweedS3IamCache.DeletePolicy:input_type -> iam_pb.DeletePolicyRequest 14, // 13: messaging_pb.SeaweedS3.ListAccessKeys:input_type -> iam_pb.ListAccessKeysRequest
15, // 14: messaging_pb.SeaweedS3IamCache.PutIdentity:output_type -> iam_pb.PutIdentityResponse 15, // 14: messaging_pb.SeaweedS3.CreateAccessKey:input_type -> iam_pb.CreateAccessKeyRequest
16, // 15: messaging_pb.SeaweedS3IamCache.RemoveIdentity:output_type -> iam_pb.RemoveIdentityResponse 16, // 15: messaging_pb.SeaweedS3.DeleteAccessKey:input_type -> iam_pb.DeleteAccessKeyRequest
17, // 16: messaging_pb.SeaweedS3IamCache.PutPolicy:output_type -> iam_pb.PutPolicyResponse 17, // 16: messaging_pb.SeaweedS3.PutUserPolicy:input_type -> iam_pb.PutUserPolicyRequest
18, // 17: messaging_pb.SeaweedS3IamCache.GetPolicy:output_type -> iam_pb.GetPolicyResponse 18, // 17: messaging_pb.SeaweedS3.GetUserPolicy:input_type -> iam_pb.GetUserPolicyRequest
19, // 18: messaging_pb.SeaweedS3IamCache.ListPolicies:output_type -> iam_pb.ListPoliciesResponse 19, // 18: messaging_pb.SeaweedS3.DeleteUserPolicy:input_type -> iam_pb.DeleteUserPolicyRequest
20, // 19: messaging_pb.SeaweedS3IamCache.DeletePolicy:output_type -> iam_pb.DeletePolicyResponse 20, // 19: messaging_pb.SeaweedS3.ListServiceAccounts:input_type -> iam_pb.ListServiceAccountsRequest
14, // [14:20] is the sub-list for method output_type 21, // 20: messaging_pb.SeaweedS3.CreateServiceAccount:input_type -> iam_pb.CreateServiceAccountRequest
8, // [8:14] is the sub-list for method input_type 22, // 21: messaging_pb.SeaweedS3.UpdateServiceAccount:input_type -> iam_pb.UpdateServiceAccountRequest
23, // 22: messaging_pb.SeaweedS3.DeleteServiceAccount:input_type -> iam_pb.DeleteServiceAccountRequest
24, // 23: messaging_pb.SeaweedS3.GetServiceAccount:input_type -> iam_pb.GetServiceAccountRequest
25, // 24: messaging_pb.SeaweedS3.ListUsers:output_type -> iam_pb.ListUsersResponse
26, // 25: messaging_pb.SeaweedS3.CreateUser:output_type -> iam_pb.CreateUserResponse
27, // 26: messaging_pb.SeaweedS3.GetUser:output_type -> iam_pb.GetUserResponse
28, // 27: messaging_pb.SeaweedS3.UpdateUser:output_type -> iam_pb.UpdateUserResponse
29, // 28: messaging_pb.SeaweedS3.DeleteUser:output_type -> iam_pb.DeleteUserResponse
30, // 29: messaging_pb.SeaweedS3.ListAccessKeys:output_type -> iam_pb.ListAccessKeysResponse
31, // 30: messaging_pb.SeaweedS3.CreateAccessKey:output_type -> iam_pb.CreateAccessKeyResponse
32, // 31: messaging_pb.SeaweedS3.DeleteAccessKey:output_type -> iam_pb.DeleteAccessKeyResponse
33, // 32: messaging_pb.SeaweedS3.PutUserPolicy:output_type -> iam_pb.PutUserPolicyResponse
34, // 33: messaging_pb.SeaweedS3.GetUserPolicy:output_type -> iam_pb.GetUserPolicyResponse
35, // 34: messaging_pb.SeaweedS3.DeleteUserPolicy:output_type -> iam_pb.DeleteUserPolicyResponse
36, // 35: messaging_pb.SeaweedS3.ListServiceAccounts:output_type -> iam_pb.ListServiceAccountsResponse
37, // 36: messaging_pb.SeaweedS3.CreateServiceAccount:output_type -> iam_pb.CreateServiceAccountResponse
38, // 37: messaging_pb.SeaweedS3.UpdateServiceAccount:output_type -> iam_pb.UpdateServiceAccountResponse
39, // 38: messaging_pb.SeaweedS3.DeleteServiceAccount:output_type -> iam_pb.DeleteServiceAccountResponse
40, // 39: messaging_pb.SeaweedS3.GetServiceAccount:output_type -> iam_pb.GetServiceAccountResponse
24, // [24:40] is the sub-list for method output_type
8, // [8:24] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name 8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee 8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name 0, // [0:8] is the sub-list for field type_name
+496 -118
View File
@@ -20,295 +20,673 @@ import (
const _ = grpc.SupportPackageIsVersion9 const _ = grpc.SupportPackageIsVersion9
const ( const (
SeaweedS3IamCache_PutIdentity_FullMethodName = "/messaging_pb.SeaweedS3IamCache/PutIdentity" SeaweedS3_ListUsers_FullMethodName = "/messaging_pb.SeaweedS3/ListUsers"
SeaweedS3IamCache_RemoveIdentity_FullMethodName = "/messaging_pb.SeaweedS3IamCache/RemoveIdentity" SeaweedS3_CreateUser_FullMethodName = "/messaging_pb.SeaweedS3/CreateUser"
SeaweedS3IamCache_PutPolicy_FullMethodName = "/messaging_pb.SeaweedS3IamCache/PutPolicy" SeaweedS3_GetUser_FullMethodName = "/messaging_pb.SeaweedS3/GetUser"
SeaweedS3IamCache_GetPolicy_FullMethodName = "/messaging_pb.SeaweedS3IamCache/GetPolicy" SeaweedS3_UpdateUser_FullMethodName = "/messaging_pb.SeaweedS3/UpdateUser"
SeaweedS3IamCache_ListPolicies_FullMethodName = "/messaging_pb.SeaweedS3IamCache/ListPolicies" SeaweedS3_DeleteUser_FullMethodName = "/messaging_pb.SeaweedS3/DeleteUser"
SeaweedS3IamCache_DeletePolicy_FullMethodName = "/messaging_pb.SeaweedS3IamCache/DeletePolicy" SeaweedS3_ListAccessKeys_FullMethodName = "/messaging_pb.SeaweedS3/ListAccessKeys"
SeaweedS3_CreateAccessKey_FullMethodName = "/messaging_pb.SeaweedS3/CreateAccessKey"
SeaweedS3_DeleteAccessKey_FullMethodName = "/messaging_pb.SeaweedS3/DeleteAccessKey"
SeaweedS3_PutUserPolicy_FullMethodName = "/messaging_pb.SeaweedS3/PutUserPolicy"
SeaweedS3_GetUserPolicy_FullMethodName = "/messaging_pb.SeaweedS3/GetUserPolicy"
SeaweedS3_DeleteUserPolicy_FullMethodName = "/messaging_pb.SeaweedS3/DeleteUserPolicy"
SeaweedS3_ListServiceAccounts_FullMethodName = "/messaging_pb.SeaweedS3/ListServiceAccounts"
SeaweedS3_CreateServiceAccount_FullMethodName = "/messaging_pb.SeaweedS3/CreateServiceAccount"
SeaweedS3_UpdateServiceAccount_FullMethodName = "/messaging_pb.SeaweedS3/UpdateServiceAccount"
SeaweedS3_DeleteServiceAccount_FullMethodName = "/messaging_pb.SeaweedS3/DeleteServiceAccount"
SeaweedS3_GetServiceAccount_FullMethodName = "/messaging_pb.SeaweedS3/GetServiceAccount"
) )
// SeaweedS3IamCacheClient is the client API for SeaweedS3IamCache service. // SeaweedS3Client is the client API for SeaweedS3 service.
// //
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
// type SeaweedS3Client interface {
// Designed for unidirectional propagation from Filer to S3 Servers // Explicit IAM APIs mirroring SeaweedIdentityAccessManagement
type SeaweedS3IamCacheClient interface { ListUsers(ctx context.Context, in *iam_pb.ListUsersRequest, opts ...grpc.CallOption) (*iam_pb.ListUsersResponse, error)
PutIdentity(ctx context.Context, in *iam_pb.PutIdentityRequest, opts ...grpc.CallOption) (*iam_pb.PutIdentityResponse, error) CreateUser(ctx context.Context, in *iam_pb.CreateUserRequest, opts ...grpc.CallOption) (*iam_pb.CreateUserResponse, error)
RemoveIdentity(ctx context.Context, in *iam_pb.RemoveIdentityRequest, opts ...grpc.CallOption) (*iam_pb.RemoveIdentityResponse, error) GetUser(ctx context.Context, in *iam_pb.GetUserRequest, opts ...grpc.CallOption) (*iam_pb.GetUserResponse, error)
PutPolicy(ctx context.Context, in *iam_pb.PutPolicyRequest, opts ...grpc.CallOption) (*iam_pb.PutPolicyResponse, error) UpdateUser(ctx context.Context, in *iam_pb.UpdateUserRequest, opts ...grpc.CallOption) (*iam_pb.UpdateUserResponse, error)
GetPolicy(ctx context.Context, in *iam_pb.GetPolicyRequest, opts ...grpc.CallOption) (*iam_pb.GetPolicyResponse, error) DeleteUser(ctx context.Context, in *iam_pb.DeleteUserRequest, opts ...grpc.CallOption) (*iam_pb.DeleteUserResponse, error)
ListPolicies(ctx context.Context, in *iam_pb.ListPoliciesRequest, opts ...grpc.CallOption) (*iam_pb.ListPoliciesResponse, error) ListAccessKeys(ctx context.Context, in *iam_pb.ListAccessKeysRequest, opts ...grpc.CallOption) (*iam_pb.ListAccessKeysResponse, error)
DeletePolicy(ctx context.Context, in *iam_pb.DeletePolicyRequest, opts ...grpc.CallOption) (*iam_pb.DeletePolicyResponse, error) CreateAccessKey(ctx context.Context, in *iam_pb.CreateAccessKeyRequest, opts ...grpc.CallOption) (*iam_pb.CreateAccessKeyResponse, error)
DeleteAccessKey(ctx context.Context, in *iam_pb.DeleteAccessKeyRequest, opts ...grpc.CallOption) (*iam_pb.DeleteAccessKeyResponse, error)
PutUserPolicy(ctx context.Context, in *iam_pb.PutUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.PutUserPolicyResponse, error)
GetUserPolicy(ctx context.Context, in *iam_pb.GetUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.GetUserPolicyResponse, error)
DeleteUserPolicy(ctx context.Context, in *iam_pb.DeleteUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.DeleteUserPolicyResponse, error)
ListServiceAccounts(ctx context.Context, in *iam_pb.ListServiceAccountsRequest, opts ...grpc.CallOption) (*iam_pb.ListServiceAccountsResponse, error)
CreateServiceAccount(ctx context.Context, in *iam_pb.CreateServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.CreateServiceAccountResponse, error)
UpdateServiceAccount(ctx context.Context, in *iam_pb.UpdateServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.UpdateServiceAccountResponse, error)
DeleteServiceAccount(ctx context.Context, in *iam_pb.DeleteServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.DeleteServiceAccountResponse, error)
GetServiceAccount(ctx context.Context, in *iam_pb.GetServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.GetServiceAccountResponse, error)
} }
type seaweedS3IamCacheClient struct { type seaweedS3Client struct {
cc grpc.ClientConnInterface cc grpc.ClientConnInterface
} }
func NewSeaweedS3IamCacheClient(cc grpc.ClientConnInterface) SeaweedS3IamCacheClient { func NewSeaweedS3Client(cc grpc.ClientConnInterface) SeaweedS3Client {
return &seaweedS3IamCacheClient{cc} return &seaweedS3Client{cc}
} }
func (c *seaweedS3IamCacheClient) PutIdentity(ctx context.Context, in *iam_pb.PutIdentityRequest, opts ...grpc.CallOption) (*iam_pb.PutIdentityResponse, error) { func (c *seaweedS3Client) ListUsers(ctx context.Context, in *iam_pb.ListUsersRequest, opts ...grpc.CallOption) (*iam_pb.ListUsersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.PutIdentityResponse) out := new(iam_pb.ListUsersResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_PutIdentity_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_ListUsers_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *seaweedS3IamCacheClient) RemoveIdentity(ctx context.Context, in *iam_pb.RemoveIdentityRequest, opts ...grpc.CallOption) (*iam_pb.RemoveIdentityResponse, error) { func (c *seaweedS3Client) CreateUser(ctx context.Context, in *iam_pb.CreateUserRequest, opts ...grpc.CallOption) (*iam_pb.CreateUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.RemoveIdentityResponse) out := new(iam_pb.CreateUserResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_RemoveIdentity_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_CreateUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *seaweedS3IamCacheClient) PutPolicy(ctx context.Context, in *iam_pb.PutPolicyRequest, opts ...grpc.CallOption) (*iam_pb.PutPolicyResponse, error) { func (c *seaweedS3Client) GetUser(ctx context.Context, in *iam_pb.GetUserRequest, opts ...grpc.CallOption) (*iam_pb.GetUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.PutPolicyResponse) out := new(iam_pb.GetUserResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_PutPolicy_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_GetUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *seaweedS3IamCacheClient) GetPolicy(ctx context.Context, in *iam_pb.GetPolicyRequest, opts ...grpc.CallOption) (*iam_pb.GetPolicyResponse, error) { func (c *seaweedS3Client) UpdateUser(ctx context.Context, in *iam_pb.UpdateUserRequest, opts ...grpc.CallOption) (*iam_pb.UpdateUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.GetPolicyResponse) out := new(iam_pb.UpdateUserResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_GetPolicy_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_UpdateUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *seaweedS3IamCacheClient) ListPolicies(ctx context.Context, in *iam_pb.ListPoliciesRequest, opts ...grpc.CallOption) (*iam_pb.ListPoliciesResponse, error) { func (c *seaweedS3Client) DeleteUser(ctx context.Context, in *iam_pb.DeleteUserRequest, opts ...grpc.CallOption) (*iam_pb.DeleteUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.ListPoliciesResponse) out := new(iam_pb.DeleteUserResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_ListPolicies_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_DeleteUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *seaweedS3IamCacheClient) DeletePolicy(ctx context.Context, in *iam_pb.DeletePolicyRequest, opts ...grpc.CallOption) (*iam_pb.DeletePolicyResponse, error) { func (c *seaweedS3Client) ListAccessKeys(ctx context.Context, in *iam_pb.ListAccessKeysRequest, opts ...grpc.CallOption) (*iam_pb.ListAccessKeysResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.DeletePolicyResponse) out := new(iam_pb.ListAccessKeysResponse)
err := c.cc.Invoke(ctx, SeaweedS3IamCache_DeletePolicy_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, SeaweedS3_ListAccessKeys_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
// SeaweedS3IamCacheServer is the server API for SeaweedS3IamCache service. func (c *seaweedS3Client) CreateAccessKey(ctx context.Context, in *iam_pb.CreateAccessKeyRequest, opts ...grpc.CallOption) (*iam_pb.CreateAccessKeyResponse, error) {
// All implementations must embed UnimplementedSeaweedS3IamCacheServer cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.CreateAccessKeyResponse)
err := c.cc.Invoke(ctx, SeaweedS3_CreateAccessKey_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) DeleteAccessKey(ctx context.Context, in *iam_pb.DeleteAccessKeyRequest, opts ...grpc.CallOption) (*iam_pb.DeleteAccessKeyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.DeleteAccessKeyResponse)
err := c.cc.Invoke(ctx, SeaweedS3_DeleteAccessKey_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) PutUserPolicy(ctx context.Context, in *iam_pb.PutUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.PutUserPolicyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.PutUserPolicyResponse)
err := c.cc.Invoke(ctx, SeaweedS3_PutUserPolicy_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) GetUserPolicy(ctx context.Context, in *iam_pb.GetUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.GetUserPolicyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.GetUserPolicyResponse)
err := c.cc.Invoke(ctx, SeaweedS3_GetUserPolicy_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) DeleteUserPolicy(ctx context.Context, in *iam_pb.DeleteUserPolicyRequest, opts ...grpc.CallOption) (*iam_pb.DeleteUserPolicyResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.DeleteUserPolicyResponse)
err := c.cc.Invoke(ctx, SeaweedS3_DeleteUserPolicy_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) ListServiceAccounts(ctx context.Context, in *iam_pb.ListServiceAccountsRequest, opts ...grpc.CallOption) (*iam_pb.ListServiceAccountsResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.ListServiceAccountsResponse)
err := c.cc.Invoke(ctx, SeaweedS3_ListServiceAccounts_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) CreateServiceAccount(ctx context.Context, in *iam_pb.CreateServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.CreateServiceAccountResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.CreateServiceAccountResponse)
err := c.cc.Invoke(ctx, SeaweedS3_CreateServiceAccount_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) UpdateServiceAccount(ctx context.Context, in *iam_pb.UpdateServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.UpdateServiceAccountResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.UpdateServiceAccountResponse)
err := c.cc.Invoke(ctx, SeaweedS3_UpdateServiceAccount_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) DeleteServiceAccount(ctx context.Context, in *iam_pb.DeleteServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.DeleteServiceAccountResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.DeleteServiceAccountResponse)
err := c.cc.Invoke(ctx, SeaweedS3_DeleteServiceAccount_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedS3Client) GetServiceAccount(ctx context.Context, in *iam_pb.GetServiceAccountRequest, opts ...grpc.CallOption) (*iam_pb.GetServiceAccountResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(iam_pb.GetServiceAccountResponse)
err := c.cc.Invoke(ctx, SeaweedS3_GetServiceAccount_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// SeaweedS3Server is the server API for SeaweedS3 service.
// All implementations must embed UnimplementedSeaweedS3Server
// for forward compatibility. // for forward compatibility.
// type SeaweedS3Server interface {
// Designed for unidirectional propagation from Filer to S3 Servers // Explicit IAM APIs mirroring SeaweedIdentityAccessManagement
type SeaweedS3IamCacheServer interface { ListUsers(context.Context, *iam_pb.ListUsersRequest) (*iam_pb.ListUsersResponse, error)
PutIdentity(context.Context, *iam_pb.PutIdentityRequest) (*iam_pb.PutIdentityResponse, error) CreateUser(context.Context, *iam_pb.CreateUserRequest) (*iam_pb.CreateUserResponse, error)
RemoveIdentity(context.Context, *iam_pb.RemoveIdentityRequest) (*iam_pb.RemoveIdentityResponse, error) GetUser(context.Context, *iam_pb.GetUserRequest) (*iam_pb.GetUserResponse, error)
PutPolicy(context.Context, *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) UpdateUser(context.Context, *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error)
GetPolicy(context.Context, *iam_pb.GetPolicyRequest) (*iam_pb.GetPolicyResponse, error) DeleteUser(context.Context, *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error)
ListPolicies(context.Context, *iam_pb.ListPoliciesRequest) (*iam_pb.ListPoliciesResponse, error) ListAccessKeys(context.Context, *iam_pb.ListAccessKeysRequest) (*iam_pb.ListAccessKeysResponse, error)
DeletePolicy(context.Context, *iam_pb.DeletePolicyRequest) (*iam_pb.DeletePolicyResponse, error) CreateAccessKey(context.Context, *iam_pb.CreateAccessKeyRequest) (*iam_pb.CreateAccessKeyResponse, error)
mustEmbedUnimplementedSeaweedS3IamCacheServer() DeleteAccessKey(context.Context, *iam_pb.DeleteAccessKeyRequest) (*iam_pb.DeleteAccessKeyResponse, error)
PutUserPolicy(context.Context, *iam_pb.PutUserPolicyRequest) (*iam_pb.PutUserPolicyResponse, error)
GetUserPolicy(context.Context, *iam_pb.GetUserPolicyRequest) (*iam_pb.GetUserPolicyResponse, error)
DeleteUserPolicy(context.Context, *iam_pb.DeleteUserPolicyRequest) (*iam_pb.DeleteUserPolicyResponse, error)
ListServiceAccounts(context.Context, *iam_pb.ListServiceAccountsRequest) (*iam_pb.ListServiceAccountsResponse, error)
CreateServiceAccount(context.Context, *iam_pb.CreateServiceAccountRequest) (*iam_pb.CreateServiceAccountResponse, error)
UpdateServiceAccount(context.Context, *iam_pb.UpdateServiceAccountRequest) (*iam_pb.UpdateServiceAccountResponse, error)
DeleteServiceAccount(context.Context, *iam_pb.DeleteServiceAccountRequest) (*iam_pb.DeleteServiceAccountResponse, error)
GetServiceAccount(context.Context, *iam_pb.GetServiceAccountRequest) (*iam_pb.GetServiceAccountResponse, error)
mustEmbedUnimplementedSeaweedS3Server()
} }
// UnimplementedSeaweedS3IamCacheServer must be embedded to have // UnimplementedSeaweedS3Server must be embedded to have
// forward compatible implementations. // forward compatible implementations.
// //
// NOTE: this should be embedded by value instead of pointer to avoid a nil // NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called. // pointer dereference when methods are called.
type UnimplementedSeaweedS3IamCacheServer struct{} type UnimplementedSeaweedS3Server struct{}
func (UnimplementedSeaweedS3IamCacheServer) PutIdentity(context.Context, *iam_pb.PutIdentityRequest) (*iam_pb.PutIdentityResponse, error) { func (UnimplementedSeaweedS3Server) ListUsers(context.Context, *iam_pb.ListUsersRequest) (*iam_pb.ListUsersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PutIdentity not implemented") return nil, status.Errorf(codes.Unimplemented, "method ListUsers not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) RemoveIdentity(context.Context, *iam_pb.RemoveIdentityRequest) (*iam_pb.RemoveIdentityResponse, error) { func (UnimplementedSeaweedS3Server) CreateUser(context.Context, *iam_pb.CreateUserRequest) (*iam_pb.CreateUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RemoveIdentity not implemented") return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) PutPolicy(context.Context, *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) { func (UnimplementedSeaweedS3Server) GetUser(context.Context, *iam_pb.GetUserRequest) (*iam_pb.GetUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PutPolicy not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) GetPolicy(context.Context, *iam_pb.GetPolicyRequest) (*iam_pb.GetPolicyResponse, error) { func (UnimplementedSeaweedS3Server) UpdateUser(context.Context, *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPolicy not implemented") return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) ListPolicies(context.Context, *iam_pb.ListPoliciesRequest) (*iam_pb.ListPoliciesResponse, error) { func (UnimplementedSeaweedS3Server) DeleteUser(context.Context, *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListPolicies not implemented") return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) DeletePolicy(context.Context, *iam_pb.DeletePolicyRequest) (*iam_pb.DeletePolicyResponse, error) { func (UnimplementedSeaweedS3Server) ListAccessKeys(context.Context, *iam_pb.ListAccessKeysRequest) (*iam_pb.ListAccessKeysResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeletePolicy not implemented") return nil, status.Errorf(codes.Unimplemented, "method ListAccessKeys not implemented")
} }
func (UnimplementedSeaweedS3IamCacheServer) mustEmbedUnimplementedSeaweedS3IamCacheServer() {} func (UnimplementedSeaweedS3Server) CreateAccessKey(context.Context, *iam_pb.CreateAccessKeyRequest) (*iam_pb.CreateAccessKeyResponse, error) {
func (UnimplementedSeaweedS3IamCacheServer) testEmbeddedByValue() {} return nil, status.Errorf(codes.Unimplemented, "method CreateAccessKey not implemented")
}
func (UnimplementedSeaweedS3Server) DeleteAccessKey(context.Context, *iam_pb.DeleteAccessKeyRequest) (*iam_pb.DeleteAccessKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteAccessKey not implemented")
}
func (UnimplementedSeaweedS3Server) PutUserPolicy(context.Context, *iam_pb.PutUserPolicyRequest) (*iam_pb.PutUserPolicyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PutUserPolicy not implemented")
}
func (UnimplementedSeaweedS3Server) GetUserPolicy(context.Context, *iam_pb.GetUserPolicyRequest) (*iam_pb.GetUserPolicyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserPolicy not implemented")
}
func (UnimplementedSeaweedS3Server) DeleteUserPolicy(context.Context, *iam_pb.DeleteUserPolicyRequest) (*iam_pb.DeleteUserPolicyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteUserPolicy not implemented")
}
func (UnimplementedSeaweedS3Server) ListServiceAccounts(context.Context, *iam_pb.ListServiceAccountsRequest) (*iam_pb.ListServiceAccountsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListServiceAccounts not implemented")
}
func (UnimplementedSeaweedS3Server) CreateServiceAccount(context.Context, *iam_pb.CreateServiceAccountRequest) (*iam_pb.CreateServiceAccountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateServiceAccount not implemented")
}
func (UnimplementedSeaweedS3Server) UpdateServiceAccount(context.Context, *iam_pb.UpdateServiceAccountRequest) (*iam_pb.UpdateServiceAccountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UpdateServiceAccount not implemented")
}
func (UnimplementedSeaweedS3Server) DeleteServiceAccount(context.Context, *iam_pb.DeleteServiceAccountRequest) (*iam_pb.DeleteServiceAccountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteServiceAccount not implemented")
}
func (UnimplementedSeaweedS3Server) GetServiceAccount(context.Context, *iam_pb.GetServiceAccountRequest) (*iam_pb.GetServiceAccountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetServiceAccount not implemented")
}
func (UnimplementedSeaweedS3Server) mustEmbedUnimplementedSeaweedS3Server() {}
func (UnimplementedSeaweedS3Server) testEmbeddedByValue() {}
// UnsafeSeaweedS3IamCacheServer may be embedded to opt out of forward compatibility for this service. // UnsafeSeaweedS3Server may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to SeaweedS3IamCacheServer will // Use of this interface is not recommended, as added methods to SeaweedS3Server will
// result in compilation errors. // result in compilation errors.
type UnsafeSeaweedS3IamCacheServer interface { type UnsafeSeaweedS3Server interface {
mustEmbedUnimplementedSeaweedS3IamCacheServer() mustEmbedUnimplementedSeaweedS3Server()
} }
func RegisterSeaweedS3IamCacheServer(s grpc.ServiceRegistrar, srv SeaweedS3IamCacheServer) { func RegisterSeaweedS3Server(s grpc.ServiceRegistrar, srv SeaweedS3Server) {
// If the following call pancis, it indicates UnimplementedSeaweedS3IamCacheServer was // If the following call pancis, it indicates UnimplementedSeaweedS3Server was
// embedded by pointer and is nil. This will cause panics if an // embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization // unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O. // time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue() t.testEmbeddedByValue()
} }
s.RegisterService(&SeaweedS3IamCache_ServiceDesc, srv) s.RegisterService(&SeaweedS3_ServiceDesc, srv)
} }
func _SeaweedS3IamCache_PutIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_ListUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.PutIdentityRequest) in := new(iam_pb.ListUsersRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).PutIdentity(ctx, in) return srv.(SeaweedS3Server).ListUsers(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_PutIdentity_FullMethodName, FullMethod: SeaweedS3_ListUsers_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).PutIdentity(ctx, req.(*iam_pb.PutIdentityRequest)) return srv.(SeaweedS3Server).ListUsers(ctx, req.(*iam_pb.ListUsersRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SeaweedS3IamCache_RemoveIdentity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.RemoveIdentityRequest) in := new(iam_pb.CreateUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).RemoveIdentity(ctx, in) return srv.(SeaweedS3Server).CreateUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_RemoveIdentity_FullMethodName, FullMethod: SeaweedS3_CreateUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).RemoveIdentity(ctx, req.(*iam_pb.RemoveIdentityRequest)) return srv.(SeaweedS3Server).CreateUser(ctx, req.(*iam_pb.CreateUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SeaweedS3IamCache_PutPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.PutPolicyRequest) in := new(iam_pb.GetUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).PutPolicy(ctx, in) return srv.(SeaweedS3Server).GetUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_PutPolicy_FullMethodName, FullMethod: SeaweedS3_GetUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).PutPolicy(ctx, req.(*iam_pb.PutPolicyRequest)) return srv.(SeaweedS3Server).GetUser(ctx, req.(*iam_pb.GetUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SeaweedS3IamCache_GetPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.GetPolicyRequest) in := new(iam_pb.UpdateUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).GetPolicy(ctx, in) return srv.(SeaweedS3Server).UpdateUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_GetPolicy_FullMethodName, FullMethod: SeaweedS3_UpdateUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).GetPolicy(ctx, req.(*iam_pb.GetPolicyRequest)) return srv.(SeaweedS3Server).UpdateUser(ctx, req.(*iam_pb.UpdateUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SeaweedS3IamCache_ListPolicies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.ListPoliciesRequest) in := new(iam_pb.DeleteUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).ListPolicies(ctx, in) return srv.(SeaweedS3Server).DeleteUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_ListPolicies_FullMethodName, FullMethod: SeaweedS3_DeleteUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).ListPolicies(ctx, req.(*iam_pb.ListPoliciesRequest)) return srv.(SeaweedS3Server).DeleteUser(ctx, req.(*iam_pb.DeleteUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SeaweedS3IamCache_DeletePolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SeaweedS3_ListAccessKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.DeletePolicyRequest) in := new(iam_pb.ListAccessKeysRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(SeaweedS3IamCacheServer).DeletePolicy(ctx, in) return srv.(SeaweedS3Server).ListAccessKeys(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: SeaweedS3IamCache_DeletePolicy_FullMethodName, FullMethod: SeaweedS3_ListAccessKeys_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3IamCacheServer).DeletePolicy(ctx, req.(*iam_pb.DeletePolicyRequest)) return srv.(SeaweedS3Server).ListAccessKeys(ctx, req.(*iam_pb.ListAccessKeysRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
// SeaweedS3IamCache_ServiceDesc is the grpc.ServiceDesc for SeaweedS3IamCache service. func _SeaweedS3_CreateAccessKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.CreateAccessKeyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).CreateAccessKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_CreateAccessKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).CreateAccessKey(ctx, req.(*iam_pb.CreateAccessKeyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_DeleteAccessKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.DeleteAccessKeyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).DeleteAccessKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_DeleteAccessKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).DeleteAccessKey(ctx, req.(*iam_pb.DeleteAccessKeyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_PutUserPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.PutUserPolicyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).PutUserPolicy(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_PutUserPolicy_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).PutUserPolicy(ctx, req.(*iam_pb.PutUserPolicyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_GetUserPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.GetUserPolicyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).GetUserPolicy(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_GetUserPolicy_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).GetUserPolicy(ctx, req.(*iam_pb.GetUserPolicyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_DeleteUserPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.DeleteUserPolicyRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).DeleteUserPolicy(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_DeleteUserPolicy_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).DeleteUserPolicy(ctx, req.(*iam_pb.DeleteUserPolicyRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_ListServiceAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.ListServiceAccountsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).ListServiceAccounts(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_ListServiceAccounts_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).ListServiceAccounts(ctx, req.(*iam_pb.ListServiceAccountsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_CreateServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.CreateServiceAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).CreateServiceAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_CreateServiceAccount_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).CreateServiceAccount(ctx, req.(*iam_pb.CreateServiceAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_UpdateServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.UpdateServiceAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).UpdateServiceAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_UpdateServiceAccount_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).UpdateServiceAccount(ctx, req.(*iam_pb.UpdateServiceAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_DeleteServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.DeleteServiceAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).DeleteServiceAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_DeleteServiceAccount_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).DeleteServiceAccount(ctx, req.(*iam_pb.DeleteServiceAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
func _SeaweedS3_GetServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(iam_pb.GetServiceAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedS3Server).GetServiceAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SeaweedS3_GetServiceAccount_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedS3Server).GetServiceAccount(ctx, req.(*iam_pb.GetServiceAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
// SeaweedS3_ServiceDesc is the grpc.ServiceDesc for SeaweedS3 service.
// It's only intended for direct use with grpc.RegisterService, // It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy) // and not to be introspected or modified (even as a copy)
var SeaweedS3IamCache_ServiceDesc = grpc.ServiceDesc{ var SeaweedS3_ServiceDesc = grpc.ServiceDesc{
ServiceName: "messaging_pb.SeaweedS3IamCache", ServiceName: "messaging_pb.SeaweedS3",
HandlerType: (*SeaweedS3IamCacheServer)(nil), HandlerType: (*SeaweedS3Server)(nil),
Methods: []grpc.MethodDesc{ Methods: []grpc.MethodDesc{
{ {
MethodName: "PutIdentity", MethodName: "ListUsers",
Handler: _SeaweedS3IamCache_PutIdentity_Handler, Handler: _SeaweedS3_ListUsers_Handler,
}, },
{ {
MethodName: "RemoveIdentity", MethodName: "CreateUser",
Handler: _SeaweedS3IamCache_RemoveIdentity_Handler, Handler: _SeaweedS3_CreateUser_Handler,
}, },
{ {
MethodName: "PutPolicy", MethodName: "GetUser",
Handler: _SeaweedS3IamCache_PutPolicy_Handler, Handler: _SeaweedS3_GetUser_Handler,
}, },
{ {
MethodName: "GetPolicy", MethodName: "UpdateUser",
Handler: _SeaweedS3IamCache_GetPolicy_Handler, Handler: _SeaweedS3_UpdateUser_Handler,
}, },
{ {
MethodName: "ListPolicies", MethodName: "DeleteUser",
Handler: _SeaweedS3IamCache_ListPolicies_Handler, Handler: _SeaweedS3_DeleteUser_Handler,
}, },
{ {
MethodName: "DeletePolicy", MethodName: "ListAccessKeys",
Handler: _SeaweedS3IamCache_DeletePolicy_Handler, Handler: _SeaweedS3_ListAccessKeys_Handler,
},
{
MethodName: "CreateAccessKey",
Handler: _SeaweedS3_CreateAccessKey_Handler,
},
{
MethodName: "DeleteAccessKey",
Handler: _SeaweedS3_DeleteAccessKey_Handler,
},
{
MethodName: "PutUserPolicy",
Handler: _SeaweedS3_PutUserPolicy_Handler,
},
{
MethodName: "GetUserPolicy",
Handler: _SeaweedS3_GetUserPolicy_Handler,
},
{
MethodName: "DeleteUserPolicy",
Handler: _SeaweedS3_DeleteUserPolicy_Handler,
},
{
MethodName: "ListServiceAccounts",
Handler: _SeaweedS3_ListServiceAccounts_Handler,
},
{
MethodName: "CreateServiceAccount",
Handler: _SeaweedS3_CreateServiceAccount_Handler,
},
{
MethodName: "UpdateServiceAccount",
Handler: _SeaweedS3_UpdateServiceAccount_Handler,
},
{
MethodName: "DeleteServiceAccount",
Handler: _SeaweedS3_DeleteServiceAccount_Handler,
},
{
MethodName: "GetServiceAccount",
Handler: _SeaweedS3_GetServiceAccount_Handler,
}, },
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
File diff suppressed because it is too large Load Diff
-48
View File
@@ -13,9 +13,6 @@ import (
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
jsonpb "google.golang.org/protobuf/encoding/protojson" jsonpb "google.golang.org/protobuf/encoding/protojson"
_ "github.com/seaweedfs/seaweedfs/weed/credential/filer_etc"
_ "github.com/seaweedfs/seaweedfs/weed/credential/memory"
) )
func TestIdentityListFileFormat(t *testing.T) { func TestIdentityListFileFormat(t *testing.T) {
@@ -745,48 +742,3 @@ func TestSignatureVerificationDoesNotCheckPermissions(t *testing.T) {
t.Log("Signature verification no longer checks for Write permission") t.Log("Signature verification no longer checks for Write permission")
t.Log("This allows list-only and read-only users to authenticate via AWS Signature V4") t.Log("This allows list-only and read-only users to authenticate via AWS Signature V4")
} }
func TestStaticIdentityProtection(t *testing.T) {
iam := NewIdentityAccessManagement(&S3ApiServerOption{})
// Add a static identity
staticIdent := &Identity{
Name: "static-user",
IsStatic: true,
}
iam.m.Lock()
if iam.nameToIdentity == nil {
iam.nameToIdentity = make(map[string]*Identity)
}
iam.identities = append(iam.identities, staticIdent)
iam.nameToIdentity[staticIdent.Name] = staticIdent
iam.m.Unlock()
// Add a dynamic identity
dynamicIdent := &Identity{
Name: "dynamic-user",
IsStatic: false,
}
iam.m.Lock()
iam.identities = append(iam.identities, dynamicIdent)
iam.nameToIdentity[dynamicIdent.Name] = dynamicIdent
iam.m.Unlock()
// Try to remove static identity
iam.RemoveIdentity("static-user")
// Verify static identity still exists
iam.m.RLock()
_, ok := iam.nameToIdentity["static-user"]
iam.m.RUnlock()
assert.True(t, ok, "Static identity should not be removed")
// Try to remove dynamic identity
iam.RemoveIdentity("dynamic-user")
// Verify dynamic identity is removed
iam.m.RLock()
_, ok = iam.nameToIdentity["dynamic-user"]
iam.m.RUnlock()
assert.False(t, ok, "Dynamic identity should have been removed")
}
-10
View File
@@ -83,16 +83,6 @@ func (bpe *BucketPolicyEngine) HasPolicyForBucket(bucket string) bool {
return bpe.engine.HasPolicyForBucket(bucket) return bpe.engine.HasPolicyForBucket(bucket)
} }
// GetBucketPolicy gets the policy for a bucket
func (bpe *BucketPolicyEngine) GetBucketPolicy(bucket string) (*policy_engine.PolicyDocument, error) {
return bpe.engine.GetBucketPolicy(bucket)
}
// ListBucketPolicies returns all buckets that have policies
func (bpe *BucketPolicyEngine) ListBucketPolicies() []string {
return bpe.engine.GetAllBucketsWithPolicies()
}
// EvaluatePolicy evaluates whether an action is allowed by bucket policy // EvaluatePolicy evaluates whether an action is allowed by bucket policy
// //
// Parameters: // Parameters:
+6 -24
View File
@@ -38,15 +38,13 @@ type EmbeddedIamApi struct {
getS3ApiConfigurationFunc func(*iam_pb.S3ApiConfiguration) error getS3ApiConfigurationFunc func(*iam_pb.S3ApiConfiguration) error
putS3ApiConfigurationFunc func(*iam_pb.S3ApiConfiguration) error putS3ApiConfigurationFunc func(*iam_pb.S3ApiConfiguration) error
reloadConfigurationFunc func() error reloadConfigurationFunc func() error
readOnly bool
} }
// NewEmbeddedIamApi creates a new embedded IAM API handler. // NewEmbeddedIamApi creates a new embedded IAM API handler.
func NewEmbeddedIamApi(credentialManager *credential.CredentialManager, iam *IdentityAccessManagement, readOnly bool) *EmbeddedIamApi { func NewEmbeddedIamApi(credentialManager *credential.CredentialManager, iam *IdentityAccessManagement) *EmbeddedIamApi {
return &EmbeddedIamApi{ return &EmbeddedIamApi{
credentialManager: credentialManager, credentialManager: credentialManager,
iam: iam, iam: iam,
readOnly: readOnly,
} }
} }
@@ -162,8 +160,6 @@ func (e *EmbeddedIamApi) writeIamErrorResponse(w http.ResponseWriter, r *http.Re
s3err.WriteXMLResponse(w, r, http.StatusConflict, errorResp) s3err.WriteXMLResponse(w, r, http.StatusConflict, errorResp)
case iam.ErrCodeMalformedPolicyDocumentException, iam.ErrCodeInvalidInputException: case iam.ErrCodeMalformedPolicyDocumentException, iam.ErrCodeInvalidInputException:
s3err.WriteXMLResponse(w, r, http.StatusBadRequest, errorResp) s3err.WriteXMLResponse(w, r, http.StatusBadRequest, errorResp)
case "AccessDenied", iam.ErrCodeLimitExceededException:
s3err.WriteXMLResponse(w, r, http.StatusForbidden, errorResp)
case iam.ErrCodeServiceFailureException: case iam.ErrCodeServiceFailureException:
s3err.WriteXMLResponse(w, r, http.StatusInternalServerError, internalErrorResponse) s3err.WriteXMLResponse(w, r, http.StatusInternalServerError, internalErrorResponse)
default: default:
@@ -194,7 +190,6 @@ func (e *EmbeddedIamApi) PutS3ApiConfiguration(s3cfg *iam_pb.S3ApiConfiguration)
// ReloadConfiguration reloads the IAM configuration from the credential manager. // ReloadConfiguration reloads the IAM configuration from the credential manager.
func (e *EmbeddedIamApi) ReloadConfiguration() error { func (e *EmbeddedIamApi) ReloadConfiguration() error {
glog.V(4).Infof("IAM: reloading configuration via EmbeddedIamApi")
if e.reloadConfigurationFunc != nil { if e.reloadConfigurationFunc != nil {
return e.reloadConfigurationFunc() return e.reloadConfigurationFunc()
} }
@@ -1048,22 +1043,11 @@ func (e *EmbeddedIamApi) AuthIam(f http.HandlerFunc, _ Action) http.HandlerFunc
} }
// ExecuteAction executes an IAM action with the given values. // ExecuteAction executes an IAM action with the given values.
// If skipPersist is true, the changed configuration is not saved to the persistent store. func (e *EmbeddedIamApi) ExecuteAction(values url.Values) (interface{}, *iamError) {
func (e *EmbeddedIamApi) ExecuteAction(values url.Values, skipPersist bool) (interface{}, *iamError) {
// Lock to prevent concurrent read-modify-write race conditions // Lock to prevent concurrent read-modify-write race conditions
e.policyLock.Lock() e.policyLock.Lock()
defer e.policyLock.Unlock() defer e.policyLock.Unlock()
action := values.Get("Action")
if e.readOnly {
switch action {
case "ListUsers", "ListAccessKeys", "GetUser", "GetUserPolicy", "ListServiceAccounts", "GetServiceAccount":
// Allowed read-only actions
default:
return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrAccessDenied).Code, Error: fmt.Errorf("IAM write operations are disabled on this server")}
}
}
s3cfg := &iam_pb.S3ApiConfiguration{} s3cfg := &iam_pb.S3ApiConfiguration{}
if err := e.GetS3ApiConfiguration(s3cfg); err != nil && !errors.Is(err, filer_pb.ErrNotFound) { if err := e.GetS3ApiConfiguration(s3cfg); err != nil && !errors.Is(err, filer_pb.ErrNotFound) {
return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrInternalError).Code, Error: fmt.Errorf("failed to get s3 api configuration: %v", err)} return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrInternalError).Code, Error: fmt.Errorf("failed to get s3 api configuration: %v", err)}
@@ -1181,11 +1165,9 @@ func (e *EmbeddedIamApi) ExecuteAction(values url.Values, skipPersist bool) (int
return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrNotImplemented).Code, Error: errors.New(s3err.GetAPIError(s3err.ErrNotImplemented).Description)} return nil, &iamError{Code: s3err.GetAPIError(s3err.ErrNotImplemented).Code, Error: errors.New(s3err.GetAPIError(s3err.ErrNotImplemented).Description)}
} }
if changed { if changed {
if !skipPersist { if err := e.PutS3ApiConfiguration(s3cfg); err != nil {
if err := e.PutS3ApiConfiguration(s3cfg); err != nil { iamErr = &iamError{Code: iam.ErrCodeServiceFailureException, Error: err}
iamErr = &iamError{Code: iam.ErrCodeServiceFailureException, Error: err} return nil, iamErr
return nil, iamErr
}
} }
// Reload in-memory identity maps so subsequent LookupByAccessKey calls // Reload in-memory identity maps so subsequent LookupByAccessKey calls
// can see newly created or deleted keys immediately // can see newly created or deleted keys immediately
@@ -1214,7 +1196,7 @@ func (e *EmbeddedIamApi) DoActions(w http.ResponseWriter, r *http.Request) {
values.Set("CreatedBy", createdBy) values.Set("CreatedBy", createdBy)
} }
response, iamErr := e.ExecuteAction(values, false) response, iamErr := e.ExecuteAction(values)
if iamErr != nil { if iamErr != nil {
e.writeIamErrorResponse(w, r, iamErr) e.writeIamErrorResponse(w, r, iamErr)
return return
+2 -44
View File
@@ -87,19 +87,7 @@ func (e *EmbeddedIamApiForTest) DoActions(w http.ResponseWriter, r *http.Request
var iamErr *iamError var iamErr *iamError
changed := true changed := true
action := r.Form.Get("Action") switch r.Form.Get("Action") {
if e.readOnly {
switch action {
case "ListUsers", "ListAccessKeys", "GetUser", "GetUserPolicy", "ListServiceAccounts", "GetServiceAccount":
// Allowed read-only actions
default:
e.writeIamErrorResponse(w, r, &iamError{Code: s3err.GetAPIError(s3err.ErrAccessDenied).Code, Error: fmt.Errorf("IAM write operations are disabled on this server")})
return
}
}
switch action {
case "ListUsers": case "ListUsers":
response = e.ListUsers(s3cfg, values) response = e.ListUsers(s3cfg, values)
changed = false changed = false
@@ -1703,7 +1691,7 @@ func TestEmbeddedIamExecuteAction(t *testing.T) {
vals.Set("Action", "CreateUser") vals.Set("Action", "CreateUser")
vals.Set("UserName", "ExecuteActionUser") vals.Set("UserName", "ExecuteActionUser")
resp, iamErr := api.ExecuteAction(vals, false) resp, iamErr := api.ExecuteAction(vals)
assert.Nil(t, iamErr) assert.Nil(t, iamErr)
// Verify response type // Verify response type
@@ -1715,33 +1703,3 @@ func TestEmbeddedIamExecuteAction(t *testing.T) {
assert.Len(t, api.mockConfig.Identities, 1) assert.Len(t, api.mockConfig.Identities, 1)
assert.Equal(t, "ExecuteActionUser", api.mockConfig.Identities[0].Name) assert.Equal(t, "ExecuteActionUser", api.mockConfig.Identities[0].Name)
} }
// TestEmbeddedIamReadOnly tests that write operations are blocked when readOnly is true
func TestEmbeddedIamReadOnly(t *testing.T) {
api := NewEmbeddedIamApiForTest()
api.readOnly = true
// Try CreateUser (Write)
userName := aws.String("ReadOnlyUser")
params := &iam.CreateUserInput{UserName: userName}
req, _ := iam.New(session.New()).CreateUserRequest(params)
_ = req.Build()
response, err := executeEmbeddedIamRequest(api, req.HTTPRequest, nil)
assert.NoError(t, err)
assert.Equal(t, http.StatusForbidden, response.Code)
code, msg := extractEmbeddedIamErrorCodeAndMessage(response)
assert.Equal(t, "AccessDenied", code)
assert.Contains(t, msg, "IAM write operations are disabled")
// Try ListUsers (Read) - Should succeed
paramsList := &iam.ListUsersInput{}
reqList, _ := iam.New(session.New()).ListUsersRequest(paramsList)
_ = reqList.Build()
outList := iamListUsersResponse{}
responseList, err := executeEmbeddedIamRequest(api, reqList.HTTPRequest, &outList)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, responseList.Code)
}
+5 -16
View File
@@ -52,14 +52,11 @@ type S3ApiServerOption struct {
ConcurrentUploadLimit int64 ConcurrentUploadLimit int64
ConcurrentFileUploadLimit int64 ConcurrentFileUploadLimit int64
EnableIam bool // Enable embedded IAM API on the same port EnableIam bool // Enable embedded IAM API on the same port
IamReadOnly bool // Disable IAM write operations on this server
Cipher bool // encrypt data on volume servers Cipher bool // encrypt data on volume servers
BindIp string
GrpcPort int
} }
type S3ApiServer struct { type S3ApiServer struct {
s3_pb.UnimplementedSeaweedS3IamCacheServer s3_pb.UnimplementedSeaweedS3Server
option *S3ApiServerOption option *S3ApiServerOption
iam *IdentityAccessManagement iam *IdentityAccessManagement
iamIntegration *S3IAMIntegration // Advanced IAM integration for JWT authentication iamIntegration *S3IAMIntegration // Advanced IAM integration for JWT authentication
@@ -117,17 +114,13 @@ func NewS3ApiServerWithStore(router *mux.Router, option *S3ApiServerOption, expl
// Uses the battle-tested vidMap with filer-based lookups // Uses the battle-tested vidMap with filer-based lookups
// Supports multiple filer addresses with automatic failover for high availability // Supports multiple filer addresses with automatic failover for high availability
var filerClient *wdclient.FilerClient var filerClient *wdclient.FilerClient
if len(option.Masters) > 0 { if len(option.Masters) > 0 && option.FilerGroup != "" {
// Enable filer discovery via master // Enable filer discovery via master
masterMap := make(map[string]pb.ServerAddress) masterMap := make(map[string]pb.ServerAddress)
for i, addr := range option.Masters { for i, addr := range option.Masters {
masterMap[fmt.Sprintf("master%d", i)] = addr masterMap[fmt.Sprintf("master%d", i)] = addr
} }
clientHost := option.BindIp masterClient := wdclient.NewMasterClient(option.GrpcDialOption, option.FilerGroup, cluster.S3Type, "", "", "", *pb.NewServiceDiscoveryFromMap(masterMap))
if clientHost == "0.0.0.0" || clientHost == "" {
clientHost = util.DetectedHostAddress()
}
masterClient := wdclient.NewMasterClient(option.GrpcDialOption, option.FilerGroup, cluster.S3Type, pb.ServerAddress(util.JoinHostPort(clientHost, option.GrpcPort)), "", "", *pb.NewServiceDiscoveryFromMap(masterMap))
// Start the master client connection loop - required for GetMaster() to work // Start the master client connection loop - required for GetMaster() to work
go masterClient.KeepConnectedToMaster(context.Background()) go masterClient.KeepConnectedToMaster(context.Background())
@@ -210,12 +203,8 @@ func NewS3ApiServerWithStore(router *mux.Router, option *S3ApiServerOption, expl
// Initialize embedded IAM API if enabled // Initialize embedded IAM API if enabled
if option.EnableIam { if option.EnableIam {
s3ApiServer.embeddedIam = NewEmbeddedIamApi(s3ApiServer.credentialManager, iam, option.IamReadOnly) s3ApiServer.embeddedIam = NewEmbeddedIamApi(s3ApiServer.credentialManager, iam)
if option.IamReadOnly { glog.V(1).Infof("Embedded IAM API initialized (use -iam=false to disable)")
glog.V(1).Infof("Embedded IAM API initialized in read-only mode (use -s3.iam.readOnly=false to enable write operations)")
} else {
glog.V(1).Infof("Embedded IAM API initialized in writable mode (WARNING: updates will not be propagated to other S3 servers)")
}
} }
if option.Config != "" { if option.Config != "" {
+398 -7
View File
@@ -2,6 +2,8 @@ package s3api
import ( import (
"context" "context"
"fmt"
"net/url"
"github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
@@ -36,7 +38,92 @@ func (s3a *S3ApiServer) RemoveIdentity(ctx context.Context, req *iam_pb.RemoveId
return &iam_pb.RemoveIdentityResponse{}, nil return &iam_pb.RemoveIdentityResponse{}, nil
} }
func (s3a *S3ApiServer) executeAction(ctx context.Context, values url.Values) (interface{}, error) {
if s3a.embeddedIam == nil {
return nil, fmt.Errorf("embedded iam is disabled")
}
response, iamErr := s3a.embeddedIam.ExecuteAction(ctx, values)
if iamErr != nil {
return nil, fmt.Errorf("IAM error: %s - %v", iamErr.Code, iamErr.Error)
}
return response, nil
}
func (s3a *S3ApiServer) ListUsers(ctx context.Context, req *iam_pb.ListUsersRequest) (*iam_pb.ListUsersResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
values := url.Values{}
values.Set("Action", "ListUsers")
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamListUsersResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM ListUsers response type %T", resp)
}
var usernames []string
for _, user := range iamResp.ListUsersResult.Users {
if user != nil && user.UserName != nil {
usernames = append(usernames, *user.UserName)
}
}
return &iam_pb.ListUsersResponse{Usernames: usernames}, nil
}
func (s3a *S3ApiServer) CreateUser(ctx context.Context, req *iam_pb.CreateUserRequest) (*iam_pb.CreateUserResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Identity == nil || req.Identity.Name == "" {
return nil, fmt.Errorf("username name is required")
}
values := url.Values{}
values.Set("Action", "CreateUser")
values.Set("UserName", req.Identity.Name)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.CreateUserResponse{}, nil
}
func (s3a *S3ApiServer) GetUser(ctx context.Context, req *iam_pb.GetUserRequest) (*iam_pb.GetUserResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, status.Errorf(codes.InvalidArgument, "username is required")
}
values := url.Values{}
values.Set("Action", "GetUser")
values.Set("UserName", req.Username)
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamGetUserResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM GetUser response type %T", resp)
}
var username string
if iamResp.GetUserResult.User.UserName != nil {
username = *iamResp.GetUserResult.User.UserName
}
return &iam_pb.GetUserResponse{
Identity: &iam_pb.Identity{
Name: username,
},
}, nil
}
func (s3a *S3ApiServer) PutPolicy(ctx context.Context, req *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) { func (s3a *S3ApiServer) PutPolicy(ctx context.Context, req *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Name == "" { if req.Name == "" {
return nil, status.Errorf(codes.InvalidArgument, "policy name is required") return nil, status.Errorf(codes.InvalidArgument, "policy name is required")
} }
@@ -58,6 +145,9 @@ func (s3a *S3ApiServer) PutPolicy(ctx context.Context, req *iam_pb.PutPolicyRequ
} }
func (s3a *S3ApiServer) DeletePolicy(ctx context.Context, req *iam_pb.DeletePolicyRequest) (*iam_pb.DeletePolicyResponse, error) { func (s3a *S3ApiServer) DeletePolicy(ctx context.Context, req *iam_pb.DeletePolicyRequest) (*iam_pb.DeletePolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Name == "" { if req.Name == "" {
return nil, status.Errorf(codes.InvalidArgument, "policy name is required") return nil, status.Errorf(codes.InvalidArgument, "policy name is required")
} }
@@ -76,6 +166,9 @@ func (s3a *S3ApiServer) DeletePolicy(ctx context.Context, req *iam_pb.DeletePoli
} }
func (s3a *S3ApiServer) GetPolicy(ctx context.Context, req *iam_pb.GetPolicyRequest) (*iam_pb.GetPolicyResponse, error) { func (s3a *S3ApiServer) GetPolicy(ctx context.Context, req *iam_pb.GetPolicyRequest) (*iam_pb.GetPolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Name == "" { if req.Name == "" {
return nil, status.Errorf(codes.InvalidArgument, "policy name is required") return nil, status.Errorf(codes.InvalidArgument, "policy name is required")
} }
@@ -84,22 +177,320 @@ func (s3a *S3ApiServer) GetPolicy(ctx context.Context, req *iam_pb.GetPolicyRequ
} }
policy, err := s3a.iam.GetPolicy(req.Name) policy, err := s3a.iam.GetPolicy(req.Name)
if err != nil { if err != nil {
return &iam_pb.GetPolicyResponse{}, nil // Not found is fine for cache return nil, status.Errorf(codes.NotFound, "policy not found: %s", req.Name)
} }
return &iam_pb.GetPolicyResponse{ return &iam_pb.GetPolicyResponse{
Name: policy.Name, Policy: &iam_pb.Policy{
Content: policy.Content, Name: req.Name,
Content: policy,
},
}, nil }, nil
} }
func (s3a *S3ApiServer) ListPolicies(ctx context.Context, req *iam_pb.ListPoliciesRequest) (*iam_pb.ListPoliciesResponse, error) { func (s3a *S3ApiServer) ListPolicies(ctx context.Context, req *iam_pb.ListPoliciesRequest) (*iam_pb.ListPoliciesResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
resp := &iam_pb.ListPoliciesResponse{} resp := &iam_pb.ListPoliciesResponse{}
if s3a.iam == nil { if s3a.iam == nil {
return nil, status.Errorf(codes.Internal, "IAM not initialized") return nil, status.Errorf(codes.Internal, "IAM not initialized")
} }
policies := s3a.iam.ListPolicies() // TODO: Iterate over policies in map?
for _, policy := range policies {
resp.Policies = append(resp.Policies, policy)
}
return resp, nil return resp, nil
} }
func (s3a *S3ApiServer) UpdateUser(ctx context.Context, req *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
values := url.Values{}
values.Set("Action", "UpdateUser")
values.Set("UserName", req.Username)
// UpdateUser in DoActions expects "NewUserName" if renaming, but CreateUser just takes UserName.
// Looking at s3api_embedded_iam.go, UpdateUser uses "NewUserName" to change name.
if req.Identity != nil && req.Identity.Name != "" {
values.Set("NewUserName", req.Identity.Name)
}
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.UpdateUserResponse{}, nil
}
func (s3a *S3ApiServer) DeleteUser(ctx context.Context, req *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
values := url.Values{}
values.Set("Action", "DeleteUser")
values.Set("UserName", req.Username)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.DeleteUserResponse{}, nil
}
func (s3a *S3ApiServer) ListAccessKeys(ctx context.Context, req *iam_pb.ListAccessKeysRequest) (*iam_pb.ListAccessKeysResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
values := url.Values{}
values.Set("Action", "ListAccessKeys")
values.Set("UserName", req.Username)
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamListAccessKeysResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM ListAccessKeys response type %T", resp)
}
var accessKeys []*iam_pb.Credential
for _, meta := range iamResp.ListAccessKeysResult.AccessKeyMetadata {
if meta != nil && meta.AccessKeyId != nil && meta.Status != nil {
accessKeys = append(accessKeys, &iam_pb.Credential{
AccessKey: *meta.AccessKeyId,
Status: *meta.Status,
})
}
}
return &iam_pb.ListAccessKeysResponse{AccessKeys: accessKeys}, nil
}
func (s3a *S3ApiServer) CreateAccessKey(ctx context.Context, req *iam_pb.CreateAccessKeyRequest) (*iam_pb.CreateAccessKeyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
values := url.Values{}
values.Set("Action", "CreateAccessKey")
values.Set("UserName", req.Username)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.CreateAccessKeyResponse{}, nil
}
func (s3a *S3ApiServer) DeleteAccessKey(ctx context.Context, req *iam_pb.DeleteAccessKeyRequest) (*iam_pb.DeleteAccessKeyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
if req.AccessKey == "" {
return nil, fmt.Errorf("access key is required")
}
values := url.Values{}
values.Set("Action", "DeleteAccessKey")
values.Set("UserName", req.Username)
values.Set("AccessKeyId", req.AccessKey)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.DeleteAccessKeyResponse{}, nil
}
func (s3a *S3ApiServer) PutUserPolicy(ctx context.Context, req *iam_pb.PutUserPolicyRequest) (*iam_pb.PutUserPolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
if req.PolicyName == "" {
return nil, fmt.Errorf("policy name is required")
}
values := url.Values{}
values.Set("Action", "PutUserPolicy")
values.Set("UserName", req.Username)
values.Set("PolicyName", req.PolicyName)
values.Set("PolicyDocument", req.PolicyDocument)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.PutUserPolicyResponse{}, nil
}
func (s3a *S3ApiServer) GetUserPolicy(ctx context.Context, req *iam_pb.GetUserPolicyRequest) (*iam_pb.GetUserPolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
if req.PolicyName == "" {
return nil, fmt.Errorf("policy name is required")
}
values := url.Values{}
values.Set("Action", "GetUserPolicy")
values.Set("UserName", req.Username)
values.Set("PolicyName", req.PolicyName)
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamGetUserPolicyResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM GetUserPolicy response type %T", resp)
}
return &iam_pb.GetUserPolicyResponse{
Username: iamResp.GetUserPolicyResult.UserName,
PolicyName: iamResp.GetUserPolicyResult.PolicyName,
PolicyDocument: iamResp.GetUserPolicyResult.PolicyDocument,
}, nil
}
func (s3a *S3ApiServer) DeleteUserPolicy(ctx context.Context, req *iam_pb.DeleteUserPolicyRequest) (*iam_pb.DeleteUserPolicyResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Username == "" {
return nil, fmt.Errorf("username is required")
}
if req.PolicyName == "" {
return nil, fmt.Errorf("policy name is required")
}
values := url.Values{}
values.Set("Action", "DeleteUserPolicy")
values.Set("UserName", req.Username)
values.Set("PolicyName", req.PolicyName)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.DeleteUserPolicyResponse{}, nil
}
func (s3a *S3ApiServer) ListServiceAccounts(ctx context.Context, req *iam_pb.ListServiceAccountsRequest) (*iam_pb.ListServiceAccountsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
values := url.Values{}
values.Set("Action", "ListServiceAccounts")
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamListServiceAccountsResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM ListServiceAccounts response type %T", resp)
}
var serviceAccounts []*iam_pb.ServiceAccount
for _, sa := range iamResp.ListServiceAccountsResult.ServiceAccounts {
if sa != nil {
serviceAccounts = append(serviceAccounts, &iam_pb.ServiceAccount{
Id: sa.ServiceAccountId,
ParentUser: sa.ParentUser,
Description: sa.Description,
Credential: &iam_pb.Credential{
AccessKey: sa.AccessKeyId,
Status: sa.Status,
},
})
}
}
return &iam_pb.ListServiceAccountsResponse{ServiceAccounts: serviceAccounts}, nil
}
func (s3a *S3ApiServer) CreateServiceAccount(ctx context.Context, req *iam_pb.CreateServiceAccountRequest) (*iam_pb.CreateServiceAccountResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.ServiceAccount == nil || req.ServiceAccount.CreatedBy == "" {
return nil, fmt.Errorf("service account owner is required")
}
values := url.Values{}
values.Set("Action", "CreateServiceAccount")
values.Set("CreatedBy", req.ServiceAccount.CreatedBy)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.CreateServiceAccountResponse{}, nil
}
func (s3a *S3ApiServer) UpdateServiceAccount(ctx context.Context, req *iam_pb.UpdateServiceAccountRequest) (*iam_pb.UpdateServiceAccountResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Id == "" {
return nil, fmt.Errorf("service account id is required")
}
values := url.Values{}
values.Set("Action", "UpdateServiceAccount")
values.Set("ServiceAccountId", req.Id)
if req.ServiceAccount != nil && req.ServiceAccount.Disabled {
values.Set("Status", "Inactive")
}
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.UpdateServiceAccountResponse{}, nil
}
func (s3a *S3ApiServer) DeleteServiceAccount(ctx context.Context, req *iam_pb.DeleteServiceAccountRequest) (*iam_pb.DeleteServiceAccountResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Id == "" {
return nil, fmt.Errorf("service account id is required")
}
values := url.Values{}
values.Set("Action", "DeleteServiceAccount")
values.Set("ServiceAccountId", req.Id)
_, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
return &iam_pb.DeleteServiceAccountResponse{}, nil
}
func (s3a *S3ApiServer) GetServiceAccount(ctx context.Context, req *iam_pb.GetServiceAccountRequest) (*iam_pb.GetServiceAccountResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "request is nil")
}
if req.Id == "" {
return nil, fmt.Errorf("service account id is required")
}
values := url.Values{}
values.Set("Action", "GetServiceAccount")
values.Set("ServiceAccountId", req.Id)
resp, err := s3a.executeAction(ctx, values)
if err != nil {
return nil, err
}
iamResp, ok := resp.(iamGetServiceAccountResponse)
if !ok {
return nil, fmt.Errorf("unexpected IAM GetServiceAccount response type %T", resp)
}
return &iam_pb.GetServiceAccountResponse{
ServiceAccount: &iam_pb.ServiceAccount{
Id: iamResp.GetServiceAccountResult.ServiceAccount.ServiceAccountId,
ParentUser: iamResp.GetServiceAccountResult.ServiceAccount.ParentUser,
Description: iamResp.GetServiceAccountResult.ServiceAccount.Description,
Credential: &iam_pb.Credential{
AccessKey: iamResp.GetServiceAccountResult.ServiceAccount.AccessKeyId,
Status: iamResp.GetServiceAccountResult.ServiceAccount.Status,
},
},
}, nil
}
+1 -1
View File
@@ -31,7 +31,7 @@ func setupRoutingTestServer(t *testing.T) *S3ApiServer {
option: opt, option: opt,
iam: iam, iam: iam,
credentialManager: iam.credentialManager, credentialManager: iam.credentialManager,
embeddedIam: NewEmbeddedIamApi(iam.credentialManager, iam, false), embeddedIam: NewEmbeddedIamApi(iam.credentialManager, iam),
stsHandlers: &STSHandlers{}, stsHandlers: &STSHandlers{},
} }
-4
View File
@@ -256,10 +256,6 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption)
fs.filer.Dlm.LockRing.SetTakeSnapshotCallback(fs.OnDlmChangeSnapshot) fs.filer.Dlm.LockRing.SetTakeSnapshotCallback(fs.OnDlmChangeSnapshot)
if fs.CredentialManager != nil {
fs.CredentialManager.SetMasterClient(fs.filer.MasterClient, fs.grpcDialOption)
}
return fs, nil return fs, nil
} }
@@ -73,7 +73,7 @@ func (s *IamGrpcServer) CreateUser(ctx context.Context, req *iam_pb.CreateUserRe
if req == nil || req.Identity == nil { if req == nil || req.Identity == nil {
return nil, status.Errorf(codes.InvalidArgument, "identity is required") return nil, status.Errorf(codes.InvalidArgument, "identity is required")
} }
glog.V(4).Infof("IAM: Filer.CreateUser %s", req.Identity.Name) glog.V(4).Infof("CreateUser: %s", req.Identity.Name)
if s.credentialManager == nil { if s.credentialManager == nil {
return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured") return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured")
@@ -113,10 +113,10 @@ func (s *IamGrpcServer) GetUser(ctx context.Context, req *iam_pb.GetUserRequest)
} }
func (s *IamGrpcServer) UpdateUser(ctx context.Context, req *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error) { func (s *IamGrpcServer) UpdateUser(ctx context.Context, req *iam_pb.UpdateUserRequest) (*iam_pb.UpdateUserResponse, error) {
glog.V(4).Infof("UpdateUser: %s", req.Username)
if req == nil || req.Identity == nil { if req == nil || req.Identity == nil {
return nil, status.Errorf(codes.InvalidArgument, "identity is required") return nil, status.Errorf(codes.InvalidArgument, "identity is required")
} }
glog.V(4).Infof("IAM: Filer.UpdateUser %s", req.Username)
if s.credentialManager == nil { if s.credentialManager == nil {
return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured") return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured")
@@ -135,7 +135,7 @@ func (s *IamGrpcServer) UpdateUser(ctx context.Context, req *iam_pb.UpdateUserRe
} }
func (s *IamGrpcServer) DeleteUser(ctx context.Context, req *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error) { func (s *IamGrpcServer) DeleteUser(ctx context.Context, req *iam_pb.DeleteUserRequest) (*iam_pb.DeleteUserResponse, error) {
glog.V(4).Infof("IAM: Filer.DeleteUser %s", req.Username) glog.V(4).Infof("DeleteUser: %s", req.Username)
if s.credentialManager == nil { if s.credentialManager == nil {
return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured") return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured")
@@ -243,7 +243,7 @@ func (s *IamGrpcServer) GetUserByAccessKey(ctx context.Context, req *iam_pb.GetU
// Policy Management // Policy Management
func (s *IamGrpcServer) PutPolicy(ctx context.Context, req *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) { func (s *IamGrpcServer) PutPolicy(ctx context.Context, req *iam_pb.PutPolicyRequest) (*iam_pb.PutPolicyResponse, error) {
glog.V(4).Infof("IAM: Filer.PutPolicy %s", req.Name) glog.V(4).Infof("PutPolicy: %s", req.Name)
if s.credentialManager == nil { if s.credentialManager == nil {
return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured") return nil, status.Errorf(codes.FailedPrecondition, "credential manager is not configured")
-1
View File
@@ -276,7 +276,6 @@ func (ms *MasterServer) KeepConnected(stream master_pb.Seaweed_KeepConnectedServ
clientName, messageChan := ms.addClient(req.FilerGroup, req.ClientType, peerAddress) clientName, messageChan := ms.addClient(req.FilerGroup, req.ClientType, peerAddress)
for _, update := range ms.Cluster.AddClusterNode(req.FilerGroup, req.ClientType, cluster.DataCenter(req.DataCenter), cluster.Rack(req.Rack), peerAddress, req.Version) { for _, update := range ms.Cluster.AddClusterNode(req.FilerGroup, req.ClientType, cluster.DataCenter(req.DataCenter), cluster.Rack(req.Rack), peerAddress, req.Version) {
glog.V(1).Infof("Cluster: %s node %s added to group '%s'", req.ClientType, peerAddress, req.FilerGroup)
ms.broadcastToClients(update) ms.broadcastToClients(update)
} }