mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-31 15:29:48 +02:00
Update import api and environment detection
This commit is contained in:
parent
bf4c2beba8
commit
5a53c6304c
7 changed files with 178 additions and 320 deletions
|
@ -121,7 +121,7 @@ func (api *API) GetClusterResourceBundles(ctx context.Context) (*cluster_api.Get
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) ImportConfig(ctx context.Context, cfg *configpb.Config) (*cluster_api.ImportResponse, error) {
|
func (api *API) ImportConfig(ctx context.Context, cfg *configpb.Config, params *cluster_api.ImportConfigurationParams) (*cluster_api.ImportResponse, error) {
|
||||||
data, err := proto.Marshal(cfg)
|
data, err := proto.Marshal(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -139,15 +139,12 @@ func (api *API) ImportConfig(ctx context.Context, cfg *configpb.Config) (*cluste
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return apierror.CheckResponse(api.cluster.ImportConfigurationWithBodyWithResponse(ctx,
|
return apierror.CheckResponse(api.cluster.ImportConfigurationWithBodyWithResponse(ctx,
|
||||||
|
params,
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
&compressedData,
|
&compressedData,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) GetQuotas(ctx context.Context) (*cluster_api.ConfigQuotas, error) {
|
|
||||||
return apierror.CheckResponse(api.cluster.GetQuotasWithResponse(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetTelemetryConn() *grpc.ClientConn {
|
func (api *API) GetTelemetryConn() *grpc.ClientConn {
|
||||||
return api.telemetryConn
|
return api.telemetryConn
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,17 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy/files"
|
"github.com/pomerium/pomerium/pkg/envoy/files"
|
||||||
|
"github.com/pomerium/pomerium/pkg/zero/cluster"
|
||||||
"github.com/pomerium/pomerium/pkg/zero/importutil"
|
"github.com/pomerium/pomerium/pkg/zero/importutil"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -24,40 +28,9 @@ func BuildImportCmd() *cobra.Command {
|
||||||
if configFlag != nil {
|
if configFlag != nil {
|
||||||
configFile = configFlag.Value.String()
|
configFile = configFlag.Value.String()
|
||||||
}
|
}
|
||||||
|
envInfo := findEnvironmentInfo()
|
||||||
if configFile == "" {
|
if configFile == "" {
|
||||||
// try looking up what pid 1 is using, we are likely in a container anyway
|
configFile = envInfo.ConfigArg
|
||||||
info, err := os.ReadFile("/proc/1/cmdline")
|
|
||||||
if err == nil {
|
|
||||||
args := bytes.Split(info, []byte{0})
|
|
||||||
if len(args) > 0 && strings.Contains(string(args[0]), "pomerium") {
|
|
||||||
for i, arg := range args {
|
|
||||||
if strings.Contains(string(arg), "-config") {
|
|
||||||
if strings.Contains(string(arg), "-config=") {
|
|
||||||
configFile = strings.Split(string(arg), "=")[1]
|
|
||||||
cmd.PrintErrf("detected config file: %s\n", configFile)
|
|
||||||
} else if len(args) > i+1 {
|
|
||||||
configFile = string(args[i+1])
|
|
||||||
cmd.PrintErrf("detected config file: %s\n", configFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try some common locations
|
|
||||||
if configFile == "" {
|
|
||||||
if _, err := os.Stat("/pomerium/config.yaml"); err == nil {
|
|
||||||
configFile = "/pomerium/config.yaml"
|
|
||||||
} else if _, err := os.Stat("/etc/pomerium/config.yaml"); err == nil {
|
|
||||||
configFile = "/etc/pomerium/config.yaml"
|
|
||||||
} else if _, err := os.Stat("config.yaml"); err == nil {
|
|
||||||
configFile = "config.yaml"
|
|
||||||
}
|
|
||||||
|
|
||||||
if configFile != "" {
|
|
||||||
cmd.PrintErrf("detected config file: %s\n", configFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if configFile == "" {
|
if configFile == "" {
|
||||||
return fmt.Errorf("no config file provided")
|
return fmt.Errorf("no config file provided")
|
||||||
|
@ -74,7 +47,20 @@ func BuildImportCmd() *cobra.Command {
|
||||||
for i, name := range importutil.GenerateRouteNames(converted.Routes) {
|
for i, name := range importutil.GenerateRouteNames(converted.Routes) {
|
||||||
converted.Routes[i].Name = name
|
converted.Routes[i].Name = name
|
||||||
}
|
}
|
||||||
resp, err := client.ImportConfig(cmd.Context(), converted)
|
var params cluster.ImportConfigurationParams
|
||||||
|
if data, err := json.Marshal(envInfo); err == nil {
|
||||||
|
hints := make(map[string]string)
|
||||||
|
if err := json.Unmarshal(data, &hints); err == nil {
|
||||||
|
pairs := []string{}
|
||||||
|
for key, value := range hints {
|
||||||
|
pairs = append(pairs, fmt.Sprintf("%s=%s", key, value))
|
||||||
|
}
|
||||||
|
if len(pairs) > 0 {
|
||||||
|
params.XImportHints = &pairs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp, err := client.ImportConfig(cmd.Context(), converted, ¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error importing config: %w", err)
|
return fmt.Errorf("error importing config: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -94,3 +80,97 @@ func BuildImportCmd() *cobra.Command {
|
||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type environmentInfo struct {
|
||||||
|
SystemType string `json:"systemType,omitempty"`
|
||||||
|
Hostname string `json:"hostname,omitempty"`
|
||||||
|
KubernetesNamespace string `json:"kubernetesNamespace,omitempty"`
|
||||||
|
Argv0 string `json:"argv0,omitempty"`
|
||||||
|
ConfigArg string `json:"configArg,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func findEnvironmentInfo() environmentInfo {
|
||||||
|
var info environmentInfo
|
||||||
|
if isKubernetes() {
|
||||||
|
info.SystemType = "kubernetes"
|
||||||
|
// search for downward api environment variables to see if we can determine
|
||||||
|
// the current namespace (adds '-n <namespace>' to the command given in the
|
||||||
|
// zero ui for users to copy/paste)
|
||||||
|
for _, env := range []string{
|
||||||
|
"POMERIUM_NAMESPACE", // the name we use in our official manifests
|
||||||
|
"POD_NAMESPACE", // very common alternative name
|
||||||
|
} {
|
||||||
|
if v, ok := os.LookupEnv(env); ok {
|
||||||
|
info.KubernetesNamespace = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if isDocker() {
|
||||||
|
info.SystemType = "docker"
|
||||||
|
} else {
|
||||||
|
info.SystemType = "linux"
|
||||||
|
info.Argv0 = os.Args[0]
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
info.Hostname, _ = os.Hostname()
|
||||||
|
|
||||||
|
pid, ok := findPomeriumPid()
|
||||||
|
if !ok {
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
|
||||||
|
if err != nil {
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
args := bytes.Split(cmdline, []byte{0})
|
||||||
|
if len(args) > 0 {
|
||||||
|
info.Argv0 = string(args[0])
|
||||||
|
}
|
||||||
|
for i, arg := range args {
|
||||||
|
if strings.Contains(string(arg), "-config") {
|
||||||
|
if strings.Contains(string(arg), "-config=") {
|
||||||
|
info.ConfigArg = strings.Split(string(arg), "=")[1]
|
||||||
|
} else if len(args) > i+1 {
|
||||||
|
info.ConfigArg = string(args[i+1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
func isKubernetes() bool {
|
||||||
|
return os.Getenv("KUBERNETES_SERVICE_HOST") != "" && os.Getenv("KUBERNETES_SERVICE_PORT") != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func isDocker() bool {
|
||||||
|
_, err := os.Stat("/.dockerenv")
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findPomeriumPid() (int, bool) {
|
||||||
|
pid1Argv0 := getProcessArgv0(1)
|
||||||
|
if path.Base(pid1Argv0) == "pomerium" {
|
||||||
|
return 1, true
|
||||||
|
}
|
||||||
|
|
||||||
|
pidList, err := os.ReadFile("/proc/1/task/1/children")
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
for _, pidStr := range strings.Fields(string(pidList)) {
|
||||||
|
pid, _ := strconv.Atoi(pidStr)
|
||||||
|
if path.Base(getProcessArgv0(pid)) == "pomerium" {
|
||||||
|
return pid, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProcessArgv0(pid int) string {
|
||||||
|
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
argv0, _, _ := bytes.Cut(cmdline, []byte{0})
|
||||||
|
return string(argv0)
|
||||||
|
}
|
||||||
|
|
|
@ -104,10 +104,7 @@ type ClientInterface interface {
|
||||||
ReportClusterResourceBundleStatus(ctx context.Context, bundleId BundleId, body ReportClusterResourceBundleStatusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
ReportClusterResourceBundleStatus(ctx context.Context, bundleId BundleId, body ReportClusterResourceBundleStatusJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
// ImportConfigurationWithBody request with any body
|
// ImportConfigurationWithBody request with any body
|
||||||
ImportConfigurationWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
ImportConfigurationWithBody(ctx context.Context, params *ImportConfigurationParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
|
||||||
// GetQuotas request
|
|
||||||
GetQuotas(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
// ExchangeClusterIdentityTokenWithBody request with any body
|
// ExchangeClusterIdentityTokenWithBody request with any body
|
||||||
ExchangeClusterIdentityTokenWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
ExchangeClusterIdentityTokenWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||||
|
@ -180,20 +177,8 @@ func (c *Client) ReportClusterResourceBundleStatus(ctx context.Context, bundleId
|
||||||
return c.Client.Do(req)
|
return c.Client.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ImportConfigurationWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
func (c *Client) ImportConfigurationWithBody(ctx context.Context, params *ImportConfigurationParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||||
req, err := NewImportConfigurationRequestWithBody(c.Server, contentType, body)
|
req, err := NewImportConfigurationRequestWithBody(c.Server, params, contentType, body)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) GetQuotas(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewGetQuotasRequest(c.Server)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -388,7 +373,7 @@ func NewReportClusterResourceBundleStatusRequestWithBody(server string, bundleId
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImportConfigurationRequestWithBody generates requests for ImportConfiguration with any type of body
|
// NewImportConfigurationRequestWithBody generates requests for ImportConfiguration with any type of body
|
||||||
func NewImportConfigurationRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {
|
func NewImportConfigurationRequestWithBody(server string, params *ImportConfigurationParams, contentType string, body io.Reader) (*http.Request, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
serverURL, err := url.Parse(server)
|
||||||
|
@ -413,31 +398,19 @@ func NewImportConfigurationRequestWithBody(server string, contentType string, bo
|
||||||
|
|
||||||
req.Header.Add("Content-Type", contentType)
|
req.Header.Add("Content-Type", contentType)
|
||||||
|
|
||||||
return req, nil
|
if params != nil {
|
||||||
}
|
|
||||||
|
|
||||||
// NewGetQuotasRequest generates requests for GetQuotas
|
if params.XImportHints != nil {
|
||||||
func NewGetQuotasRequest(server string) (*http.Request, error) {
|
var headerParam0 string
|
||||||
var err error
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
headerParam0, err = runtime.StyleParamWithLocation("simple", true, "X-Import-Hints", runtime.ParamLocationHeader, *params.XImportHints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
operationPath := fmt.Sprintf("/config/quotas")
|
req.Header.Set("X-Import-Hints", headerParam0)
|
||||||
if operationPath[0] == '/' {
|
}
|
||||||
operationPath = "." + operationPath
|
|
||||||
}
|
|
||||||
|
|
||||||
queryURL, err := serverURL.Parse(operationPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", queryURL.String(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return req, nil
|
return req, nil
|
||||||
|
@ -581,10 +554,7 @@ type ClientWithResponsesInterface interface {
|
||||||
ReportClusterResourceBundleStatusWithResponse(ctx context.Context, bundleId BundleId, body ReportClusterResourceBundleStatusJSONRequestBody, reqEditors ...RequestEditorFn) (*ReportClusterResourceBundleStatusResp, error)
|
ReportClusterResourceBundleStatusWithResponse(ctx context.Context, bundleId BundleId, body ReportClusterResourceBundleStatusJSONRequestBody, reqEditors ...RequestEditorFn) (*ReportClusterResourceBundleStatusResp, error)
|
||||||
|
|
||||||
// ImportConfigurationWithBodyWithResponse request with any body
|
// ImportConfigurationWithBodyWithResponse request with any body
|
||||||
ImportConfigurationWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ImportConfigurationResp, error)
|
ImportConfigurationWithBodyWithResponse(ctx context.Context, params *ImportConfigurationParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ImportConfigurationResp, error)
|
||||||
|
|
||||||
// GetQuotasWithResponse request
|
|
||||||
GetQuotasWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetQuotasResp, error)
|
|
||||||
|
|
||||||
// ExchangeClusterIdentityTokenWithBodyWithResponse request with any body
|
// ExchangeClusterIdentityTokenWithBodyWithResponse request with any body
|
||||||
ExchangeClusterIdentityTokenWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error)
|
ExchangeClusterIdentityTokenWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error)
|
||||||
|
@ -719,30 +689,6 @@ func (r ImportConfigurationResp) StatusCode() int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetQuotasResp struct {
|
|
||||||
Body []byte
|
|
||||||
HTTPResponse *http.Response
|
|
||||||
JSON200 *ConfigQuotas
|
|
||||||
JSON400 *ErrorResponse
|
|
||||||
JSON500 *ErrorResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns HTTPResponse.Status
|
|
||||||
func (r GetQuotasResp) Status() string {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.Status
|
|
||||||
}
|
|
||||||
return http.StatusText(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns HTTPResponse.StatusCode
|
|
||||||
func (r GetQuotasResp) StatusCode() int {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.StatusCode
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExchangeClusterIdentityTokenResp struct {
|
type ExchangeClusterIdentityTokenResp struct {
|
||||||
Body []byte
|
Body []byte
|
||||||
HTTPResponse *http.Response
|
HTTPResponse *http.Response
|
||||||
|
@ -835,23 +781,14 @@ func (c *ClientWithResponses) ReportClusterResourceBundleStatusWithResponse(ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportConfigurationWithBodyWithResponse request with arbitrary body returning *ImportConfigurationResp
|
// ImportConfigurationWithBodyWithResponse request with arbitrary body returning *ImportConfigurationResp
|
||||||
func (c *ClientWithResponses) ImportConfigurationWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ImportConfigurationResp, error) {
|
func (c *ClientWithResponses) ImportConfigurationWithBodyWithResponse(ctx context.Context, params *ImportConfigurationParams, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ImportConfigurationResp, error) {
|
||||||
rsp, err := c.ImportConfigurationWithBody(ctx, contentType, body, reqEditors...)
|
rsp, err := c.ImportConfigurationWithBody(ctx, params, contentType, body, reqEditors...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return ParseImportConfigurationResp(rsp)
|
return ParseImportConfigurationResp(rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetQuotasWithResponse request returning *GetQuotasResp
|
|
||||||
func (c *ClientWithResponses) GetQuotasWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetQuotasResp, error) {
|
|
||||||
rsp, err := c.GetQuotas(ctx, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseGetQuotasResp(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExchangeClusterIdentityTokenWithBodyWithResponse request with arbitrary body returning *ExchangeClusterIdentityTokenResp
|
// ExchangeClusterIdentityTokenWithBodyWithResponse request with arbitrary body returning *ExchangeClusterIdentityTokenResp
|
||||||
func (c *ClientWithResponses) ExchangeClusterIdentityTokenWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error) {
|
func (c *ClientWithResponses) ExchangeClusterIdentityTokenWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error) {
|
||||||
rsp, err := c.ExchangeClusterIdentityTokenWithBody(ctx, contentType, body, reqEditors...)
|
rsp, err := c.ExchangeClusterIdentityTokenWithBody(ctx, contentType, body, reqEditors...)
|
||||||
|
@ -1100,46 +1037,6 @@ func ParseImportConfigurationResp(rsp *http.Response) (*ImportConfigurationResp,
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseGetQuotasResp parses an HTTP response from a GetQuotasWithResponse call
|
|
||||||
func ParseGetQuotasResp(rsp *http.Response) (*GetQuotasResp, error) {
|
|
||||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
|
||||||
defer func() { _ = rsp.Body.Close() }()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &GetQuotasResp{
|
|
||||||
Body: bodyBytes,
|
|
||||||
HTTPResponse: rsp,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
|
||||||
var dest ConfigQuotas
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON200 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400:
|
|
||||||
var dest ErrorResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON400 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
|
||||||
var dest ErrorResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON500 = &dest
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseExchangeClusterIdentityTokenResp parses an HTTP response from a ExchangeClusterIdentityTokenWithResponse call
|
// ParseExchangeClusterIdentityTokenResp parses an HTTP response from a ExchangeClusterIdentityTokenWithResponse call
|
||||||
func ParseExchangeClusterIdentityTokenResp(rsp *http.Response) (*ExchangeClusterIdentityTokenResp, error) {
|
func ParseExchangeClusterIdentityTokenResp(rsp *http.Response) (*ExchangeClusterIdentityTokenResp, error) {
|
||||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||||
|
@ -1360,32 +1257,6 @@ func (r *ImportConfigurationResp) GetInternalServerError() (string, bool) {
|
||||||
return r.JSON500.Error, true
|
return r.JSON500.Error, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHTTPResponse implements apierror.APIResponse
|
|
||||||
func (r *GetQuotasResp) GetHTTPResponse() *http.Response {
|
|
||||||
return r.HTTPResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetValue implements apierror.APIResponse
|
|
||||||
func (r *GetQuotasResp) GetValue() *ConfigQuotas {
|
|
||||||
return r.JSON200
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBadRequestError implements apierror.APIResponse
|
|
||||||
func (r *GetQuotasResp) GetBadRequestError() (string, bool) {
|
|
||||||
if r.JSON400 == nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
return r.JSON400.Error, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInternalServerError implements apierror.APIResponse
|
|
||||||
func (r *GetQuotasResp) GetInternalServerError() (string, bool) {
|
|
||||||
if r.JSON500 == nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
return r.JSON500.Error, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHTTPResponse implements apierror.APIResponse
|
// GetHTTPResponse implements apierror.APIResponse
|
||||||
func (r *ExchangeClusterIdentityTokenResp) GetHTTPResponse() *http.Response {
|
func (r *ExchangeClusterIdentityTokenResp) GetHTTPResponse() *http.Response {
|
||||||
return r.HTTPResponse
|
return r.HTTPResponse
|
||||||
|
|
|
@ -14,5 +14,4 @@ var (
|
||||||
_ apierror.APIResponse[DownloadBundleResponse] = (*DownloadClusterResourceBundleResp)(nil)
|
_ apierror.APIResponse[DownloadBundleResponse] = (*DownloadClusterResourceBundleResp)(nil)
|
||||||
_ apierror.APIResponse[EmptyResponse] = (*ReportClusterResourceBundleStatusResp)(nil)
|
_ apierror.APIResponse[EmptyResponse] = (*ReportClusterResourceBundleStatusResp)(nil)
|
||||||
_ apierror.APIResponse[ImportResponse] = (*ImportConfigurationResp)(nil)
|
_ apierror.APIResponse[ImportResponse] = (*ImportConfigurationResp)(nil)
|
||||||
_ apierror.APIResponse[ConfigQuotas] = (*GetQuotasResp)(nil)
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -62,13 +62,6 @@ type BundleStatusSuccess struct {
|
||||||
Metadata map[string]string `json:"metadata"`
|
Metadata map[string]string `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigQuotas defines model for ConfigQuotas.
|
|
||||||
type ConfigQuotas struct {
|
|
||||||
Certificates int `json:"certificates"`
|
|
||||||
Policies int `json:"policies"`
|
|
||||||
Routes int `json:"routes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DownloadBundleResponse defines model for DownloadBundleResponse.
|
// DownloadBundleResponse defines model for DownloadBundleResponse.
|
||||||
type DownloadBundleResponse struct {
|
type DownloadBundleResponse struct {
|
||||||
// CaptureMetadataHeaders bundle metadata that need be picked up by the client from the download URL
|
// CaptureMetadataHeaders bundle metadata that need be picked up by the client from the download URL
|
||||||
|
@ -128,6 +121,11 @@ type ReportUsageUser struct {
|
||||||
// BundleId defines model for bundleId.
|
// BundleId defines model for bundleId.
|
||||||
type BundleId = string
|
type BundleId = string
|
||||||
|
|
||||||
|
// ImportConfigurationParams defines parameters for ImportConfiguration.
|
||||||
|
type ImportConfigurationParams struct {
|
||||||
|
XImportHints *[]string `json:"X-Import-Hints,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ReportClusterResourceBundleStatusJSONRequestBody defines body for ReportClusterResourceBundleStatus for application/json ContentType.
|
// ReportClusterResourceBundleStatusJSONRequestBody defines body for ReportClusterResourceBundleStatus for application/json ContentType.
|
||||||
type ReportClusterResourceBundleStatusJSONRequestBody = BundleStatus
|
type ReportClusterResourceBundleStatusJSONRequestBody = BundleStatus
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,15 @@ paths:
|
||||||
for the first time.
|
for the first time.
|
||||||
operationId: importConfiguration
|
operationId: importConfiguration
|
||||||
tags: [cluster]
|
tags: [cluster]
|
||||||
|
parameters:
|
||||||
|
- in: header
|
||||||
|
name: X-Import-Hints
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
explode: true
|
||||||
requestBody:
|
requestBody:
|
||||||
required: true
|
required: true
|
||||||
content:
|
content:
|
||||||
|
@ -191,7 +200,7 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
contentMediaType: application/octet-stream
|
contentMediaType: application/octet-stream
|
||||||
contentEncoding: gzip
|
contentEncoding: zstd
|
||||||
description: type.googleapis.com/pomerium.config.Config
|
description: type.googleapis.com/pomerium.config.Config
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
|
@ -224,29 +233,6 @@ paths:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/ErrorResponse"
|
$ref: "#/components/schemas/ErrorResponse"
|
||||||
/config/quotas:
|
|
||||||
get:
|
|
||||||
description: Get the cluster's current configuration quotas
|
|
||||||
operationId: getQuotas
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/ConfigQuotas"
|
|
||||||
"400":
|
|
||||||
description: Bad Request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/ErrorResponse"
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/ErrorResponse"
|
|
||||||
components:
|
components:
|
||||||
parameters:
|
parameters:
|
||||||
bundleId:
|
bundleId:
|
||||||
|
@ -415,16 +401,3 @@ components:
|
||||||
- lastSignedInAt
|
- lastSignedInAt
|
||||||
- pseudonymousEmail
|
- pseudonymousEmail
|
||||||
- pseudonymousId
|
- pseudonymousId
|
||||||
ConfigQuotas:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
certificates:
|
|
||||||
type: integer
|
|
||||||
policies:
|
|
||||||
type: integer
|
|
||||||
routes:
|
|
||||||
type: integer
|
|
||||||
required:
|
|
||||||
- certificates
|
|
||||||
- policies
|
|
||||||
- routes
|
|
||||||
|
|
|
@ -31,10 +31,7 @@ type ServerInterface interface {
|
||||||
ReportClusterResourceBundleStatus(w http.ResponseWriter, r *http.Request, bundleId BundleId)
|
ReportClusterResourceBundleStatus(w http.ResponseWriter, r *http.Request, bundleId BundleId)
|
||||||
|
|
||||||
// (PUT /config/import)
|
// (PUT /config/import)
|
||||||
ImportConfiguration(w http.ResponseWriter, r *http.Request)
|
ImportConfiguration(w http.ResponseWriter, r *http.Request, params ImportConfigurationParams)
|
||||||
|
|
||||||
// (GET /config/quotas)
|
|
||||||
GetQuotas(w http.ResponseWriter, r *http.Request)
|
|
||||||
|
|
||||||
// (POST /exchangeToken)
|
// (POST /exchangeToken)
|
||||||
ExchangeClusterIdentityToken(w http.ResponseWriter, r *http.Request)
|
ExchangeClusterIdentityToken(w http.ResponseWriter, r *http.Request)
|
||||||
|
@ -68,12 +65,7 @@ func (_ Unimplemented) ReportClusterResourceBundleStatus(w http.ResponseWriter,
|
||||||
}
|
}
|
||||||
|
|
||||||
// (PUT /config/import)
|
// (PUT /config/import)
|
||||||
func (_ Unimplemented) ImportConfiguration(w http.ResponseWriter, r *http.Request) {
|
func (_ Unimplemented) ImportConfiguration(w http.ResponseWriter, r *http.Request, params ImportConfigurationParams) {
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
// (GET /config/quotas)
|
|
||||||
func (_ Unimplemented) GetQuotas(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
w.WriteHeader(http.StatusNotImplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,27 +182,36 @@ func (siw *ServerInterfaceWrapper) ReportClusterResourceBundleStatus(w http.Resp
|
||||||
func (siw *ServerInterfaceWrapper) ImportConfiguration(w http.ResponseWriter, r *http.Request) {
|
func (siw *ServerInterfaceWrapper) ImportConfiguration(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
||||||
|
|
||||||
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
// Parameter object where we will unmarshal all parameters from the context
|
||||||
siw.Handler.ImportConfiguration(w, r)
|
var params ImportConfigurationParams
|
||||||
}))
|
|
||||||
|
headers := r.Header
|
||||||
|
|
||||||
|
// ------------- Optional header parameter "X-Import-Hints" -------------
|
||||||
|
if valueList, found := headers[http.CanonicalHeaderKey("X-Import-Hints")]; found {
|
||||||
|
var XImportHints []string
|
||||||
|
n := len(valueList)
|
||||||
|
if n != 1 {
|
||||||
|
siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Import-Hints", Count: n})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = runtime.BindStyledParameterWithOptions("simple", "X-Import-Hints", valueList[0], &XImportHints, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: true, Required: false})
|
||||||
|
if err != nil {
|
||||||
|
siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "X-Import-Hints", Err: err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
params.XImportHints = &XImportHints
|
||||||
|
|
||||||
for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
|
|
||||||
handler = siw.HandlerMiddlewares[i](handler)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.ServeHTTP(w, r.WithContext(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetQuotas operation middleware
|
|
||||||
func (siw *ServerInterfaceWrapper) GetQuotas(w http.ResponseWriter, r *http.Request) {
|
|
||||||
ctx := r.Context()
|
|
||||||
|
|
||||||
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
|
||||||
|
|
||||||
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
siw.Handler.GetQuotas(w, r)
|
siw.Handler.ImportConfiguration(w, r, params)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
|
for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
|
||||||
|
@ -380,9 +381,6 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Put(options.BaseURL+"/config/import", wrapper.ImportConfiguration)
|
r.Put(options.BaseURL+"/config/import", wrapper.ImportConfiguration)
|
||||||
})
|
})
|
||||||
r.Group(func(r chi.Router) {
|
|
||||||
r.Get(options.BaseURL+"/config/quotas", wrapper.GetQuotas)
|
|
||||||
})
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Post(options.BaseURL+"/exchangeToken", wrapper.ExchangeClusterIdentityToken)
|
r.Post(options.BaseURL+"/exchangeToken", wrapper.ExchangeClusterIdentityToken)
|
||||||
})
|
})
|
||||||
|
@ -541,7 +539,8 @@ func (response ReportClusterResourceBundleStatus500JSONResponse) VisitReportClus
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImportConfigurationRequestObject struct {
|
type ImportConfigurationRequestObject struct {
|
||||||
Body io.Reader
|
Params ImportConfigurationParams
|
||||||
|
Body io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImportConfigurationResponseObject interface {
|
type ImportConfigurationResponseObject interface {
|
||||||
|
@ -593,40 +592,6 @@ func (response ImportConfiguration500JSONResponse) VisitImportConfigurationRespo
|
||||||
return json.NewEncoder(w).Encode(response)
|
return json.NewEncoder(w).Encode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetQuotasRequestObject struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetQuotasResponseObject interface {
|
|
||||||
VisitGetQuotasResponse(w http.ResponseWriter) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetQuotas200JSONResponse ConfigQuotas
|
|
||||||
|
|
||||||
func (response GetQuotas200JSONResponse) VisitGetQuotasResponse(w http.ResponseWriter) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(200)
|
|
||||||
|
|
||||||
return json.NewEncoder(w).Encode(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetQuotas400JSONResponse ErrorResponse
|
|
||||||
|
|
||||||
func (response GetQuotas400JSONResponse) VisitGetQuotasResponse(w http.ResponseWriter) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(400)
|
|
||||||
|
|
||||||
return json.NewEncoder(w).Encode(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetQuotas500JSONResponse ErrorResponse
|
|
||||||
|
|
||||||
func (response GetQuotas500JSONResponse) VisitGetQuotasResponse(w http.ResponseWriter) error {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.WriteHeader(500)
|
|
||||||
|
|
||||||
return json.NewEncoder(w).Encode(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExchangeClusterIdentityTokenRequestObject struct {
|
type ExchangeClusterIdentityTokenRequestObject struct {
|
||||||
Body *ExchangeClusterIdentityTokenJSONRequestBody
|
Body *ExchangeClusterIdentityTokenJSONRequestBody
|
||||||
}
|
}
|
||||||
|
@ -714,9 +679,6 @@ type StrictServerInterface interface {
|
||||||
// (PUT /config/import)
|
// (PUT /config/import)
|
||||||
ImportConfiguration(ctx context.Context, request ImportConfigurationRequestObject) (ImportConfigurationResponseObject, error)
|
ImportConfiguration(ctx context.Context, request ImportConfigurationRequestObject) (ImportConfigurationResponseObject, error)
|
||||||
|
|
||||||
// (GET /config/quotas)
|
|
||||||
GetQuotas(ctx context.Context, request GetQuotasRequestObject) (GetQuotasResponseObject, error)
|
|
||||||
|
|
||||||
// (POST /exchangeToken)
|
// (POST /exchangeToken)
|
||||||
ExchangeClusterIdentityToken(ctx context.Context, request ExchangeClusterIdentityTokenRequestObject) (ExchangeClusterIdentityTokenResponseObject, error)
|
ExchangeClusterIdentityToken(ctx context.Context, request ExchangeClusterIdentityTokenRequestObject) (ExchangeClusterIdentityTokenResponseObject, error)
|
||||||
|
|
||||||
|
@ -861,9 +823,11 @@ func (sh *strictHandler) ReportClusterResourceBundleStatus(w http.ResponseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportConfiguration operation middleware
|
// ImportConfiguration operation middleware
|
||||||
func (sh *strictHandler) ImportConfiguration(w http.ResponseWriter, r *http.Request) {
|
func (sh *strictHandler) ImportConfiguration(w http.ResponseWriter, r *http.Request, params ImportConfigurationParams) {
|
||||||
var request ImportConfigurationRequestObject
|
var request ImportConfigurationRequestObject
|
||||||
|
|
||||||
|
request.Params = params
|
||||||
|
|
||||||
request.Body = r.Body
|
request.Body = r.Body
|
||||||
|
|
||||||
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
||||||
|
@ -886,30 +850,6 @@ func (sh *strictHandler) ImportConfiguration(w http.ResponseWriter, r *http.Requ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetQuotas operation middleware
|
|
||||||
func (sh *strictHandler) GetQuotas(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var request GetQuotasRequestObject
|
|
||||||
|
|
||||||
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
|
||||||
return sh.ssi.GetQuotas(ctx, request.(GetQuotasRequestObject))
|
|
||||||
}
|
|
||||||
for _, middleware := range sh.middlewares {
|
|
||||||
handler = middleware(handler, "GetQuotas")
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := handler(r.Context(), w, r, request)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
|
||||||
} else if validResponse, ok := response.(GetQuotasResponseObject); ok {
|
|
||||||
if err := validResponse.VisitGetQuotasResponse(w); err != nil {
|
|
||||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
|
||||||
}
|
|
||||||
} else if response != nil {
|
|
||||||
sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExchangeClusterIdentityToken operation middleware
|
// ExchangeClusterIdentityToken operation middleware
|
||||||
func (sh *strictHandler) ExchangeClusterIdentityToken(w http.ResponseWriter, r *http.Request) {
|
func (sh *strictHandler) ExchangeClusterIdentityToken(w http.ResponseWriter, r *http.Request) {
|
||||||
var request ExchangeClusterIdentityTokenRequestObject
|
var request ExchangeClusterIdentityTokenRequestObject
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue