mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
feat(openamt): Configuration of the OpenAMT capability [INT-6] (#6071)
Co-authored-by: Sven Dowideit <sven.dowideit@portainer.io>
This commit is contained in:
parent
ab0849d0f3
commit
47c1af93ea
24 changed files with 1373 additions and 8 deletions
52
api/hostmanagement/openamt/authorization.go
Normal file
52
api/hostmanagement/openamt/authorization.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
type authenticationResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
func (service *Service) executeAuthenticationRequest(configuration portainer.OpenAMTConfiguration) (*authenticationResponse, error) {
|
||||
loginURL := fmt.Sprintf("https://%s/mps/login/api/v1/authorize", configuration.MPSURL)
|
||||
|
||||
payload := map[string]string{
|
||||
"username": configuration.Credentials.MPSUser,
|
||||
"password": configuration.Credentials.MPSPassword,
|
||||
}
|
||||
jsonValue, _ := json.Marshal(payload)
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, loginURL, bytes.NewBuffer(jsonValue))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
response, err := service.httpsClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responseBody, readErr := ioutil.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
return nil, readErr
|
||||
}
|
||||
errorResponse := parseError(responseBody)
|
||||
if errorResponse != nil {
|
||||
return nil, errorResponse
|
||||
}
|
||||
|
||||
var token authenticationResponse
|
||||
err = json.Unmarshal(responseBody, &token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &token, nil
|
||||
}
|
143
api/hostmanagement/openamt/configCIRA.go
Normal file
143
api/hostmanagement/openamt/configCIRA.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
type CIRAConfig struct {
|
||||
ConfigName string `json:"configName"`
|
||||
MPSServerAddress string `json:"mpsServerAddress"`
|
||||
ServerAddressFormat int `json:"serverAddressFormat"`
|
||||
CommonName string `json:"commonName"`
|
||||
MPSPort int `json:"mpsPort"`
|
||||
Username string `json:"username"`
|
||||
MPSRootCertificate string `json:"mpsRootCertificate"`
|
||||
RegeneratePassword bool `json:"regeneratePassword"`
|
||||
AuthMethod int `json:"authMethod"`
|
||||
}
|
||||
|
||||
func (service *Service) createOrUpdateCIRAConfig(configuration portainer.OpenAMTConfiguration, configName string) (*CIRAConfig, error) {
|
||||
ciraConfig, err := service.getCIRAConfig(configuration, configName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
method := http.MethodPost
|
||||
if ciraConfig != nil {
|
||||
method = http.MethodPatch
|
||||
}
|
||||
|
||||
ciraConfig, err = service.saveCIRAConfig(method, configuration, configName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ciraConfig, nil
|
||||
}
|
||||
|
||||
func (service *Service) getCIRAConfig(configuration portainer.OpenAMTConfiguration, configName string) (*CIRAConfig, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/ciraconfigs/%s", configuration.MPSURL, configName)
|
||||
|
||||
responseBody, err := service.executeGetRequest(url, configuration.Credentials.MPSToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if responseBody == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var result CIRAConfig
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (service *Service) saveCIRAConfig(method string, configuration portainer.OpenAMTConfiguration, configName string) (*CIRAConfig, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/ciraconfigs", configuration.MPSURL)
|
||||
|
||||
certificate, err := service.getCIRACertificate(configuration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addressFormat, err := addressFormat(configuration.MPSURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := CIRAConfig{
|
||||
ConfigName: configName,
|
||||
MPSServerAddress: configuration.MPSURL,
|
||||
CommonName: configuration.MPSURL,
|
||||
ServerAddressFormat: addressFormat,
|
||||
MPSPort: 4433,
|
||||
Username: "admin",
|
||||
MPSRootCertificate: certificate,
|
||||
RegeneratePassword: false,
|
||||
AuthMethod: 2,
|
||||
}
|
||||
payload, _ := json.Marshal(config)
|
||||
|
||||
responseBody, err := service.executeSaveRequest(method, url, configuration.Credentials.MPSToken, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result CIRAConfig
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func addressFormat(url string) (int, error) {
|
||||
ip := net.ParseIP(url)
|
||||
if ip == nil {
|
||||
return 201, nil // FQDN
|
||||
}
|
||||
if strings.Contains(url, ".") {
|
||||
return 3, nil // IPV4
|
||||
}
|
||||
if strings.Contains(url, ":") {
|
||||
return 4, nil // IPV6
|
||||
}
|
||||
return 0, fmt.Errorf("could not determine server address format for %s", url)
|
||||
}
|
||||
|
||||
func (service *Service) getCIRACertificate(configuration portainer.OpenAMTConfiguration) (string, error) {
|
||||
loginURL := fmt.Sprintf("https://%s/mps/api/v1/ciracert", configuration.MPSURL)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, loginURL, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", configuration.Credentials.MPSToken))
|
||||
|
||||
response, err := service.httpsClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return "", errors.New(fmt.Sprintf("unexpected status code %s", response.Status))
|
||||
}
|
||||
|
||||
certificate, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
block, _ := pem.Decode(certificate)
|
||||
return base64.StdEncoding.EncodeToString(block.Bytes), nil
|
||||
}
|
81
api/hostmanagement/openamt/configDomain.go
Normal file
81
api/hostmanagement/openamt/configDomain.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
type (
|
||||
Domain struct {
|
||||
DomainName string `json:"profileName"`
|
||||
DomainSuffix string `json:"domainSuffix"`
|
||||
ProvisioningCert string `json:"provisioningCert"`
|
||||
ProvisioningCertPassword string `json:"provisioningCertPassword"`
|
||||
ProvisioningCertStorageFormat string `json:"provisioningCertStorageFormat"`
|
||||
}
|
||||
)
|
||||
|
||||
func (service *Service) createOrUpdateDomain(configuration portainer.OpenAMTConfiguration) (*Domain, error) {
|
||||
domain, err := service.getDomain(configuration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
method := http.MethodPost
|
||||
if domain != nil {
|
||||
method = http.MethodPatch
|
||||
}
|
||||
|
||||
domain, err = service.saveDomain(method, configuration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
func (service *Service) getDomain(configuration portainer.OpenAMTConfiguration) (*Domain, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/domains/%s", configuration.MPSURL, configuration.DomainConfiguration.DomainName)
|
||||
|
||||
responseBody, err := service.executeGetRequest(url, configuration.Credentials.MPSToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if responseBody == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var result Domain
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (service *Service) saveDomain(method string, configuration portainer.OpenAMTConfiguration) (*Domain, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/domains", configuration.MPSURL)
|
||||
|
||||
profile := Domain{
|
||||
DomainName: configuration.DomainConfiguration.DomainName,
|
||||
DomainSuffix: configuration.DomainConfiguration.DomainName,
|
||||
ProvisioningCert: configuration.DomainConfiguration.CertFileText,
|
||||
ProvisioningCertPassword: configuration.DomainConfiguration.CertPassword,
|
||||
ProvisioningCertStorageFormat: "string",
|
||||
}
|
||||
payload, _ := json.Marshal(profile)
|
||||
|
||||
responseBody, err := service.executeSaveRequest(method, url, configuration.Credentials.MPSToken, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result Domain
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
104
api/hostmanagement/openamt/configProfile.go
Normal file
104
api/hostmanagement/openamt/configProfile.go
Normal file
|
@ -0,0 +1,104 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
type (
|
||||
Profile struct {
|
||||
ProfileName string `json:"profileName"`
|
||||
Activation string `json:"activation"`
|
||||
CIRAConfigName *string `json:"ciraConfigName"`
|
||||
GenerateRandomAMTPassword bool `json:"generateRandomPassword"`
|
||||
AMTPassword string `json:"amtPassword"`
|
||||
GenerateRandomMEBxPassword bool `json:"generateRandomMEBxPassword"`
|
||||
MEBXPassword string `json:"mebxPassword"`
|
||||
Tags []string `json:"tags"`
|
||||
DHCPEnabled bool `json:"dhcpEnabled"`
|
||||
TenantId string `json:"tenantId"`
|
||||
WIFIConfigs []ProfileWifiConfig `json:"wifiConfigs"`
|
||||
}
|
||||
|
||||
ProfileWifiConfig struct {
|
||||
Priority int `json:"priority"`
|
||||
ProfileName string `json:"profileName"`
|
||||
}
|
||||
)
|
||||
|
||||
func (service *Service) createOrUpdateAMTProfile(configuration portainer.OpenAMTConfiguration, profileName string, ciraConfigName string, wirelessConfig string) (*Profile, error) {
|
||||
profile, err := service.getAMTProfile(configuration, profileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
method := http.MethodPost
|
||||
if profile != nil {
|
||||
method = http.MethodPatch
|
||||
}
|
||||
|
||||
profile, err = service.saveAMTProfile(method, configuration, profileName, ciraConfigName, wirelessConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func (service *Service) getAMTProfile(configuration portainer.OpenAMTConfiguration, profileName string) (*Profile, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/profiles/%s", configuration.MPSURL, profileName)
|
||||
|
||||
responseBody, err := service.executeGetRequest(url, configuration.Credentials.MPSToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if responseBody == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var result Profile
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (service *Service) saveAMTProfile(method string, configuration portainer.OpenAMTConfiguration, profileName string, ciraConfigName string, wirelessConfig string) (*Profile, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/profiles", configuration.MPSURL)
|
||||
|
||||
profile := Profile{
|
||||
ProfileName: profileName,
|
||||
Activation: "acmactivate",
|
||||
GenerateRandomAMTPassword: false,
|
||||
GenerateRandomMEBxPassword: false,
|
||||
AMTPassword: configuration.Credentials.MPSPassword,
|
||||
MEBXPassword: configuration.Credentials.MPSPassword,
|
||||
CIRAConfigName: &ciraConfigName,
|
||||
Tags: []string{},
|
||||
DHCPEnabled: true,
|
||||
}
|
||||
if wirelessConfig != "" {
|
||||
profile.WIFIConfigs = []ProfileWifiConfig{
|
||||
{
|
||||
Priority: 1,
|
||||
ProfileName: DefaultWirelessConfigName,
|
||||
},
|
||||
}
|
||||
}
|
||||
payload, _ := json.Marshal(profile)
|
||||
|
||||
responseBody, err := service.executeSaveRequest(method, url, configuration.Credentials.MPSToken, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result Profile
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
91
api/hostmanagement/openamt/configWireless.go
Normal file
91
api/hostmanagement/openamt/configWireless.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
type (
|
||||
WirelessProfile struct {
|
||||
ProfileName string `json:"profileName"`
|
||||
AuthenticationMethod int `json:"authenticationMethod"`
|
||||
EncryptionMethod int `json:"encryptionMethod"`
|
||||
SSID string `json:"ssid"`
|
||||
PSKPassphrase string `json:"pskPassphrase"`
|
||||
}
|
||||
)
|
||||
|
||||
func (service *Service) createOrUpdateWirelessConfig(configuration portainer.OpenAMTConfiguration, wirelessConfigName string) (*WirelessProfile, error) {
|
||||
wirelessConfig, err := service.getWirelessConfig(configuration, wirelessConfigName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
method := http.MethodPost
|
||||
if wirelessConfig != nil {
|
||||
method = http.MethodPatch
|
||||
}
|
||||
|
||||
wirelessConfig, err = service.saveWirelessConfig(method, configuration, wirelessConfigName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wirelessConfig, nil
|
||||
}
|
||||
|
||||
func (service *Service) getWirelessConfig(configuration portainer.OpenAMTConfiguration, configName string) (*WirelessProfile, error) {
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/wirelessconfigs/%s", configuration.MPSURL, configName)
|
||||
|
||||
responseBody, err := service.executeGetRequest(url, configuration.Credentials.MPSToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if responseBody == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var result WirelessProfile
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (service *Service) saveWirelessConfig(method string, configuration portainer.OpenAMTConfiguration, configName string) (*WirelessProfile, error) {
|
||||
parsedAuthenticationMethod, err := strconv.Atoi(configuration.WirelessConfiguration.AuthenticationMethod)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing wireless authentication method: %s", err.Error())
|
||||
}
|
||||
parsedEncryptionMethod, err := strconv.Atoi(configuration.WirelessConfiguration.EncryptionMethod)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing wireless encryption method: %s", err.Error())
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s/rps/api/v1/admin/wirelessconfigs", configuration.MPSURL)
|
||||
|
||||
config := WirelessProfile{
|
||||
ProfileName: configName,
|
||||
AuthenticationMethod: parsedAuthenticationMethod,
|
||||
EncryptionMethod: parsedEncryptionMethod,
|
||||
SSID: configuration.WirelessConfiguration.SSID,
|
||||
PSKPassphrase: configuration.WirelessConfiguration.PskPass,
|
||||
}
|
||||
payload, _ := json.Marshal(config)
|
||||
|
||||
responseBody, err := service.executeSaveRequest(method, url, configuration.Credentials.MPSToken, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result WirelessProfile
|
||||
err = json.Unmarshal(responseBody, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
157
api/hostmanagement/openamt/openamt.go
Normal file
157
api/hostmanagement/openamt/openamt.go
Normal file
|
@ -0,0 +1,157 @@
|
|||
package openamt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultCIRAConfigName = "ciraConfigDefault"
|
||||
DefaultWirelessConfigName = "wirelessProfileDefault"
|
||||
DefaultProfileName = "profileAMTDefault"
|
||||
)
|
||||
|
||||
// Service represents a service for managing an OpenAMT server.
|
||||
type Service struct {
|
||||
httpsClient *http.Client
|
||||
}
|
||||
|
||||
// NewService initializes a new service.
|
||||
func NewService(dataStore portainer.DataStore) *Service {
|
||||
if !dataStore.Settings().IsFeatureFlagEnabled(portainer.FeatOpenAMT) {
|
||||
return nil
|
||||
}
|
||||
return &Service{
|
||||
httpsClient: &http.Client{
|
||||
Timeout: time.Second * time.Duration(5),
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type openAMTError struct {
|
||||
ErrorMsg string `json:"message"`
|
||||
Errors []struct {
|
||||
ErrorMsg string `json:"msg"`
|
||||
} `json:"errors"`
|
||||
}
|
||||
|
||||
func parseError(responseBody []byte) error {
|
||||
var errorResponse openAMTError
|
||||
err := json.Unmarshal(responseBody, &errorResponse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(errorResponse.Errors) > 0 {
|
||||
return errors.New(errorResponse.Errors[0].ErrorMsg)
|
||||
}
|
||||
if errorResponse.ErrorMsg != "" {
|
||||
return errors.New(errorResponse.ErrorMsg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *Service) ConfigureDefault(configuration portainer.OpenAMTConfiguration) error {
|
||||
token, err := service.executeAuthenticationRequest(configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configuration.Credentials.MPSToken = token.Token
|
||||
|
||||
ciraConfig, err := service.createOrUpdateCIRAConfig(configuration, DefaultCIRAConfigName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wirelessConfigName := ""
|
||||
if configuration.WirelessConfiguration != nil {
|
||||
wirelessConfig, err := service.createOrUpdateWirelessConfig(configuration, DefaultWirelessConfigName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wirelessConfigName = wirelessConfig.ProfileName
|
||||
}
|
||||
|
||||
_, err = service.createOrUpdateAMTProfile(configuration, DefaultProfileName, ciraConfig.ConfigName, wirelessConfigName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = service.createOrUpdateDomain(configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *Service) executeSaveRequest(method string, url string, token string, payload []byte) ([]byte, error) {
|
||||
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
|
||||
response, err := service.httpsClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responseBody, readErr := ioutil.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
return nil, readErr
|
||||
}
|
||||
|
||||
if response.StatusCode < 200 || response.StatusCode > 300 {
|
||||
errorResponse := parseError(responseBody)
|
||||
if errorResponse != nil {
|
||||
return nil, errorResponse
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("unexpected status code %s", response.Status))
|
||||
}
|
||||
|
||||
return responseBody, nil
|
||||
}
|
||||
|
||||
func (service *Service) executeGetRequest(url string, token string) ([]byte, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
|
||||
response, err := service.httpsClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responseBody, readErr := ioutil.ReadAll(response.Body)
|
||||
if readErr != nil {
|
||||
return nil, readErr
|
||||
}
|
||||
|
||||
if response.StatusCode < 200 || response.StatusCode > 300 {
|
||||
if response.StatusCode == http.StatusNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
errorResponse := parseError(responseBody)
|
||||
if errorResponse != nil {
|
||||
return nil, errorResponse
|
||||
}
|
||||
return nil, errors.New(fmt.Sprintf("unexpected status code %s", response.Status))
|
||||
}
|
||||
|
||||
return responseBody, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue