Skip to content
This repository has been archived by the owner on Mar 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #13 from magneticio/feature/LAM-130-grant-and-revo…
Browse files Browse the repository at this point in the history
…ke-permissions

Implemented grant and revoke for permissions. Also added sample yamls
  • Loading branch information
avalcepina authored Apr 18, 2019
2 parents 383aa12 + 5ecefd0 commit 187583c
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 26 deletions.
85 changes: 64 additions & 21 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,26 +204,13 @@ func getUrlForResource(base string, version string, resourceName string, subComm
if name != "" {
namedParameter = "&" + resourceName + "_name=" + name
}
applicationParameter := ""
application := values["application"]
if application != "" {
applicationParameter = "&" + "application_name=" + application
}

project := values["project"]
projectParameter := ""
if project != "" {
projectParameter = "&" + "project_name=" + project
}

cluster := values["cluster"]
clusterParameter := ""
if cluster != "" {
clusterParameter = "&" + "cluster_name=" + cluster
}

virtualCluster := values["virtual_cluster"]
virtualClusterParameter := ""
if virtualCluster != "" {
virtualClusterParameter = "&" + "virtual_cluster_name=" + virtualCluster
}

switch resourceName {
case "project":
return base + "/api/" + version + "/" + "projects" + subPath + "?time=-1" + namedParameter, nil
Expand All @@ -246,13 +233,16 @@ func getUrlForResource(base string, version string, resourceName string, subComm
namedParameter
return url, nil
}
var queryParams = ""

for key, value := range values {
queryParams = queryParams + "&" + key + "_name=" + value
}

timestamp := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
url := base + "/api/" + version + "/" + strings.Replace(resourceName, "_", "-", -1) + "s" + subPath +
"?" + "t=" + timestamp +
projectParameter +
clusterParameter +
virtualClusterParameter +
applicationParameter +
queryParams +
namedParameter
return url, nil
}
Expand Down Expand Up @@ -436,6 +426,59 @@ func (s *restClient) List(resourceName string, outputFormat string, values map[s

}

func (s *restClient) UpdateUserPermission(username string, permission string, values map[string]string) (bool, error) {
url, _ := getUrlForResource((*s).url, (*s).version, "user-access-permission", "", "", values)
url += "&user_name=" + username

permissionBody := models.Permission{
Read: strings.Contains(permission, "r"),
Write: strings.Contains(permission, "w"),
Delete: strings.Contains(permission, "d"),
EditAccess: strings.Contains(permission, "a"),
}

resp, err := resty.R().
SetHeader("Content-Type", "application/json").
SetHeader("Accept", "application/json").
SetAuthToken((*s).token).
SetBody(permissionBody).
SetResult(&successResponse{}).
SetError(&errorResponse{}).
Post(url)

if err != nil {
return false, err
}

if resp.IsError() {
return false, getError(resp)
}
return true, nil

}

func (s *restClient) RemovePermissionFromUser(username string, values map[string]string) (bool, error) {
url, _ := getUrlForResource((*s).url, (*s).version, "user-access-permission", "", "", values)
url += "&user_name=" + username
resp, err := resty.R().
SetHeader("Content-Type", "application/json").
SetHeader("Accept", "application/json").
SetAuthToken((*s).token).
SetResult(&authSuccess{}).
SetError(&errorResponse{}).
Delete(url)

if err != nil {
return false, err
}

if resp.IsError() {
return false, getError(resp)
}
return true, nil

}

func (s *restClient) AddRoleToUser(username string, rolename string, values map[string]string) (bool, error) {
url, _ := getUrlForResource((*s).url, (*s).version, "user-access-role", "", "", values)
url += "&user_name=" + username + "&role_name=" + rolename
Expand Down
51 changes: 48 additions & 3 deletions cmd/grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,32 @@
package cmd

import (
"errors"
"regexp"
"strings"

"github.com/magneticio/forklift/logging"
"github.com/magneticio/vampkubistcli/client"
"github.com/spf13/cobra"
)

var Role string
var Permission string
var Kind string

// grantCmd represents the grant command
var grantCmd = &cobra.Command{
Use: "grant",
Short: "Grant a role or permission to a user for an object",
Long: AddAppName(`Usage:
$AppName grant --user user1 --role admin -p default`),
$AppName grant --user user1 --role admin -p default
$AppName grant --user user1 --permission rwda -p project -c cluster -r virtualcluster -a application --kind deployment --name deploymentname
Permissions follow the format:
r = read
w = write
d = delete
a = edit access to resource for other users
`),
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -36,13 +49,43 @@ $AppName grant --user user1 --role admin -p default`),
values["project"] = Project
values["cluster"] = Cluster
values["virtual_cluster"] = VirtualCluster
values["application"] = Application
values[Kind] = Name
// values["application"] = Application
if Role != "" {
isSet, err_set := restClient.AddRoleToUser(Username, Role, values)
if !isSet {
return err_set
}
} else if Permission != "" {

lowkPermission := strings.ToLower(Permission)

// Regex matches all permutations of lowercase rwda with max length 4 and only once character per type
reg := "^[rwda]{1,4}$"

match, regexErr := regexp.MatchString(reg, lowkPermission)
if regexErr != nil {
return regexErr
}
validity := match &&
strings.Count(lowkPermission, "r") <= 1 &&
strings.Count(lowkPermission, "w") <= 1 &&
strings.Count(lowkPermission, "d") <= 1 &&
strings.Count(lowkPermission, "a") <= 1

if !validity {
return errors.New("Permission format is invalid")
}

isSet, err_set := restClient.UpdateUserPermission(Username, lowkPermission, values)
if !isSet {
return err_set
}
} else {
return errors.New("Resource to be granted is missing. Specify either permission or role.")
}

return nil
},
}
Expand All @@ -61,6 +104,8 @@ func init() {
// grantCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
grantCmd.Flags().StringVarP(&Username, "user", "", "", "Username required")
grantCmd.MarkFlagRequired("user")
grantCmd.Flags().StringVarP(&Role, "role", "", "", "Role required")
grantCmd.MarkFlagRequired("role")
grantCmd.Flags().StringVarP(&Kind, "kind", "k", "", "")
grantCmd.Flags().StringVarP(&Name, "name", "n", "", "")
grantCmd.Flags().StringVarP(&Permission, "permission", "", "", "")
grantCmd.Flags().StringVarP(&Role, "role", "", "", "")
}
16 changes: 14 additions & 2 deletions cmd/revoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package cmd

import (
"errors"

"github.com/magneticio/forklift/logging"
"github.com/magneticio/vampkubistcli/client"
"github.com/spf13/cobra"
Expand All @@ -25,7 +27,8 @@ var revokeCmd = &cobra.Command{
Use: "revoke",
Short: "Revoke a role or permission of a user for an object",
Long: AddAppName(`Usage:
$AppName revoke --user user1 --role admin -p default`),
$AppName revoke --user user1 --role admin -p default
$AppName vamp revoke permission --user user1 -p project -c cluster -r virtualcluster -a application --kind deployment --name deploymentname`),
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -40,7 +43,15 @@ $AppName revoke --user user1 --role admin -p default`),
if !isSet {
return err_set
}
} else if len(args) > 0 && args[0] == "permission" {
isSet, err_set := restClient.RemovePermissionFromUser(Username, values)
if !isSet {
return err_set
}
} else {
return errors.New("Resource to be revoked is missing. Specify either permission or role.")
}

return nil
},
}
Expand All @@ -59,6 +70,7 @@ func init() {
// revokeCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
revokeCmd.Flags().StringVarP(&Username, "user", "", "", "Username required")
revokeCmd.MarkFlagRequired("user")
revokeCmd.Flags().StringVarP(&Role, "role", "", "", "Role required")
revokeCmd.Flags().StringVarP(&Kind, "kind", "k", "", "")
revokeCmd.Flags().StringVarP(&Name, "name", "n", "", "")
revokeCmd.MarkFlagRequired("role")
}
7 changes: 7 additions & 0 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ type Metadata struct {
Metadata map[string]string `json:"metadata"`
}

type Permission struct {
Read bool `json:"read"`
Write bool `json:"write"`
Delete bool `json:"delete"`
EditAccess bool `json:"editAccess"`
}

type VampService struct {
Gateways []string `json:"gateways"`
Hosts []string `json:"hosts"`
Expand Down
6 changes: 6 additions & 0 deletions resources/samples/canary.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vampService: vamp-service-1
destination: dest-1
port: 9090
subset: subset3
updatePeriod: 30000
updateStep: 10
16 changes: 16 additions & 0 deletions resources/samples/destination.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
application: app1
ports:
- name: http
port: 9090
targetPort: 9090
protocol: TCP
subsets:
subset1:
labels:
deployment: deployment1
subset2:
labels:
deployment: deployment2
subset3:
labels:
deployment: deployment3
5 changes: 5 additions & 0 deletions resources/samples/destinationrule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
service: svc2
subsets:
- name: subset1
labels:
deployment: deployment1
16 changes: 16 additions & 0 deletions resources/samples/experiment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
vampServiceName: vamp-service-1
period: 1
step: 10
destinations:
- destination: dest-1
tags:
- test1
port: 9090
subset: subset1
target: /endpoint1
- destination: dest-2
tags:
- test1
port: 9090
subset: subset1
target: /endpoint1
5 changes: 5 additions & 0 deletions resources/samples/gateway.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
servers:
- port: 80
protocol: http
hosts:
- vamp-gw1.democluster.net
4 changes: 4 additions & 0 deletions resources/samples/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
paths:
- path: /
port: 80
serviceName: svc2
2 changes: 2 additions & 0 deletions resources/samples/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
policyExecutor:
name: DefaultProjectPolicyExecutor
7 changes: 7 additions & 0 deletions resources/samples/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ports:
- name: http
port: 9090
targetPort: 9090
protocol: TCP
selectors:
deploymnet: deployment1
2 changes: 2 additions & 0 deletions resources/samples/user.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
userName: user1
password: pass12
16 changes: 16 additions & 0 deletions resources/samples/vampservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
gateways:
- gw-1
hosts:
- vamp-gw1.democluster.net
routes:
- protocol: http
weights:
- destination: dest-1
port: 9090
version: subset1
weight: 50
- destination: dest-1
port: 9090
version: subset2
weight: 50
exposeInternally: true
15 changes: 15 additions & 0 deletions resources/samples/virtualservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
gateways:
- gw-1
hosts:
- vamp-gw1.democluster.net
routes:
- protocol: http
weights:
- destination: svc2
port: 9090
version: subset1
weight: 50
- destination: svc2
port: 9090
version: subset2
weight: 50

0 comments on commit 187583c

Please sign in to comment.