github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/identity/v3/roles/results.go (about)

     1  package roles
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  
     7  	"github.com/chnsz/golangsdk"
     8  	"github.com/chnsz/golangsdk/internal"
     9  	"github.com/chnsz/golangsdk/pagination"
    10  )
    11  
    12  const defaultPageNumber = 1
    13  
    14  // Role grants permissions to a user.
    15  type Role struct {
    16  	// DomainID is the domain ID the role belongs to.
    17  	DomainID string `json:"domain_id"`
    18  
    19  	// ID is the unique ID of the role.
    20  	ID string `json:"id"`
    21  
    22  	// Links contains referencing links to the role.
    23  	Links map[string]interface{} `json:"links"`
    24  
    25  	Name          string `json:"name"`
    26  	DisplayName   string `json:"display_name"`
    27  	Description   string `json:"description"`
    28  	DescriptionCN string `json:"description_cn"`
    29  	Flag          string `json:"flag"`
    30  	Catalog       string `json:"catalog"`
    31  	Type          string `json:"type"`
    32  	Policy        Policy `json:"policy"`
    33  
    34  	// Extra is a collection of miscellaneous key/values.
    35  	Extra map[string]interface{} `json:"-"`
    36  }
    37  
    38  func (r *Role) UnmarshalJSON(b []byte) error {
    39  	type tmp Role
    40  	var s struct {
    41  		tmp
    42  		Extra map[string]interface{} `json:"extra"`
    43  	}
    44  	err := json.Unmarshal(b, &s)
    45  	if err != nil {
    46  		return err
    47  	}
    48  	*r = Role(s.tmp)
    49  
    50  	// Collect other fields and bundle them into Extra
    51  	// but only if a field titled "extra" wasn't sent.
    52  	if s.Extra != nil {
    53  		r.Extra = s.Extra
    54  	} else {
    55  		var result interface{}
    56  		err := json.Unmarshal(b, &result)
    57  		if err != nil {
    58  			return err
    59  		}
    60  		if resultMap, ok := result.(map[string]interface{}); ok {
    61  			r.Extra = internal.RemainingKeys(Role{}, resultMap)
    62  		}
    63  	}
    64  
    65  	return err
    66  }
    67  
    68  type roleResult struct {
    69  	golangsdk.Result
    70  }
    71  
    72  // GetResult is the response from a Get operation. Call its Extract method
    73  // to interpret it as a Role.
    74  type GetResult struct {
    75  	roleResult
    76  }
    77  
    78  // CreateResult is the response from a Create operation. Call its Extract method
    79  // to interpret it as a Role
    80  type CreateResult struct {
    81  	roleResult
    82  }
    83  
    84  // UpdateResult is the response from an Update operation. Call its Extract
    85  // method to interpret it as a Role.
    86  type UpdateResult struct {
    87  	roleResult
    88  }
    89  
    90  // DeleteResult is the response from a Delete operation. Call its ExtractErr to
    91  // determine if the request succeeded or failed.
    92  type DeleteResult struct {
    93  	golangsdk.ErrResult
    94  }
    95  
    96  // RolePage is a single page of Role results.
    97  type RolePage struct {
    98  	pagination.LinkedPageBase
    99  }
   100  
   101  // IsEmpty determines whether or not a page of Roles contains any results.
   102  func (r RolePage) IsEmpty() (bool, error) {
   103  	roles, err := ExtractRoles(r)
   104  	return len(roles) == 0, err
   105  }
   106  
   107  // NextPageURL extracts the "next" link from the links section of the result.
   108  func (r RolePage) NextPageURL() (string, error) {
   109  	var s struct {
   110  		Links struct {
   111  			Next     string `json:"next"`
   112  			Previous string `json:"previous"`
   113  		} `json:"links"`
   114  	}
   115  	err := r.ExtractInto(&s)
   116  	if err != nil {
   117  		return "", err
   118  	}
   119  	return s.Links.Next, err
   120  }
   121  
   122  // ExtractRoles returns a slice of Roles contained in a single page of
   123  // results.
   124  func ExtractRoles(r pagination.Page) ([]Role, error) {
   125  	var s struct {
   126  		Roles []Role `json:"roles"`
   127  	}
   128  	err := (r.(RolePage)).ExtractInto(&s)
   129  	return s.Roles, err
   130  }
   131  
   132  // Extract interprets any roleResults as a Role.
   133  func (r roleResult) Extract() (*Role, error) {
   134  	var s struct {
   135  		Role *Role `json:"role"`
   136  	}
   137  	err := r.ExtractInto(&s)
   138  	return s.Role, err
   139  }
   140  
   141  // RoleOffsetPage is the offset page of Role results.
   142  type RoleOffsetPage struct {
   143  	pagination.OffsetPageBase
   144  }
   145  
   146  // IsEmpty determines whether or not a page of Roles contains any results.
   147  func (r RoleOffsetPage) IsEmpty() (bool, error) {
   148  	roles, err := ExtractOffsetRoles(r)
   149  	return len(roles) == 0, err
   150  }
   151  
   152  // NextOffset returns offset of the next element of the page.
   153  func (current RoleOffsetPage) CurrentPageNum() int {
   154  	q := current.URL.Query()
   155  	page, _ := strconv.Atoi(q.Get("page"))
   156  	if page == 0 {
   157  		return defaultPageNumber
   158  	}
   159  	return page
   160  }
   161  
   162  // NextPageURL generates the URL for the page of results after this one.
   163  func (current RoleOffsetPage) NextPageURL() (string, error) {
   164  	currentPageNum := current.CurrentPageNum()
   165  	currentURL := current.URL
   166  	q := currentURL.Query()
   167  	q.Set("page", strconv.Itoa(currentPageNum+1))
   168  	currentURL.RawQuery = q.Encode()
   169  
   170  	return currentURL.String(), nil
   171  }
   172  
   173  // ExtractOffsetRoles returns a slice of Roles contained in a single page of
   174  // results.
   175  func ExtractOffsetRoles(r pagination.Page) ([]Role, error) {
   176  	var s struct {
   177  		Roles []Role `json:"roles"`
   178  	}
   179  	err := (r.(RoleOffsetPage)).ExtractInto(&s)
   180  	return s.Roles, err
   181  }
   182  
   183  // RoleAssignment is the result of a role assignments query.
   184  type RoleAssignment struct {
   185  	ID            string `json:"id"`
   186  	Name          string `json:"name"`
   187  	DisplayName   string `json:"display_name"`
   188  	Description   string `json:"description"`
   189  	DescriptionCN string `json:"description_cn"`
   190  	Catalog       string `json:"catalog"`
   191  	Type          string `json:"type"`
   192  	Policy        Policy `json:"policy"`
   193  }
   194  
   195  type Policy struct {
   196  	Statement []Statement `json:"Statement"`
   197  	Version   string      `json:"Version"`
   198  }
   199  
   200  type Statement struct {
   201  	Action []string `json:"Action"`
   202  	Effect string   `json:"Effect"`
   203  }
   204  
   205  // RoleAssignmentPage is a single page of RoleAssignments results.
   206  type RoleAssignmentPage struct {
   207  	pagination.LinkedPageBase
   208  }
   209  
   210  // IsEmpty returns true if the RoleAssignmentPage contains no results.
   211  func (r RoleAssignmentPage) IsEmpty() (bool, error) {
   212  	roleAssignments, err := ExtractRoleAssignments(r)
   213  	return len(roleAssignments) == 0, err
   214  }
   215  
   216  // NextPageURL uses the response's embedded link reference to navigate to
   217  // the next page of results.
   218  func (r RoleAssignmentPage) NextPageURL() (string, error) {
   219  	var s struct {
   220  		Links struct {
   221  			Next string `json:"next"`
   222  		} `json:"links"`
   223  	}
   224  	err := r.ExtractInto(&s)
   225  	return s.Links.Next, err
   226  }
   227  
   228  // ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection
   229  // acquired from List.
   230  func ExtractRoleAssignments(r pagination.Page) ([]RoleAssignment, error) {
   231  	var s struct {
   232  		RoleAssignments []RoleAssignment `json:"roles"`
   233  	}
   234  	err := (r.(RoleAssignmentPage)).ExtractInto(&s)
   235  	return s.RoleAssignments, err
   236  }
   237  
   238  // AssignmentResult represents the result of an assign operation.
   239  // Call ExtractErr method to determine if the request succeeded or failed.
   240  type AssignmentResult struct {
   241  	golangsdk.ErrResult
   242  }
   243  
   244  // UnassignmentResult represents the result of an unassign operation.
   245  // Call ExtractErr method to determine if the request succeeded or failed.
   246  type UnassignmentResult struct {
   247  	golangsdk.ErrResult
   248  }
   249  
   250  type CheckResult struct {
   251  	golangsdk.ErrResult
   252  }