github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/identity/v3/policies/requests.go (about)

     1  package policies
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	golangsdk "github.com/opentelekomcloud/gophertelekomcloud"
     8  )
     9  
    10  var RequestOpts = golangsdk.RequestOpts{
    11  	MoreHeaders: map[string]string{"Content-Type": "application/json;charset=utf8"},
    12  }
    13  
    14  // ListOpts Page&PerPage options currently don't have any effect
    15  type ListOpts struct {
    16  	DisplayName string
    17  	Type        string
    18  	ID          string
    19  	Page        int `q:"page"`
    20  	PerPage     int `q:"per_page"`
    21  }
    22  
    23  func (opts ListOpts) ToPolicyListQuery() (string, error) {
    24  	q, err := golangsdk.BuildQueryString(opts)
    25  	if err != nil {
    26  		return "", err
    27  	}
    28  	return q.String(), err
    29  }
    30  
    31  func List(client *golangsdk.ServiceClient, opts ListOpts) (ListPolicy, error) {
    32  	var r ListResult
    33  	_, r.Err = client.Get(listURL(client), &r.Body, &golangsdk.RequestOpts{
    34  		OkCodes:     []int{200},
    35  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
    36  	})
    37  
    38  	allPolicies, err := r.ExtractPolicies()
    39  	if err != nil {
    40  		return allPolicies, err
    41  	}
    42  
    43  	return FilterRoles(allPolicies, opts)
    44  }
    45  
    46  func FilterRoles(roles ListPolicy, opts ListOpts) (ListPolicy, error) {
    47  	refinedListPolicy := ListPolicy{
    48  		Links: roles.Links,
    49  	}
    50  	var matched bool
    51  	m := map[string]interface{}{}
    52  
    53  	if opts.DisplayName != "" {
    54  		m["DisplayName"] = opts.DisplayName
    55  	}
    56  
    57  	if opts.Type != "" {
    58  		m["Type"] = opts.Type
    59  	}
    60  
    61  	if opts.Type != "" {
    62  		m["ID"] = opts.ID
    63  	}
    64  
    65  	if len(m) > 0 && len(roles.Roles) > 0 {
    66  
    67  		for _, role := range roles.Roles {
    68  			matched = true
    69  
    70  			for key, value := range m {
    71  				if sVal := getStructField(&role, key); !(sVal == value) {
    72  					matched = false
    73  				}
    74  			}
    75  
    76  			if matched {
    77  				refinedListPolicy.Roles = append(refinedListPolicy.Roles, role)
    78  			}
    79  		}
    80  	} else {
    81  		refinedListPolicy.Roles = roles.Roles
    82  	}
    83  
    84  	refinedListPolicy.TotalNumber = len(refinedListPolicy.Roles)
    85  
    86  	return refinedListPolicy, nil
    87  
    88  }
    89  
    90  func getStructField(v *Policy, field string) string {
    91  	r := reflect.ValueOf(v)
    92  	f := reflect.Indirect(r).FieldByName(field)
    93  	return f.String()
    94  }
    95  
    96  func Get(client *golangsdk.ServiceClient, id string) (r GetResult) {
    97  	_, r.Err = client.Get(getURL(client, id), &r.Body, &golangsdk.RequestOpts{
    98  		OkCodes:     []int{200},
    99  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   100  	})
   101  	return
   102  }
   103  
   104  type CreateOpts struct {
   105  	// Display name of the custom policy
   106  	DisplayName string `json:"display_name" required:"true"`
   107  	// Display mode which can only be AX or XA
   108  	// AX: Account level.
   109  	// XA: Project level.
   110  	Type string `json:"type" required:"true"`
   111  	// Description of the custom policy
   112  	Description string `json:"description" required:"true"`
   113  	// DescriptionCn string `json:"description_cn"`
   114  	// Content of custom policy.
   115  	Policy CreatePolicy `json:"policy" required:"true"`
   116  }
   117  
   118  type CreatePolicy struct {
   119  	// Policy version. When creating a custom policy, set this parameter to 1.1
   120  	Version string `json:"Version" required:"true"`
   121  	// Statement of the policy
   122  	// A policy can contain a maximum of eight statements.
   123  	Statement []CreateStatement `json:"Statement" required:"true"`
   124  }
   125  
   126  type CreateStatement struct {
   127  	// Specific operation permission on a resource. A maximum of 100 actions are allowed.
   128  	// The value format is `Service name:Resource type:Operation`, for example, `vpc:ports:create`
   129  	// `Service name`: indicates the product name, such as ecs, evs, or vpc. Only lowercase letters are allowed.
   130  	// Resource types and operations are not case-sensitive. You can use an asterisk (*) to represent all operations.
   131  	Action []string `json:"Action" required:"true"`
   132  	// Effect of the permission. The value can be `Allow` or `Deny`.
   133  	// If both `Allow` and `Deny` statements are found in a policy,
   134  	// the authentication starts from the `Deny` statements.
   135  	Effect string `json:"Effect" required:"true"`
   136  	// Conditions for the permission to take effect. A maximum of 10 conditions are allowed.
   137  	// Conditions can't be used if `Resource` is selected using delegating agencies.
   138  	Condition Condition `json:"Condition,omitempty"`
   139  	// Cloud resource. The array can contain a maximum of 10 resource strings - []string,
   140  	// and each string cannot exceed 128 characters.
   141  	// Format: ::::. For example, `obs:::bucket:*`. Asterisks are allowed.
   142  	// In the case of a custom policy for agencies, the type of this parameter is map[string][]string
   143  	// and the value should be set to
   144  	// "Resource": {"uri": ["/iam/agencies/07805acaba800fdd4fbdc00b8f888c7c"]}.
   145  	Resource interface{} `json:"Resource,omitempty"`
   146  }
   147  
   148  type Condition map[string]map[string][]string
   149  
   150  func (opts CreateOpts) ToPolicyCreateMap() (map[string]interface{}, error) {
   151  	b, err := golangsdk.BuildRequestBody(opts, "role")
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  	return b, nil
   156  }
   157  
   158  type CreateOptsBuilder interface {
   159  	ToPolicyCreateMap() (map[string]interface{}, error)
   160  }
   161  
   162  func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   163  	reqBody, err := opts.ToPolicyCreateMap()
   164  	if err != nil {
   165  		r.Err = fmt.Errorf("failed to create policy create map: %s", err)
   166  		return
   167  	}
   168  	_, err = client.Post(createURL(client), reqBody, &r.Body, &golangsdk.RequestOpts{
   169  		OkCodes:     []int{201},
   170  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   171  	})
   172  	r.Err = err
   173  	return
   174  }
   175  
   176  func (opts CreateOpts) ToPolicyUpdateMap() (map[string]interface{}, error) {
   177  	return golangsdk.BuildRequestBody(opts, "role")
   178  }
   179  
   180  func Update(c *golangsdk.ServiceClient, id string, opts CreateOpts) (r UpdateResult) {
   181  	b, err := opts.ToPolicyUpdateMap()
   182  	if err != nil {
   183  		r.Err = err
   184  		return
   185  	}
   186  	_, r.Err = c.Patch(updateURL(c, id), b, &r.Body, &golangsdk.RequestOpts{
   187  		OkCodes:     []int{200},
   188  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   189  	})
   190  	return
   191  }
   192  
   193  func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) {
   194  	_, r.Err = client.Delete(deleteURL(client, id), &golangsdk.RequestOpts{
   195  		OkCodes:     []int{200},
   196  		MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil,
   197  	})
   198  	return
   199  }