mirror of https://github.com/portainer/portainer
				
				
				
			
		
			
				
	
	
		
			147 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
package openamt
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/base64"
 | 
						|
	"encoding/pem"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"net"
 | 
						|
	"net/http"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	portainer "github.com/portainer/portainer/api"
 | 
						|
 | 
						|
	"github.com/segmentio/encoding/json"
 | 
						|
)
 | 
						|
 | 
						|
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.MPSServer, configName)
 | 
						|
 | 
						|
	responseBody, err := service.executeGetRequest(url, configuration.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.MPSServer)
 | 
						|
 | 
						|
	certificate, err := service.getCIRACertificate(configuration)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	addressFormat, err := addressFormat(configuration.MPSServer)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	config := CIRAConfig{
 | 
						|
		ConfigName:          configName,
 | 
						|
		MPSServerAddress:    configuration.MPSServer,
 | 
						|
		CommonName:          configuration.MPSServer,
 | 
						|
		ServerAddressFormat: addressFormat,
 | 
						|
		MPSPort:             4433,
 | 
						|
		Username:            "admin",
 | 
						|
		MPSRootCertificate:  certificate,
 | 
						|
		RegeneratePassword:  false,
 | 
						|
		AuthMethod:          2,
 | 
						|
	}
 | 
						|
	payload, _ := json.Marshal(config)
 | 
						|
 | 
						|
	responseBody, err := service.executeSaveRequest(method, url, configuration.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.MPSServer)
 | 
						|
 | 
						|
	req, err := http.NewRequest(http.MethodGet, loginURL, nil)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	req.Header.Set("Authorization", "Bearer "+configuration.MPSToken)
 | 
						|
 | 
						|
	response, err := service.httpsClient.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	defer response.Body.Close()
 | 
						|
 | 
						|
	if response.StatusCode != http.StatusOK {
 | 
						|
		return "", fmt.Errorf("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
 | 
						|
}
 |