Resources segregation by tenant #20
|
@ -0,0 +1,56 @@
|
|||
package tenant
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/command/client/apierr"
|
||||
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/client/flag"
|
||||
tenantFlag "forge.cadoles.com/Cadoles/emissary/internal/command/client/tenant/flag"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
|
||||
"forge.cadoles.com/Cadoles/emissary/pkg/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli/v2"
|
||||
"gitlab.com/wpetit/goweb/cli/format"
|
||||
)
|
||||
|
||||
func DeleteCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete tenant",
|
||||
Flags: tenantFlag.WithTenantFlags(),
|
||||
Action: func(ctx *cli.Context) error {
|
||||
baseFlags := clientFlag.GetBaseFlags(ctx)
|
||||
|
||||
token, err := clientFlag.GetToken(baseFlags)
|
||||
if err != nil {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
tenantID, err := tenantFlag.AssertTenantID(ctx)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
client := client.New(baseFlags.ServerURL, client.WithToken(token))
|
||||
|
||||
tenantID, err = client.DeleteTenant(ctx.Context, tenantID)
|
||||
if err != nil {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
hints := format.Hints{
|
||||
OutputMode: baseFlags.OutputMode,
|
||||
}
|
||||
|
||||
if err := format.Write(baseFlags.Format, os.Stdout, hints, struct {
|
||||
ID datastore.TenantID `json:"id"`
|
||||
}{
|
||||
ID: tenantID,
|
||||
}); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ func Root() *cli.Command {
|
|||
CreateCommand(),
|
||||
GetCommand(),
|
||||
UpdateCommand(),
|
||||
DeleteCommand(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,8 +230,8 @@ func (r *AgentRepository) UpdateSpec(ctx context.Context, agentID datastore.Agen
|
|||
now := time.Now().UTC()
|
||||
|
||||
query := `
|
||||
INSERT INTO specs (agent_id, name, revision, data, created_at, updated_at)
|
||||
VALUES($1, $2, $3, $4, $5, $5)
|
||||
INSERT INTO specs (agent_id, name, revision, data, created_at, updated_at, tenant_id)
|
||||
VALUES($1, $2, $3, $4, $5, $5, ( SELECT tenant_id FROM agents WHERE id = $1 ))
|
||||
ON CONFLICT (agent_id, name) DO UPDATE SET
|
||||
data = $4, updated_at = $5, revision = specs.revision + 1
|
||||
WHERE revision = $3
|
||||
|
|
|
@ -63,7 +63,7 @@ func assertAdminOrTenantReadAccess(h http.Handler) http.Handler {
|
|||
assertOneOfRoles(user.RoleAdmin),
|
||||
assertAllOfUser(
|
||||
assertOneOfRoles(user.RoleReader, user.RoleWriter),
|
||||
assertTenant(),
|
||||
assertSameTenant(),
|
||||
),
|
||||
),
|
||||
nil,
|
||||
|
@ -77,7 +77,7 @@ func assertAdminOrTenantWriteAccess(h http.Handler) http.Handler {
|
|||
assertOneOfRoles(user.RoleAdmin),
|
||||
assertAllOfUser(
|
||||
assertOneOfRoles(user.RoleWriter),
|
||||
assertTenant(),
|
||||
assertSameTenant(),
|
||||
),
|
||||
),
|
||||
nil,
|
||||
|
@ -147,7 +147,7 @@ func assertOneOfUser(funcs ...assertUser) assertUser {
|
|||
}
|
||||
}
|
||||
|
||||
func assertTenant() assertUser {
|
||||
func assertSameTenant() assertUser {
|
||||
return func(w http.ResponseWriter, r *http.Request, u *user.User) bool {
|
||||
tenantID, ok := getTenantID(w, r)
|
||||
if !ok {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (c *Client) DeleteTenant(ctx context.Context, tenantID TenantID, funcs ...OptionFunc) (TenantID, error) {
|
||||
response := withResponse[struct {
|
||||
TenantID string `json:"tenantId"`
|
||||
}]()
|
||||
|
||||
path := fmt.Sprintf("/api/v1/tenants/%s", tenantID)
|
||||
|
||||
if err := c.apiDelete(ctx, path, nil, &response, funcs...); err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
if response.Error != nil {
|
||||
return "", errors.WithStack(response.Error)
|
||||
}
|
||||
|
||||
return TenantID(response.Data.TenantID), nil
|
||||
}
|
Loading…
Reference in New Issue