From 6a447cb7ce06704c9e0e2729b8463de70e688cbc Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Tue, 14 Nov 2023 15:19:17 +0200 Subject: [PATCH 1/4] APIGOV-26621 get spec from local --- default_kong_discovery_agent.yml | 1 + pkg/cmd/discovery/cmd.go | 5 +- pkg/config/discovery/config.go | 1 + pkg/gateway/client.go | 15 ++---- pkg/kong/kongclient.go | 82 +++++++++++++++++++++++++++++--- 5 files changed, 85 insertions(+), 19 deletions(-) diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 015e080..526aede 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -29,3 +29,4 @@ kong: http: 80 https: 443 specDownloadPaths: [] + specLocalPaths: [] diff --git a/pkg/cmd/discovery/cmd.go b/pkg/cmd/discovery/cmd.go index 015271a..ef10e22 100644 --- a/pkg/cmd/discovery/cmd.go +++ b/pkg/cmd/discovery/cmd.go @@ -20,6 +20,7 @@ const ( cfgKongProxyEpHttp = "kong.proxyEndpointProtocols.http" cfgKongProxyEpHttps = "kong.proxyEndpointProtocols.https" cfgKongSpecDownloadPaths = "kong.specDownloadPaths" + cfgKongSpecLocalPaths = "kong.specLocalPaths" ) func init() { @@ -40,7 +41,8 @@ func init() { rootProps.AddStringProperty(cfgKongProxyEp, "", "The Kong proxy endpoint") rootProps.AddIntProperty(cfgKongProxyEpHttp, 80, "The Kong proxy http port") rootProps.AddIntProperty(cfgKongProxyEpHttps, 443, "The Kong proxy https port") - rootProps.AddStringSliceProperty(cfgKongSpecDownloadPaths, []string{}, "URL paths that the agent will look in for spec files") + rootProps.AddStringSliceProperty(cfgKongSpecDownloadPaths, []string{}, "URL paths where the agent will look in for spec files") + rootProps.AddStringSliceProperty(cfgKongSpecLocalPaths, []string{}, "Local paths where the agent will look for spec files") } // Callback that agent will call to process the execution @@ -84,6 +86,7 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { ProxyHttpPort: rootProps.IntPropertyValue(cfgKongProxyEpHttp), ProxyHttpsPort: rootProps.IntPropertyValue(cfgKongProxyEpHttps), SpecDownloadPaths: rootProps.StringSlicePropertyValue(cfgKongSpecDownloadPaths), + SpecLocalPaths: rootProps.StringSlicePropertyValue(cfgKongSpecLocalPaths), } agentConfig = config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index 713dde9..b530042 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -22,6 +22,7 @@ type KongGatewayConfig struct { ProxyHttpPort int `config:"proxyHttpPort"` ProxyHttpsPort int `config:"proxyHttpsPort"` SpecDownloadPaths []string `config:"specDownloadPaths"` + SpecLocalPaths []string `config:"specLocalPaths"` } // ValidateCfg - Validates the gateway config diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index dba36cd..c9d9258 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -130,23 +130,14 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } - // all three fields are needed to form the backend URL used in discovery process - if service.Protocol == nil && service.Host == nil { - err := fmt.Errorf("fields for backend URL are not set") - log.WithError(err).Error("failed to create backend URL") - return err - } - backendURL := *service.Protocol + "://" + *service.Host - if service.Path != nil { - backendURL = backendURL + *service.Path - } - - kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, backendURL) + kongServiceSpec, err := gc.kongClient.GetSpecForService(ctx, service) if err != nil { log.WithError(err).Errorf("failed to get spec for service") return err } + // TODO: check if spec is nil + oasSpec := Openapi{ spec: string(kongServiceSpec), } diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index f8d8d64..87909b1 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -6,6 +6,8 @@ import ( "fmt" "io" "net/http" + "os" + "path" "strings" "time" @@ -16,6 +18,8 @@ import ( klib "github.com/kong/go-kong/kong" ) +const tagPrefix = "spec_local_" + type KongAPIClient interface { // Provisioning CreateConsumer(ctx context.Context, id, name string) (*klib.Consumer, error) @@ -27,7 +31,7 @@ type KongAPIClient interface { ListServices(ctx context.Context) ([]*klib.Service, error) ListRoutesForService(ctx context.Context, serviceId string) ([]*klib.Route, error) - GetSpecForService(ctx context.Context, backendURL string) ([]byte, error) + GetSpecForService(ctx context.Context, service *klib.Service) ([]byte, error) GetKongPlugins() *Plugins } @@ -37,7 +41,8 @@ type KongClient struct { logger log.FieldLogger baseClient DoRequest kongAdminEndpoint string - specPaths []string + specURLPaths []string + specLocalPaths []string clientTimeout time.Duration } @@ -65,7 +70,8 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig logger: log.NewFieldLogger().WithComponent("KongClient").WithPackage("kong"), baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, - specPaths: kongConfig.SpecDownloadPaths, + specURLPaths: kongConfig.SpecDownloadPaths, + specLocalPaths: kongConfig.SpecLocalPaths, clientTimeout: 10 * time.Second, }, nil } @@ -79,13 +85,77 @@ func (k KongClient) ListRoutesForService(ctx context.Context, serviceId string) return routes, err } -func (k KongClient) GetSpecForService(ctx context.Context, backendURL string) ([]byte, error) { - if len(k.specPaths) == 0 { +func (k KongClient) GetSpecForService(ctx context.Context, service *klib.Service) ([]byte, error) { + log := k.logger.WithField("serviceID", service.ID).WithField("serviceName", service.Name) + + if len(k.specLocalPaths) > 0 { + return k.getSpecFromLocal(ctx, service) + } + + // all three fields are needed to form the backend URL used in discovery process + if service.Protocol == nil && service.Host == nil { + err := fmt.Errorf("fields for backend URL are not set") + log.WithError(err).Error("failed to create backend URL") + return nil, err + } + backendURL := *service.Protocol + "://" + *service.Host + if service.Path != nil { + backendURL = backendURL + *service.Path + } + + return k.getSpecFromBackend(ctx, backendURL) +} + +func (k KongClient) getSpecFromLocal(ctx context.Context, service *klib.Service) ([]byte, error) { + log := k.logger.WithField("serviceID", service.ID).WithField("serviceName", service.Name) + + specTag := "" + for _, tag := range service.Tags { + if strings.HasPrefix(*tag, tagPrefix) { + specTag = *tag + } + } + + if len(specTag) > 0 { + filename := specTag[len(tagPrefix):] + for _, specPath := range k.specLocalPaths { + specFilePath := path.Join(specPath, filename) + specContent, err := k.loadSpecFile(specFilePath) + if err != nil { + log.WithError(err).Error("failed to get spec from file") + continue + } + return specContent, nil + } + } + + log.Info("no specification tag found") + return []byte{}, nil +} + +func (k KongClient) loadSpecFile(specFilePath string) ([]byte, error) { + log := k.logger.WithField("specFilePath", specFilePath) + + if _, err := os.Stat(specFilePath); os.IsNotExist(err) { + log.Debug("spec file not found") + return []byte{}, nil + } + + data, err := os.ReadFile(specFilePath) + if err != nil { + return nil, err + } + + return data, nil +} + +func (k KongClient) getSpecFromBackend(ctx context.Context, backendURL string) ([]byte, error) { + if len(k.specURLPaths) == 0 { k.logger.Info("no spec paths configured") return nil, nil } - for _, specPath := range k.specPaths { + for _, specPath := range k.specURLPaths { endpoint := fmt.Sprintf("%s/%s", backendURL, strings.TrimPrefix(specPath, "/")) spec, err := k.getSpec(ctx, endpoint) From a181051686628cc7a77250089eeffa5491c36779 Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Tue, 14 Nov 2023 16:43:52 +0200 Subject: [PATCH 2/4] APIGOV-26621 fix PR comms --- default_kong_discovery_agent.yml | 2 +- pkg/cmd/discovery/cmd.go | 6 ++--- pkg/config/discovery/config.go | 2 +- pkg/gateway/client.go | 6 ++++- pkg/kong/kongclient.go | 38 ++++++++++++++++---------------- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml index 526aede..a7bcde1 100644 --- a/default_kong_discovery_agent.yml +++ b/default_kong_discovery_agent.yml @@ -29,4 +29,4 @@ kong: http: 80 https: 443 specDownloadPaths: [] - specLocalPaths: [] + specLocalPath: diff --git a/pkg/cmd/discovery/cmd.go b/pkg/cmd/discovery/cmd.go index ef10e22..7d245aa 100644 --- a/pkg/cmd/discovery/cmd.go +++ b/pkg/cmd/discovery/cmd.go @@ -20,7 +20,7 @@ const ( cfgKongProxyEpHttp = "kong.proxyEndpointProtocols.http" cfgKongProxyEpHttps = "kong.proxyEndpointProtocols.https" cfgKongSpecDownloadPaths = "kong.specDownloadPaths" - cfgKongSpecLocalPaths = "kong.specLocalPaths" + cfgKongSpecLocalPath = "kong.specLocalPath" ) func init() { @@ -42,7 +42,7 @@ func init() { rootProps.AddIntProperty(cfgKongProxyEpHttp, 80, "The Kong proxy http port") rootProps.AddIntProperty(cfgKongProxyEpHttps, 443, "The Kong proxy https port") rootProps.AddStringSliceProperty(cfgKongSpecDownloadPaths, []string{}, "URL paths where the agent will look in for spec files") - rootProps.AddStringSliceProperty(cfgKongSpecLocalPaths, []string{}, "Local paths where the agent will look for spec files") + rootProps.AddStringProperty(cfgKongSpecLocalPath, "", "Local paths where the agent will look for spec files") } // Callback that agent will call to process the execution @@ -86,7 +86,7 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { ProxyHttpPort: rootProps.IntPropertyValue(cfgKongProxyEpHttp), ProxyHttpsPort: rootProps.IntPropertyValue(cfgKongProxyEpHttps), SpecDownloadPaths: rootProps.StringSlicePropertyValue(cfgKongSpecDownloadPaths), - SpecLocalPaths: rootProps.StringSlicePropertyValue(cfgKongSpecLocalPaths), + SpecLocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), } agentConfig = config.AgentConfig{ diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index b530042..0225aa0 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -22,7 +22,7 @@ type KongGatewayConfig struct { ProxyHttpPort int `config:"proxyHttpPort"` ProxyHttpsPort int `config:"proxyHttpsPort"` SpecDownloadPaths []string `config:"specDownloadPaths"` - SpecLocalPaths []string `config:"specLocalPaths"` + SpecLocalPath string `config:"specLocalPath"` } // ValidateCfg - Validates the gateway config diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index b3f896d..b1e8c05 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -179,7 +179,11 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se return err } - // TODO: check if spec is nil + // don't publish an empty spec + if kongServiceSpec == nil { + log.Debug("no spec found") + return nil + } oasSpec := Openapi{ spec: string(kongServiceSpec), diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 08da25a..1632697 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -33,7 +33,7 @@ type KongAPIClient interface { CreateHttpBasic(ctx context.Context, consumerID string, basicAuth *klib.BasicAuth) (*klib.BasicAuth, error) CreateOauth2(ctx context.Context, consumerID string, oauth2 *klib.Oauth2Credential) (*klib.Oauth2Credential, error) CreateAuthKey(ctx context.Context, consumerID string, keyAuth *klib.KeyAuth) (*klib.KeyAuth, error) - // Access Request + // Access Request AddRouteACL(ctx context.Context, routeID, allowedID string) error RemoveRouteACL(ctx context.Context, routeID, revokedID string) error AddQuota(ctx context.Context, routeID, allowedID, quotaInterval string, quotaLimit int) error @@ -51,7 +51,7 @@ type KongClient struct { baseClient DoRequest kongAdminEndpoint string specURLPaths []string - specLocalPaths []string + specLocalPath string clientTimeout time.Duration } @@ -80,7 +80,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig baseClient: baseClient, kongAdminEndpoint: kongConfig.AdminEndpoint, specURLPaths: kongConfig.SpecDownloadPaths, - specLocalPaths: kongConfig.SpecLocalPaths, + specLocalPath: kongConfig.SpecLocalPath, clientTimeout: 10 * time.Second, }, nil } @@ -97,7 +97,7 @@ func (k KongClient) ListRoutesForService(ctx context.Context, serviceId string) func (k KongClient) GetSpecForService(ctx context.Context, service *klib.Service) ([]byte, error) { log := k.logger.WithField("serviceID", service.ID).WithField("serviceName", service.Name) - if len(k.specLocalPaths) > 0 { + if k.specLocalPath != "" { return k.getSpecFromLocal(ctx, service) } @@ -122,24 +122,24 @@ func (k KongClient) getSpecFromLocal(ctx context.Context, service *klib.Service) for _, tag := range service.Tags { if strings.HasPrefix(*tag, tagPrefix) { specTag = *tag + break } } - if len(specTag) > 0 { - filename := specTag[len(tagPrefix):] - for _, specPath := range k.specLocalPaths { - specFilePath := path.Join(specPath, filename) - specContent, err := k.loadSpecFile(specFilePath) - if err != nil { - log.WithError(err).Error("failed to get spec from file") - continue - } - return specContent, nil - } + if specTag == "" { + log.Info("no specification tag found") + return nil, nil + } + + filename := specTag[len(tagPrefix):] + specFilePath := path.Join(k.specLocalPath, filename) + specContent, err := k.loadSpecFile(specFilePath) + if err != nil { + log.WithError(err).Error("failed to get spec from file") + return nil, err } - log.Info("no specification tag found") - return []byte{}, nil + return specContent, nil } func (k KongClient) loadSpecFile(specFilePath string) ([]byte, error) { @@ -147,7 +147,7 @@ func (k KongClient) loadSpecFile(specFilePath string) ([]byte, error) { if _, err := os.Stat(specFilePath); os.IsNotExist(err) { log.Debug("spec file not found") - return []byte{}, nil + return nil, nil } data, err := os.ReadFile(specFilePath) @@ -178,7 +178,7 @@ func (k KongClient) getSpecFromBackend(ctx context.Context, backendURL string) ( } k.logger.Info("no spec found") - return []byte{}, nil + return nil, nil } func (k KongClient) getSpec(ctx context.Context, endpoint string) ([]byte, error) { From 15ffe601e2b5a447c8d0164d2cbd17d35214732b Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Fri, 17 Nov 2023 11:21:44 +0200 Subject: [PATCH 3/4] APIGOV-26621 get spec from dev portal --- pkg/cmd/discovery/cmd.go | 23 ++++++----- pkg/config/discovery/config.go | 5 ++- pkg/kong/kongclient.go | 72 ++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/pkg/cmd/discovery/cmd.go b/pkg/cmd/discovery/cmd.go index f6659b9..d270241 100644 --- a/pkg/cmd/discovery/cmd.go +++ b/pkg/cmd/discovery/cmd.go @@ -14,14 +14,15 @@ var DiscoveryCmd corecmd.AgentRootCmd var agentConfig config.AgentConfig const ( - cfgKongAdminURL = "kong.admin.url" - cfgKongAdminAPIKey = "kong.admin.auth.apikey.value" - cfgKongAdminAPIKeyHeader = "kong.admin.auth.apikey.header" - cfgKongProxyHost = "kong.proxy.host" - cfgKongProxyPortHttp = "kong.proxy.port.http" - cfgKongProxyPortHttps = "kong.proxy.port.https" - cfgKongSpecURLPaths = "kong.spec.urlPaths" - cfgKongSpecLocalPath = "kong.spec.localPath" + cfgKongAdminURL = "kong.admin.url" + cfgKongAdminAPIKey = "kong.admin.auth.apikey.value" + cfgKongAdminAPIKeyHeader = "kong.admin.auth.apikey.header" + cfgKongProxyHost = "kong.proxy.host" + cfgKongProxyPortHttp = "kong.proxy.port.http" + cfgKongProxyPortHttps = "kong.proxy.port.https" + cfgKongSpecURLPaths = "kong.spec.urlPaths" + cfgKongSpecLocalPath = "kong.spec.localPath" + cfgKongSpecDevPortalEnabled = "kong.spec.devPortalEnabled" ) func init() { @@ -45,6 +46,7 @@ func init() { rootProps.AddIntProperty(cfgKongProxyPortHttps, 443, "The Kong proxy https port") rootProps.AddStringSliceProperty(cfgKongSpecURLPaths, []string{}, "URL paths that the agent will look in for spec files") rootProps.AddStringProperty(cfgKongSpecLocalPath, "", "Local paths where the agent will look for spec files") + rootProps.AddBoolProperty(cfgKongSpecDevPortalEnabled, false, "Dev Portal is used to download spec files") } // Callback that agent will call to process the execution @@ -99,8 +101,9 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { }, }, Spec: config.KongSpecConfig{ - URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths), - LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), + URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths), + LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), + DevPortalEnabled: rootProps.BoolPropertyValue(cfgKongSpecDevPortalEnabled), }, } diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index d07944d..a7d1996 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -37,8 +37,9 @@ type KongProxyPortConfig struct { } type KongSpecConfig struct { - URLPaths []string `config:"urlPaths"` - LocalPath string `config:"localPaths"` + URLPaths []string `config:"urlPaths"` + LocalPath string `config:"localPath"` + DevPortalEnabled bool `config:"devPortalEnabled"` } // KongGatewayConfig - represents the config for gateway diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index e331023..f64fb8d 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -3,6 +3,7 @@ package kong import ( "context" "crypto/tls" + "encoding/json" "fmt" "io" "net/http" @@ -44,6 +45,14 @@ type KongAPIClient interface { GetKongPlugins() *Plugins } +type KongServiceSpec struct { + Contents string `json:"contents"` + CreatedAt int `json:"created_at"` + ID string `json:"id"` + Path string `json:"path"` + Checksum string `json:"checksum"` +} + type KongClient struct { *klib.Client logger log.FieldLogger @@ -51,6 +60,7 @@ type KongClient struct { kongAdminEndpoint string specURLPaths []string specLocalPath string + devPortalEnabled bool clientTimeout time.Duration } @@ -80,6 +90,7 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig kongAdminEndpoint: kongConfig.Admin.URL, specURLPaths: kongConfig.Spec.URLPaths, specLocalPath: kongConfig.Spec.LocalPath, + devPortalEnabled: kongConfig.Spec.DevPortalEnabled, clientTimeout: 60 * time.Second, }, nil } @@ -100,6 +111,10 @@ func (k KongClient) GetSpecForService(ctx context.Context, service *klib.Service return k.getSpecFromLocal(ctx, service) } + if k.devPortalEnabled { + return k.getSpecFromDevPortal(ctx, *service.ID) + } + // all three fields are needed to form the backend URL used in discovery process if service.Protocol == nil && service.Host == nil { err := fmt.Errorf("fields for backend URL are not set") @@ -116,6 +131,7 @@ func (k KongClient) GetSpecForService(ctx context.Context, service *klib.Service func (k KongClient) getSpecFromLocal(ctx context.Context, service *klib.Service) ([]byte, error) { log := k.logger.WithField("serviceID", service.ID).WithField("serviceName", service.Name) + log.Info("getting spec from local storage") specTag := "" for _, tag := range service.Tags { @@ -157,7 +173,44 @@ func (k KongClient) loadSpecFile(specFilePath string) ([]byte, error) { return data, nil } +func (k KongClient) getSpecFromDevPortal(ctx context.Context, serviceID string) ([]byte, error) { + log := k.logger.WithField("serviceID", serviceID) + log.Info("getting spec file from dev portal") + + endpoint := fmt.Sprintf("%s/services/%s/document_objects", k.kongAdminEndpoint, serviceID) + req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) + if err != nil { + log.WithError(err).Error("failed to create request") + return nil, err + } + res, err := k.baseClient.Do(req) + if err != nil { + log.WithError(err).Error("failed to execute request") + return nil, err + } + data, err := io.ReadAll(res.Body) + if err != nil { + log.WithError(err).Error("failed to read body") + return nil, err + } + documents := &DocumentObjects{} + err = json.Unmarshal(data, documents) + if err != nil { + log.WithError(err).Error("failed to unmarshal") + return nil, err + } + if len(documents.Data) < 1 { + log.Debug("no documents found") + return nil, nil + } + + endpoint = fmt.Sprintf("%s/default/files/%s", k.kongAdminEndpoint, documents.Data[0].Path) + return k.getSpec(ctx, endpoint, true) +} + func (k KongClient) getSpecFromBackend(ctx context.Context, backendURL string) ([]byte, error) { + k.logger.Info("trying to get spec file from service backend") + if len(k.specURLPaths) == 0 { k.logger.Info("no spec paths configured") return nil, nil @@ -166,7 +219,7 @@ func (k KongClient) getSpecFromBackend(ctx context.Context, backendURL string) ( for _, specPath := range k.specURLPaths { endpoint := fmt.Sprintf("%s/%s", backendURL, strings.TrimPrefix(specPath, "/")) - spec, err := k.getSpec(ctx, endpoint) + spec, err := k.getSpec(ctx, endpoint, false) if err != nil { return nil, err } @@ -180,7 +233,7 @@ func (k KongClient) getSpecFromBackend(ctx context.Context, backendURL string) ( return nil, nil } -func (k KongClient) getSpec(ctx context.Context, endpoint string) ([]byte, error) { +func (k KongClient) getSpec(ctx context.Context, endpoint string, fromDevPortal bool) ([]byte, error) { ctxTimeout, cancel := context.WithTimeout(ctx, k.clientTimeout) defer cancel() @@ -198,12 +251,25 @@ func (k KongClient) getSpec(ctx context.Context, endpoint string) ([]byte, error return nil, nil } - specContent, err := io.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if err != nil { k.logger.WithError(err).Error("failed to read body") return nil, err } + var specContent []byte + if fromDevPortal { + kongServiceSpec := &KongServiceSpec{} + err = json.Unmarshal(data, kongServiceSpec) + if err != nil { + k.logger.WithError(err).Error("failed to unmarshal") + return nil, err + } + specContent = []byte(kongServiceSpec.Contents) + } else { + specContent = data + } + specParser := apic.NewSpecResourceParser(specContent, "") err = specParser.Parse() if err != nil { From d3e88f0f6f855e2555062ffc058ac241f9bec6cf Mon Sep 17 00:00:00 2001 From: Alin Rosca Date: Tue, 21 Nov 2023 17:10:02 +0200 Subject: [PATCH 4/4] APIGOV-26621 fix PR comms --- README.md | 14 ++++++++++++++ pkg/cmd/discovery/cmd.go | 22 +++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index df4de44..002dd93 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ The Kong agents are used to discover, provision access to, and track usages of K - [Specification discovery methods](#specification-discovery-methods) - [Local specification path](#local-specification-path) - [URL specification paths](#url-specification-paths) + - [Kong Dev Portal](#kong-dev-portal) - [Kong agents deployment](#kong-agents-deployment) - [Additional information](#additional-information) - [Docker](#docker) @@ -150,6 +151,19 @@ Configuration for agent KONG_SPEC_URLPATHS=/openapi.json,/swagger.json ``` +##### Kong Dev Portal + +The Kong Dev Portal discovery method is configured by providing a value for the `KONG_SPEC_DEVPORTALENABLED`, but also the local spec discovery needs to be disabled by setting an empty value for the`KONG_SPEC_LOCALPATH`, otherwise, the local discovery process will be used. + +Ex. + +Configuration for agent + +```shell +KONG_SPEC_LOCALPATH="" +KONG_SPEC_DEVPORTALENABLED=true +``` + ## Kong agents deployment The Kong agents are delivered as containers, kong_discovery_agent and kong_traceability_agent. These containers can be deployed directly to a container server, such as Docker, or using the provided helm chart. In this section you will lean how to deploy the agents directly as containers or within a kubernetes cluster using the helm chart. diff --git a/pkg/cmd/discovery/cmd.go b/pkg/cmd/discovery/cmd.go index d270241..0bf4746 100644 --- a/pkg/cmd/discovery/cmd.go +++ b/pkg/cmd/discovery/cmd.go @@ -14,15 +14,15 @@ var DiscoveryCmd corecmd.AgentRootCmd var agentConfig config.AgentConfig const ( - cfgKongAdminURL = "kong.admin.url" - cfgKongAdminAPIKey = "kong.admin.auth.apikey.value" - cfgKongAdminAPIKeyHeader = "kong.admin.auth.apikey.header" - cfgKongProxyHost = "kong.proxy.host" - cfgKongProxyPortHttp = "kong.proxy.port.http" - cfgKongProxyPortHttps = "kong.proxy.port.https" - cfgKongSpecURLPaths = "kong.spec.urlPaths" - cfgKongSpecLocalPath = "kong.spec.localPath" - cfgKongSpecDevPortalEnabled = "kong.spec.devPortalEnabled" + cfgKongAdminURL = "kong.admin.url" + cfgKongAdminAPIKey = "kong.admin.auth.apikey.value" + cfgKongAdminAPIKeyHeader = "kong.admin.auth.apikey.header" + cfgKongProxyHost = "kong.proxy.host" + cfgKongProxyPortHttp = "kong.proxy.port.http" + cfgKongProxyPortHttps = "kong.proxy.port.https" + cfgKongSpecURLPaths = "kong.spec.urlPaths" + cfgKongSpecLocalPath = "kong.spec.localPath" + cfgKongDevPortalEnabled = "kong.spec.devPortalEnabled" ) func init() { @@ -46,7 +46,7 @@ func init() { rootProps.AddIntProperty(cfgKongProxyPortHttps, 443, "The Kong proxy https port") rootProps.AddStringSliceProperty(cfgKongSpecURLPaths, []string{}, "URL paths that the agent will look in for spec files") rootProps.AddStringProperty(cfgKongSpecLocalPath, "", "Local paths where the agent will look for spec files") - rootProps.AddBoolProperty(cfgKongSpecDevPortalEnabled, false, "Dev Portal is used to download spec files") + rootProps.AddBoolProperty(cfgKongDevPortalEnabled, false, "Dev Portal is used to download spec files") } // Callback that agent will call to process the execution @@ -103,7 +103,7 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { Spec: config.KongSpecConfig{ URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths), LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), - DevPortalEnabled: rootProps.BoolPropertyValue(cfgKongSpecDevPortalEnabled), + DevPortalEnabled: rootProps.BoolPropertyValue(cfgKongDevPortalEnabled), }, }