-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
1,499 additions
and
1,944 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
module github.com/selectel/go-selvpcclient | ||
|
||
go 1.14 | ||
|
||
require github.com/gophercloud/gophercloud v1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k= | ||
github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= | ||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package quotamanager | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"io/ioutil" //nolint:staticcheck | ||
"net/http" | ||
"strings" | ||
"unicode" | ||
|
||
"github.com/selectel/go-selvpcclient/selvpcclient/resell" | ||
) | ||
|
||
var errServiceResponse = errors.New("status code from the server") | ||
|
||
const ( | ||
projectURL = "projects" | ||
) | ||
|
||
// QuotaRegionalClient stores details that are needed to work with quotas Selectel APIs. | ||
type QuotaRegionalClient struct { | ||
UserAgent string | ||
HTTPClient *http.Client | ||
IdentityMgr IdentityManagerInterface | ||
} | ||
|
||
// NewQuotaRegionalClient creates regional quota client with Openstack identity and HTTP client. | ||
func NewQuotaRegionalClient(httpClient *http.Client, identityMgr IdentityManagerInterface) *QuotaRegionalClient { | ||
return &QuotaRegionalClient{ | ||
UserAgent: resell.UserAgent, | ||
IdentityMgr: identityMgr, | ||
HTTPClient: httpClient, | ||
} | ||
} | ||
|
||
type ResponseResult struct { | ||
*http.Response | ||
|
||
// Err contains error that can be provided to a caller. | ||
Err error | ||
} | ||
|
||
// ExtractResult allows to provide an object into which ResponseResult body will be extracted. | ||
func (result *ResponseResult) ExtractResult(to interface{}) error { | ||
body, err := ioutil.ReadAll(result.Body) | ||
defer result.Body.Close() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = json.Unmarshal(body, to) | ||
return err | ||
} | ||
|
||
func (result *ResponseResult) ExtractErr() (string, error) { | ||
body, err := ioutil.ReadAll(result.Body) | ||
defer result.Body.Close() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
resp := string(body) | ||
|
||
var builder strings.Builder | ||
builder.Grow(len(resp)) | ||
for _, ch := range resp { | ||
if !unicode.IsSpace(ch) { | ||
builder.WriteRune(ch) | ||
} | ||
} | ||
|
||
return builder.String(), nil | ||
} | ||
|
||
// DoRequest performs the HTTP request with the current ServiceClient's HTTPClient. | ||
// Authentication and optional headers will be added automatically. | ||
func (mgr *QuotaRegionalClient) DoRequest(ctx context.Context, method, path string, body io.Reader) (*ResponseResult, error) { | ||
tokenID, err := mgr.IdentityMgr.GetToken() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
request, err := http.NewRequest(method, path, body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
request.Header.Set("User-Agent", mgr.UserAgent) | ||
request.Header.Set("X-Auth-Token", tokenID) | ||
if body != nil { | ||
request.Header.Set("Content-Type", "application/json") | ||
} | ||
request = request.WithContext(ctx) | ||
|
||
// Send HTTP request and populate the ResponseResult. | ||
response, err := mgr.HTTPClient.Do(request) | ||
if err != nil { | ||
return nil, err | ||
} | ||
responseResult := &ResponseResult{ | ||
response, | ||
nil, | ||
} | ||
|
||
// Check status code and populate extended error message if it's possible. | ||
if response.StatusCode >= 400 && response.StatusCode <= 599 { | ||
extendedError, err := responseResult.ExtractErr() | ||
if err != nil { | ||
responseResult.Err = fmt.Errorf("selvpcclient: got the %d %w", response.StatusCode, errServiceResponse) | ||
} else { | ||
responseResult.Err = fmt.Errorf("selvpcclient: got the %d %w: %s", response.StatusCode, errServiceResponse, extendedError) | ||
} | ||
} | ||
|
||
return responseResult, nil | ||
} | ||
|
||
// BuildPath builds quotas url for specific region and project. | ||
func (mgr *QuotaRegionalClient) BuildPath(region, projectID, path string) (string, error) { | ||
baseURL, err := mgr.IdentityMgr.GetEndpointForRegion(region) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
path = strings.Join([]string{baseURL, projectURL, projectID, path}, "/") | ||
|
||
return path, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
Package quotamanager provides methods and structures to work with the Quotas Manager API. | ||
Example of creating QuotaRegional client | ||
resellClient := resell.NewV2ResellClient(APIToken) | ||
ctx := context.Background() | ||
accountName := "123456" | ||
token, _, _ := reselTokens.Create(ctx, resellClient, reselTokens.TokenOpts{ | ||
AccountName: accountName, | ||
}) | ||
OpenstackClient := resell.NewOpenstackClient(token.ID) | ||
identity := quotamanager.NewIdentityManager(resellClient, OpenstackClient, accountName) | ||
QuotaRegionalClient := quotamanager.NewQuotaRegionalClient(selvpcclient.NewHTTPClient(), identity) | ||
*/ | ||
package quotamanager |
Oops, something went wrong.