lego/vendor/github.com/sacloud/libsacloud/api/base_api.go
Ludovic Fernandez 42941ccea6
Refactor the core of the lib (#700)
- Packages
- Isolate code used by the CLI into the package `cmd`
- (experimental) Add e2e tests for HTTP01, TLS-ALPN-01 and DNS-01, use [Pebble](https://github.com/letsencrypt/pebble) and [challtestsrv](https://github.com/letsencrypt/boulder/tree/master/test/challtestsrv) 
- Support non-ascii domain name (punnycode)
- Check all challenges in a predictable order
- No more global exported variables
- Archive revoked certificates
- Fixes revocation for subdomains and non-ascii domains
- Disable pending authorizations
- use pointer for RemoteError/ProblemDetails
- Poll authz URL instead of challenge URL
- The ability for a DNS provider to solve the challenge sequentially
- Check all nameservers in a predictable order
- Option to disable the complete propagation Requirement
- CLI, support for renew with CSR
- CLI, add SAN on renew
- Add command to list certificates.
- Logs every iteration of waiting for the propagation
- update DNSimple client
- update github.com/miekg/dns
2018-12-06 22:50:17 +01:00

278 lines
6.4 KiB
Go

package api
import (
"encoding/json"
"fmt"
"net/url"
"github.com/sacloud/libsacloud/sacloud"
)
type baseAPI struct {
client *Client
FuncGetResourceURL func() string
FuncBaseSearchCondition func() *sacloud.Request
state *sacloud.Request
apiRootSuffix string
}
var (
sakuraCloudAPIRootSuffix = "api/cloud/1.1"
sakuraBillingAPIRootSuffix = "api/system/1.0"
sakuraWebAccelAPIRootSuffix = "api/webaccel/1.0"
)
func (api *baseAPI) getResourceURL() string {
suffix := api.apiRootSuffix
//デフォルト : クラウドAPI
if suffix == "" {
suffix = sakuraCloudAPIRootSuffix
}
url := ""
if api.FuncGetResourceURL != nil {
url = api.FuncGetResourceURL()
}
if suffix == "" {
return url
}
if url == "" {
return suffix
}
return fmt.Sprintf("%s/%s", suffix, url)
}
func (api *baseAPI) getSearchState() *sacloud.Request {
if api.state == nil {
api.reset()
}
return api.state
}
func (api *baseAPI) sortBy(key string, reverse bool) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
if state.Sort == nil {
state.Sort = []string{}
}
col := key
if reverse {
col = "-" + col
}
state.Sort = append(state.Sort, col)
})
}
func (api *baseAPI) reset() *baseAPI {
if api.FuncBaseSearchCondition == nil {
api.state = &sacloud.Request{}
} else {
api.state = api.FuncBaseSearchCondition()
}
return api
}
func (api *baseAPI) setStateValue(setFunc func(*sacloud.Request)) *baseAPI {
state := api.getSearchState()
setFunc(state)
return api
}
func (api *baseAPI) offset(offset int) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
state.From = offset
})
}
func (api *baseAPI) limit(limit int) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
state.Count = limit
})
}
func (api *baseAPI) include(key string) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
if state.Include == nil {
state.Include = []string{}
}
state.Include = append(state.Include, key)
})
}
func (api *baseAPI) exclude(key string) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
if state.Exclude == nil {
state.Exclude = []string{}
}
state.Exclude = append(state.Exclude, key)
})
}
func (api *baseAPI) filterBy(key string, value interface{}, multiple bool) *baseAPI {
return api.setStateValue(func(state *sacloud.Request) {
//HACK さくらのクラウド側でqueryStringでの+エスケープに対応していないため、
// %20にエスケープされるurl.Pathを利用する。
// http://qiita.com/shibukawa/items/c0730092371c0e243f62
if strValue, ok := value.(string); ok {
u := &url.URL{Path: strValue}
value = u.String()
}
if state.Filter == nil {
state.Filter = map[string]interface{}{}
}
if multiple {
if state.Filter[key] == nil {
state.Filter[key] = []interface{}{}
}
state.Filter[key] = append(state.Filter[key].([]interface{}), value)
} else {
// どちらもstring型の場合はスペース区切りで繋げる
if f, ok := state.Filter[key]; ok {
if s, ok := f.(string); ok && s != "" {
if v, ok := value.(string); ok {
state.Filter[key] = fmt.Sprintf("%s %s", s, v)
return
}
}
}
state.Filter[key] = value
}
})
}
func (api *baseAPI) withNameLike(name string) *baseAPI {
return api.filterBy("Name", name, false)
}
func (api *baseAPI) withTag(tag string) *baseAPI {
return api.filterBy("Tags.Name", tag, false)
}
func (api *baseAPI) withTags(tags []string) *baseAPI {
return api.filterBy("Tags.Name", tags, false)
}
func (api *baseAPI) sortByName(reverse bool) *baseAPI {
return api.sortBy("Name", reverse)
}
func (api *baseAPI) Find() (*sacloud.SearchResponse, error) {
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
if err != nil {
return nil, err
}
var res sacloud.SearchResponse
if err := json.Unmarshal(data, &res); err != nil {
return nil, err
}
return &res, nil
}
func (api *baseAPI) request(method string, uri string, body interface{}, res interface{}) error {
data, err := api.client.newRequest(method, uri, body)
if err != nil {
return err
}
if res != nil {
if err := json.Unmarshal(data, &res); err != nil {
return err
}
}
return nil
}
func (api *baseAPI) create(body interface{}, res interface{}) error {
var (
method = "POST"
uri = api.getResourceURL()
)
return api.request(method, uri, body, res)
}
func (api *baseAPI) read(id int64, body interface{}, res interface{}) error {
var (
method = "GET"
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
)
return api.request(method, uri, body, res)
}
func (api *baseAPI) update(id int64, body interface{}, res interface{}) error {
var (
method = "PUT"
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
)
return api.request(method, uri, body, res)
}
func (api *baseAPI) delete(id int64, body interface{}, res interface{}) error {
var (
method = "DELETE"
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
)
return api.request(method, uri, body, res)
}
func (api *baseAPI) modify(method string, uri string, body interface{}) (bool, error) {
res := &sacloud.ResultFlagValue{}
err := api.request(method, uri, body, res)
if err != nil {
return false, err
}
return res.IsOk, nil
}
func (api *baseAPI) action(method string, uri string, body interface{}, res interface{}) (bool, error) {
err := api.request(method, uri, body, res)
if err != nil {
return false, err
}
return true, nil
}
func (api *baseAPI) monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
var (
method = "GET"
uri = fmt.Sprintf("%s/%d/monitor", api.getResourceURL(), id)
)
res := &sacloud.ResourceMonitorResponse{}
err := api.request(method, uri, body, res)
if err != nil {
return nil, err
}
return res.Data, nil
}
func (api *baseAPI) applianceMonitorBy(id int64, target string, nicIndex int, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
var (
method = "GET"
uri = fmt.Sprintf("%s/%d/%s/%d/monitor", api.getResourceURL(), id, target, nicIndex)
)
if nicIndex == 0 {
uri = fmt.Sprintf("%s/%d/%s/monitor", api.getResourceURL(), id, target)
}
res := &sacloud.ResourceMonitorResponse{}
err := api.request(method, uri, body, res)
if err != nil {
return nil, err
}
return res.Data, nil
}
func (api *baseAPI) NewResourceMonitorRequest() *sacloud.ResourceMonitorRequest {
return &sacloud.ResourceMonitorRequest{}
}