yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/openstack/project.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package openstack
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  
    21  	"yunion.io/x/log"
    22  	"yunion.io/x/pkg/errors"
    23  
    24  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    25  	"yunion.io/x/onecloud/pkg/mcclient"
    26  	"yunion.io/x/cloudmux/pkg/multicloud"
    27  	"yunion.io/x/onecloud/pkg/util/httputils"
    28  )
    29  
    30  type SProject struct {
    31  	multicloud.SProjectBase
    32  	OpenStackTags
    33  	client      *SOpenStackClient
    34  	Description string
    35  	Enabled     bool
    36  	Id          string
    37  	Name        string
    38  }
    39  
    40  func (p *SProject) GetId() string {
    41  	return p.Id
    42  }
    43  
    44  func (p *SProject) GetGlobalId() string {
    45  	return p.GetId()
    46  }
    47  
    48  func (p *SProject) GetName() string {
    49  	return p.Name
    50  }
    51  
    52  func (p *SProject) GetStatus() string {
    53  	if !p.Enabled {
    54  		return api.EXTERNAL_PROJECT_STATUS_UNKNOWN
    55  	}
    56  	_, err := p.getToken()
    57  	if err != nil {
    58  		log.Errorf("get project %s token error: %v %T", p.Name, err, err)
    59  		return api.EXTERNAL_PROJECT_STATUS_UNKNOWN
    60  	}
    61  	return api.EXTERNAL_PROJECT_STATUS_AVAILABLE
    62  }
    63  
    64  func (p *SProject) getToken() (mcclient.TokenCredential, error) {
    65  	return p.client.getProjectToken(p.Id, p.Name)
    66  }
    67  
    68  func (p *SProject) IsEmulated() bool {
    69  	return false
    70  }
    71  
    72  func (p *SProject) Refresh() error {
    73  	return nil
    74  }
    75  
    76  type SProjectLinks struct {
    77  	Next     string
    78  	Previous string
    79  	Self     string
    80  }
    81  
    82  func (link SProjectLinks) GetNextMark() string {
    83  	if len(link.Next) == 0 || link.Next == "null" {
    84  		return ""
    85  	}
    86  	next, err := url.Parse(link.Next)
    87  	if err != nil {
    88  		log.Errorf("parse next link %s error: %v", link.Next, err)
    89  		return ""
    90  	}
    91  	return next.Query().Get("marker")
    92  }
    93  
    94  func (cli *SOpenStackClient) GetProjects() ([]SProject, error) {
    95  	resource := "/v3/projects"
    96  	projects := []SProject{}
    97  	query := url.Values{}
    98  	for {
    99  		resp, err := cli.iamRequest("", httputils.GET, resource, query, nil)
   100  		if err != nil {
   101  			return nil, errors.Wrap(err, "iamRequest")
   102  		}
   103  		part := struct {
   104  			Projects []SProject
   105  			Links    SProjectLinks
   106  		}{}
   107  		err = resp.Unmarshal(&part)
   108  		if err != nil {
   109  			return nil, errors.Wrap(err, "iamRequest")
   110  		}
   111  		projects = append(projects, part.Projects...)
   112  		marker := part.Links.GetNextMark()
   113  		if len(marker) == 0 {
   114  			break
   115  		}
   116  		query.Set("marker", marker)
   117  	}
   118  	return projects, nil
   119  }
   120  
   121  func (cli *SOpenStackClient) DeleteProject(projectId string) error {
   122  	resource := fmt.Sprintf("/v3/projects/%s", projectId)
   123  	_, err := cli.iamRequest(cli.getDefaultRegionName(), httputils.DELETE, resource, nil, nil)
   124  	return err
   125  }