github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/identity/v3/policies/requests.go (about)

     1  package policies
     2  
     3  import (
     4  	"context"
     5  	"net/url"
     6  	"strings"
     7  
     8  	"github.com/vnpaycloud-console/gophercloud/v2"
     9  	"github.com/vnpaycloud-console/gophercloud/v2/pagination"
    10  )
    11  
    12  const policyTypeMaxLength = 255
    13  
    14  // ListOptsBuilder allows extensions to add additional parameters to
    15  // the List request
    16  type ListOptsBuilder interface {
    17  	ToPolicyListQuery() (string, error)
    18  }
    19  
    20  // ListOpts provides options to filter the List results.
    21  type ListOpts struct {
    22  	// Type filters the response by MIME media type
    23  	// of the serialized policy blob.
    24  	Type string `q:"type"`
    25  
    26  	// Filters filters the response by custom filters such as
    27  	// 'type__contains=foo'
    28  	Filters map[string]string `q:"-"`
    29  }
    30  
    31  // ToPolicyListQuery formats a ListOpts into a query string.
    32  func (opts ListOpts) ToPolicyListQuery() (string, error) {
    33  	q, err := gophercloud.BuildQueryString(opts)
    34  	if err != nil {
    35  		return "", err
    36  	}
    37  
    38  	params := q.Query()
    39  	for k, v := range opts.Filters {
    40  		i := strings.Index(k, "__")
    41  		if i > 0 && i < len(k)-2 {
    42  			params.Add(k, v)
    43  		} else {
    44  			return "", InvalidListFilter{FilterName: k}
    45  		}
    46  	}
    47  
    48  	q = &url.URL{RawQuery: params.Encode()}
    49  	return q.String(), err
    50  }
    51  
    52  // List enumerates the policies to which the current token has access.
    53  func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
    54  	url := listURL(client)
    55  	if opts != nil {
    56  		query, err := opts.ToPolicyListQuery()
    57  		if err != nil {
    58  			return pagination.Pager{Err: err}
    59  		}
    60  		url += query
    61  	}
    62  
    63  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
    64  		return PolicyPage{pagination.LinkedPageBase{PageResult: r}}
    65  	})
    66  }
    67  
    68  // CreateOptsBuilder allows extensions to add additional parameters to
    69  // the Create request.
    70  type CreateOptsBuilder interface {
    71  	ToPolicyCreateMap() (map[string]any, error)
    72  }
    73  
    74  // CreateOpts provides options used to create a policy.
    75  type CreateOpts struct {
    76  	// Type is the MIME media type of the serialized policy blob.
    77  	Type string `json:"type" required:"true"`
    78  
    79  	// Blob is the policy rule as a serialized blob.
    80  	Blob []byte `json:"-" required:"true"`
    81  
    82  	// Extra is free-form extra key/value pairs to describe the policy.
    83  	Extra map[string]any `json:"-"`
    84  }
    85  
    86  // ToPolicyCreateMap formats a CreateOpts into a create request.
    87  func (opts CreateOpts) ToPolicyCreateMap() (map[string]any, error) {
    88  	if len(opts.Type) > policyTypeMaxLength {
    89  		return nil, StringFieldLengthExceedsLimit{
    90  			Field: "type",
    91  			Limit: policyTypeMaxLength,
    92  		}
    93  	}
    94  
    95  	b, err := gophercloud.BuildRequestBody(opts, "policy")
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	if v, ok := b["policy"].(map[string]any); ok {
   101  		v["blob"] = string(opts.Blob)
   102  
   103  		if opts.Extra != nil {
   104  			for key, value := range opts.Extra {
   105  				v[key] = value
   106  			}
   107  		}
   108  	}
   109  
   110  	return b, nil
   111  }
   112  
   113  // Create creates a new Policy.
   114  func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   115  	b, err := opts.ToPolicyCreateMap()
   116  	if err != nil {
   117  		r.Err = err
   118  		return
   119  	}
   120  	resp, err := client.Post(ctx, createURL(client), &b, &r.Body, &gophercloud.RequestOpts{
   121  		OkCodes: []int{201},
   122  	})
   123  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   124  	return
   125  }
   126  
   127  // Get retrieves details on a single policy, by ID.
   128  func Get(ctx context.Context, client *gophercloud.ServiceClient, policyID string) (r GetResult) {
   129  	resp, err := client.Get(ctx, getURL(client, policyID), &r.Body, nil)
   130  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   131  	return
   132  }
   133  
   134  // UpdateOptsBuilder allows extensions to add additional parameters to
   135  // the Update request.
   136  type UpdateOptsBuilder interface {
   137  	ToPolicyUpdateMap() (map[string]any, error)
   138  }
   139  
   140  // UpdateOpts provides options for updating a policy.
   141  type UpdateOpts struct {
   142  	// Type is the MIME media type of the serialized policy blob.
   143  	Type string `json:"type,omitempty"`
   144  
   145  	// Blob is the policy rule as a serialized blob.
   146  	Blob []byte `json:"-"`
   147  
   148  	// Extra is free-form extra key/value pairs to describe the policy.
   149  	Extra map[string]any `json:"-"`
   150  }
   151  
   152  // ToPolicyUpdateMap formats a UpdateOpts into an update request.
   153  func (opts UpdateOpts) ToPolicyUpdateMap() (map[string]any, error) {
   154  	if len(opts.Type) > policyTypeMaxLength {
   155  		return nil, StringFieldLengthExceedsLimit{
   156  			Field: "type",
   157  			Limit: policyTypeMaxLength,
   158  		}
   159  	}
   160  
   161  	b, err := gophercloud.BuildRequestBody(opts, "policy")
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  
   166  	if v, ok := b["policy"].(map[string]any); ok {
   167  		if len(opts.Blob) != 0 {
   168  			v["blob"] = string(opts.Blob)
   169  		}
   170  
   171  		if opts.Extra != nil {
   172  			for key, value := range opts.Extra {
   173  				v[key] = value
   174  			}
   175  		}
   176  	}
   177  
   178  	return b, nil
   179  }
   180  
   181  // Update updates an existing Role.
   182  func Update(ctx context.Context, client *gophercloud.ServiceClient, policyID string, opts UpdateOptsBuilder) (r UpdateResult) {
   183  	b, err := opts.ToPolicyUpdateMap()
   184  	if err != nil {
   185  		r.Err = err
   186  		return
   187  	}
   188  	resp, err := client.Patch(ctx, updateURL(client, policyID), &b, &r.Body, &gophercloud.RequestOpts{
   189  		OkCodes: []int{200},
   190  	})
   191  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   192  	return
   193  }
   194  
   195  // Delete deletes a policy.
   196  func Delete(ctx context.Context, client *gophercloud.ServiceClient, policyID string) (r DeleteResult) {
   197  	resp, err := client.Delete(ctx, deleteURL(client, policyID), nil)
   198  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   199  	return
   200  }