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

     1  package projects
     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  // ListOptsBuilder allows extensions to add additional parameters to
    13  // the List request
    14  type ListOptsBuilder interface {
    15  	ToProjectListQuery() (string, error)
    16  }
    17  
    18  // ListOpts enables filtering of a list request.
    19  type ListOpts struct {
    20  	// DomainID filters the response by a domain ID.
    21  	DomainID string `q:"domain_id"`
    22  
    23  	// Enabled filters the response by enabled projects.
    24  	Enabled *bool `q:"enabled"`
    25  
    26  	// IsDomain filters the response by projects that are domains.
    27  	// Setting this to true is effectively listing domains.
    28  	IsDomain *bool `q:"is_domain"`
    29  
    30  	// Name filters the response by project name.
    31  	Name string `q:"name"`
    32  
    33  	// ParentID filters the response by projects of a given parent project.
    34  	ParentID string `q:"parent_id"`
    35  
    36  	// Tags filters on specific project tags. All tags must be present for the project.
    37  	Tags string `q:"tags"`
    38  
    39  	// TagsAny filters on specific project tags. At least one of the tags must be present for the project.
    40  	TagsAny string `q:"tags-any"`
    41  
    42  	// NotTags filters on specific project tags. All tags must be absent for the project.
    43  	NotTags string `q:"not-tags"`
    44  
    45  	// NotTagsAny filters on specific project tags. At least one of the tags must be absent for the project.
    46  	NotTagsAny string `q:"not-tags-any"`
    47  
    48  	// Filters filters the response by custom filters such as
    49  	// 'name__contains=foo'
    50  	Filters map[string]string `q:"-"`
    51  }
    52  
    53  // ToProjectListQuery formats a ListOpts into a query string.
    54  func (opts ListOpts) ToProjectListQuery() (string, error) {
    55  	q, err := gophercloud.BuildQueryString(opts)
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  
    60  	params := q.Query()
    61  	for k, v := range opts.Filters {
    62  		i := strings.Index(k, "__")
    63  		if i > 0 && i < len(k)-2 {
    64  			params.Add(k, v)
    65  		} else {
    66  			return "", InvalidListFilter{FilterName: k}
    67  		}
    68  	}
    69  
    70  	q = &url.URL{RawQuery: params.Encode()}
    71  	return q.String(), err
    72  }
    73  
    74  // List enumerates the Projects to which the current token has access.
    75  func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
    76  	url := listURL(client)
    77  	if opts != nil {
    78  		query, err := opts.ToProjectListQuery()
    79  		if err != nil {
    80  			return pagination.Pager{Err: err}
    81  		}
    82  		url += query
    83  	}
    84  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
    85  		return ProjectPage{pagination.LinkedPageBase{PageResult: r}}
    86  	})
    87  }
    88  
    89  // ListAvailable enumerates the Projects which are available to a specific user.
    90  func ListAvailable(client *gophercloud.ServiceClient) pagination.Pager {
    91  	url := listAvailableURL(client)
    92  	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
    93  		return ProjectPage{pagination.LinkedPageBase{PageResult: r}}
    94  	})
    95  }
    96  
    97  // Get retrieves details on a single project, by ID.
    98  func Get(ctx context.Context, client *gophercloud.ServiceClient, id string) (r GetResult) {
    99  	resp, err := client.Get(ctx, getURL(client, id), &r.Body, nil)
   100  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   101  	return
   102  }
   103  
   104  // CreateOptsBuilder allows extensions to add additional parameters to
   105  // the Create request.
   106  type CreateOptsBuilder interface {
   107  	ToProjectCreateMap() (map[string]any, error)
   108  }
   109  
   110  // CreateOpts represents parameters used to create a project.
   111  type CreateOpts struct {
   112  	// DomainID is the ID this project will belong under.
   113  	DomainID string `json:"domain_id,omitempty"`
   114  
   115  	// Enabled sets the project status to enabled or disabled.
   116  	Enabled *bool `json:"enabled,omitempty"`
   117  
   118  	// IsDomain indicates if this project is a domain.
   119  	IsDomain *bool `json:"is_domain,omitempty"`
   120  
   121  	// Name is the name of the project.
   122  	Name string `json:"name" required:"true"`
   123  
   124  	// ParentID specifies the parent project of this new project.
   125  	ParentID string `json:"parent_id,omitempty"`
   126  
   127  	// Description is the description of the project.
   128  	Description string `json:"description,omitempty"`
   129  
   130  	// Tags is a list of tags to associate with the project.
   131  	Tags []string `json:"tags,omitempty"`
   132  
   133  	// Extra is free-form extra key/value pairs to describe the project.
   134  	Extra map[string]any `json:"-"`
   135  
   136  	// Options are defined options in the API to enable certain features.
   137  	Options map[Option]any `json:"options,omitempty"`
   138  }
   139  
   140  // ToProjectCreateMap formats a CreateOpts into a create request.
   141  func (opts CreateOpts) ToProjectCreateMap() (map[string]any, error) {
   142  	b, err := gophercloud.BuildRequestBody(opts, "project")
   143  
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	if opts.Extra != nil {
   149  		if v, ok := b["project"].(map[string]any); ok {
   150  			for key, value := range opts.Extra {
   151  				v[key] = value
   152  			}
   153  		}
   154  	}
   155  
   156  	return b, nil
   157  }
   158  
   159  // Create creates a new Project.
   160  func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   161  	b, err := opts.ToProjectCreateMap()
   162  	if err != nil {
   163  		r.Err = err
   164  		return
   165  	}
   166  	resp, err := client.Post(ctx, createURL(client), &b, &r.Body, nil)
   167  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   168  	return
   169  }
   170  
   171  // Delete deletes a project.
   172  func Delete(ctx context.Context, client *gophercloud.ServiceClient, projectID string) (r DeleteResult) {
   173  	resp, err := client.Delete(ctx, deleteURL(client, projectID), nil)
   174  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   175  	return
   176  }
   177  
   178  // UpdateOptsBuilder allows extensions to add additional parameters to
   179  // the Update request.
   180  type UpdateOptsBuilder interface {
   181  	ToProjectUpdateMap() (map[string]any, error)
   182  }
   183  
   184  // UpdateOpts represents parameters to update a project.
   185  type UpdateOpts struct {
   186  	// DomainID is the ID this project will belong under.
   187  	DomainID string `json:"domain_id,omitempty"`
   188  
   189  	// Enabled sets the project status to enabled or disabled.
   190  	Enabled *bool `json:"enabled,omitempty"`
   191  
   192  	// IsDomain indicates if this project is a domain.
   193  	IsDomain *bool `json:"is_domain,omitempty"`
   194  
   195  	// Name is the name of the project.
   196  	Name string `json:"name,omitempty"`
   197  
   198  	// ParentID specifies the parent project of this new project.
   199  	ParentID string `json:"parent_id,omitempty"`
   200  
   201  	// Description is the description of the project.
   202  	Description *string `json:"description,omitempty"`
   203  
   204  	// Tags is a list of tags to associate with the project.
   205  	Tags *[]string `json:"tags,omitempty"`
   206  
   207  	// Extra is free-form extra key/value pairs to describe the project.
   208  	Extra map[string]any `json:"-"`
   209  
   210  	// Options are defined options in the API to enable certain features.
   211  	Options map[Option]any `json:"options,omitempty"`
   212  }
   213  
   214  // ToUpdateCreateMap formats a UpdateOpts into an update request.
   215  func (opts UpdateOpts) ToProjectUpdateMap() (map[string]any, error) {
   216  	b, err := gophercloud.BuildRequestBody(opts, "project")
   217  
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  
   222  	if opts.Extra != nil {
   223  		if v, ok := b["project"].(map[string]any); ok {
   224  			for key, value := range opts.Extra {
   225  				v[key] = value
   226  			}
   227  		}
   228  	}
   229  
   230  	return b, nil
   231  }
   232  
   233  // Update modifies the attributes of a project.
   234  func Update(ctx context.Context, client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
   235  	b, err := opts.ToProjectUpdateMap()
   236  	if err != nil {
   237  		r.Err = err
   238  		return
   239  	}
   240  	resp, err := client.Patch(ctx, updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
   241  		OkCodes: []int{200},
   242  	})
   243  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   244  	return
   245  }
   246  
   247  // CheckTags lists tags for a project.
   248  func ListTags(ctx context.Context, client *gophercloud.ServiceClient, projectID string) (r ListTagsResult) {
   249  	resp, err := client.Get(ctx, listTagsURL(client, projectID), &r.Body, &gophercloud.RequestOpts{
   250  		OkCodes: []int{200},
   251  	})
   252  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   253  	return
   254  }
   255  
   256  // Tags represents a list of Tags object.
   257  type ModifyTagsOpts struct {
   258  	// Tags is the list of tags associated with the project.
   259  	Tags []string `json:"tags,omitempty"`
   260  }
   261  
   262  // ModifyTagsOptsBuilder allows extensions to add additional parameters to
   263  // the Modify request.
   264  type ModifyTagsOptsBuilder interface {
   265  	ToModifyTagsCreateMap() (map[string]any, error)
   266  }
   267  
   268  // ToModifyTagsCreateMap formats a ModifyTagsOpts into a Modify tags request.
   269  func (opts ModifyTagsOpts) ToModifyTagsCreateMap() (map[string]any, error) {
   270  	b, err := gophercloud.BuildRequestBody(opts, "")
   271  
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	return b, nil
   276  }
   277  
   278  // ModifyTags deletes all tags of a project and adds new ones.
   279  func ModifyTags(ctx context.Context, client *gophercloud.ServiceClient, projectID string, opts ModifyTagsOpts) (r ModifyTagsResult) {
   280  
   281  	b, err := opts.ToModifyTagsCreateMap()
   282  	if err != nil {
   283  		r.Err = err
   284  		return
   285  	}
   286  	resp, err := client.Put(ctx, modifyTagsURL(client, projectID), b, &r.Body, &gophercloud.RequestOpts{
   287  		OkCodes: []int{200},
   288  	})
   289  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   290  	return
   291  }
   292  
   293  // DeleteTag deletes a tag from a project.
   294  func DeleteTags(ctx context.Context, client *gophercloud.ServiceClient, projectID string) (r DeleteTagsResult) {
   295  	resp, err := client.Delete(ctx, deleteTagsURL(client, projectID), &gophercloud.RequestOpts{
   296  		OkCodes: []int{204},
   297  	})
   298  	_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
   299  	return
   300  }