github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/organization/cloud_organization.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package organization 21 22 import ( 23 "encoding/json" 24 "net/http" 25 "os" 26 "path/filepath" 27 "strings" 28 29 "github.com/pkg/errors" 30 ) 31 32 type CloudOrganization struct { 33 Token string 34 APIURL string 35 APIPath string 36 } 37 38 func (o *CloudOrganization) getOrganization(name string) (*OrgItem, error) { 39 path := strings.Join([]string{o.APIURL, o.APIPath, "organizations", name}, "/") 40 response, err := NewRequest(http.MethodGet, path, o.Token, nil) 41 if err != nil { 42 return nil, errors.Wrap(err, "Failed to get organization.") 43 } 44 45 var orgItem OrgItem 46 err = json.Unmarshal(response, &orgItem) 47 if err != nil { 48 return nil, errors.Wrap(err, "Invalid organization format.") 49 } 50 51 return &orgItem, nil 52 } 53 54 func (o *CloudOrganization) GetOrganizations() (*Organizations, error) { 55 path := strings.Join([]string{o.APIURL, o.APIPath, "organizations"}, "/") 56 response, err := NewRequest(http.MethodGet, path, o.Token, nil) 57 if err != nil { 58 return nil, errors.Wrap(err, "Failed to get organizations.") 59 } 60 61 var organizations Organizations 62 err = json.Unmarshal(response, &organizations) 63 if err != nil { 64 return nil, errors.Wrap(err, "Invalid organizations format.") 65 } 66 67 return &organizations, nil 68 } 69 70 func (o *CloudOrganization) switchOrganization(name string) (string, error) { 71 if ok, err := o.IsValidOrganization(name); !ok { 72 return "", err 73 } 74 75 currentOrgAndContext, err := GetCurrentOrgAndContext() 76 if err != nil { 77 return "", errors.Wrap(err, "Failed to get current organization.") 78 } 79 oldOrganizationName := currentOrgAndContext.CurrentOrganization 80 currentOrgAndContext.CurrentOrganization = name 81 if err = SetCurrentOrgAndContext(currentOrgAndContext); err != nil { 82 return "", errors.Wrapf(err, "Failed to switch organization to %s.", name) 83 } 84 return oldOrganizationName, nil 85 } 86 87 func (o *CloudOrganization) getCurrentOrganization() (string, error) { 88 currentOrg, err := getCurrentOrganization() 89 if err != nil { 90 return "", err 91 } 92 93 if ok, err := o.IsValidOrganization(currentOrg); !ok { 94 return "", err 95 } 96 return currentOrg, nil 97 } 98 99 func (o *CloudOrganization) IsValidOrganization(name string) (bool, error) { 100 organizations, err := o.GetOrganizations() 101 if err != nil { 102 return false, errors.Wrap(err, "Failed to get organizations.") 103 } 104 for _, item := range organizations.Items { 105 if item.Name == name { 106 return true, nil 107 } 108 } 109 return false, errors.Errorf("Organization %s not found.", name) 110 } 111 112 func (o *CloudOrganization) addOrganization(body []byte) error { 113 path := strings.Join([]string{o.APIURL, o.APIPath, "organizations"}, "/") 114 _, err := NewRequest(http.MethodPost, path, o.Token, body) 115 if err != nil { 116 return errors.Wrap(err, "Failed to add organization.") 117 } 118 119 return nil 120 } 121 122 func (o *CloudOrganization) deleteOrganization(name string) error { 123 path := strings.Join([]string{o.APIURL, o.APIPath, "organizations", name}, "/") 124 _, err := NewRequest(http.MethodDelete, path, o.Token, nil) 125 if err != nil { 126 return errors.Wrap(err, "Failed to delete organization.") 127 } 128 129 return nil 130 } 131 132 // SetCurrentOrgAndContext TODO:Check whether the newly set context and org exist. 133 func SetCurrentOrgAndContext(currentOrgAndContext *CurrentOrgAndContext) error { 134 data, err := json.MarshalIndent(currentOrgAndContext, "", " ") 135 if err != nil { 136 return errors.Wrap(err, "Failed to marshal current organization and context.") 137 } 138 139 filePath, err := GetCurrentOrgAndContextFilePath() 140 if err != nil { 141 return errors.Wrap(err, "Failed to get current organization and context.") 142 } 143 144 // Create the necessary folders and file if they don't exist 145 if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil { 146 return errors.Wrap(err, "Failed to create necessary folders.") 147 } 148 149 file, err := os.Create(filePath) 150 if err != nil { 151 return errors.Wrap(err, "Failed to create or open current organization and context file.") 152 } 153 154 _, err = file.Write(data) 155 if err != nil { 156 return errors.Wrap(err, "Failed to write current organization and context.") 157 } 158 defer file.Close() 159 160 return nil 161 } 162 163 func getCurrentOrganization() (string, error) { 164 currentOrgAndContext, err := GetCurrentOrgAndContext() 165 if err != nil { 166 return "", err 167 } 168 169 if currentOrgAndContext.CurrentOrganization == "" { 170 return "", errors.New("No organization available, please join an organization.") 171 } 172 return currentOrgAndContext.CurrentOrganization, nil 173 }