Skip to content

Commit

Permalink
Merge branch 'main' into APIGOV-26621
Browse files Browse the repository at this point in the history
  • Loading branch information
alrosca committed Nov 21, 2023
2 parents d3e88f0 + 578441a commit 0291b2b
Show file tree
Hide file tree
Showing 16 changed files with 252 additions and 182 deletions.
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ bin/
.run/
*.log

/kong_discovery_agent.yml
/kong_traceability_agent.yml
**/kong_discovery_agent.yml
**/kong_traceability_agent.yml

specs/
data/
logs/

secret.yaml
overrides.yaml
configmap.yaml

**/__debug_bin*
26 changes: 21 additions & 5 deletions build/traceability/kong_traceability_agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ kong_traceability_agent:
apikey:
header: ${KONG_ADMIN_AUTH_APIKEY_HEADER}
value: ${KONG_ADMIN_AUTH_APIKEY_VALUE}
http_log_plugin_config:
path: ${KONG_LOGS_HTTP_SERVER_PATH}
port: ${KONG_LOGS_HTTP_SERVER_PORT}
httpLogPlugin:
path: ${KONG_HTTPLOGPLUGIN_PATH}
port: ${KONG_HTTPLOGPLUGIN_PORT}
# Settings for connecting to Amplify Central
central:
url: ${CENTRAL_URL:https://apicentral.axway.com}
Expand All @@ -21,7 +21,6 @@ kong_traceability_agent:
agentName: ${CENTRAL_AGENTNAME:""}
platformURL: ${CENTRAL_PLATFORMURL:https://platform.axway.com}
reportActivityFrequency: ${CENTRAL_REPORTACTIVITYFREQUENCY:5m}
versionChecker: ${CENTRAL_VERSIONCHECKER:true}
usageReporting:
publish: ${CENTRAL_USAGEREPORTING_PUBLISH}
publishMetric: ${CENTRAL_USAGEREPORTING_PUBLISHMETRIC}
Expand Down Expand Up @@ -49,8 +48,25 @@ kong_traceability_agent:
port: ${CENTRAL_GRPC_PORT}
proxyUrl: ${CENTRAL_PROXYURL:""}
clientTimeout: ${CENTRAL_CLIENTTIMEOUT:60s}
agentFeatures:
persistCache: ${AGENTFEATURES_PERSISTCACHE}
marketplaceProvisioning: ${AGENTFEATURES_MARKETPLACEPROVISIONING}
versionChecker: ${AGENTFEATURES_VERSIONCHECKER}
processSystemSignals: ${AGENTFEATURES_PROCESSSYSTEMSIGNALS}
connectToCentral: ${AGENTFEATURES_CONNECTTOCENTRAL}
status:
port: ${STATUS_PORT:8990}
healthCheckPeriod: ${STATUS_HEALTHCHECKPERIOD:3m}
healthCheckInterval: ${STATUS_HEALTHCHECKINTERVAL:30s}
log:
level: ${LOG_LEVEL:info}
format: ${LOG_FORMAT:json}
output: ${LOG_OUTPUT:stdout}
file:
name: ${LOG_FILE_NAME:traceability_agent.log}
path: ${LOG_FILE_PATH:logs}

# Condor Ingestion service
# Send output to Central Database
output.traceability:
enabled: true
hosts: ${TRACEABILITY_HOST:ingestion.datasearch.axway.com:5044}
Expand Down
66 changes: 38 additions & 28 deletions pkg/beater/custom_beater.go
Original file line number Diff line number Diff line change
@@ -1,97 +1,107 @@
package beater

import (
"context"
"fmt"
"io/ioutil"
"log"
"io"
"net/http"

traceabilityconfig "github.com/Axway/agents-kong/pkg/config/traceability"

"github.com/Axway/agents-kong/pkg/processor"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/google/uuid"

agentErrors "github.com/Axway/agent-sdk/pkg/util/errors"
hc "github.com/Axway/agent-sdk/pkg/util/healthcheck"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/logp"
"github.com/Axway/agent-sdk/pkg/util/log"

config "github.com/Axway/agents-kong/pkg/config/traceability"
"github.com/Axway/agents-kong/pkg/processor"
)

type customLogBeater struct {
type httpLogBeater struct {
done chan struct{}
eventProcessor *processor.EventProcessor
client beat.Client
eventChannel chan string
logger log.FieldLogger
}

// New creates an instance of kong_traceability_agent.
func New(*beat.Beat, *common.Config) (beat.Beater, error) {
bt := &customLogBeater{
b := &httpLogBeater{
done: make(chan struct{}),
eventChannel: make(chan string),
logger: log.NewFieldLogger().WithComponent("httpLogBeater").WithPackage("beater"),
}

bt.eventProcessor = processor.NewEventProcessor()
b.eventProcessor = processor.NewEventProcessor()

// Validate that all necessary services are up and running. If not, return error
if hc.RunChecks() != hc.OK {
b.logger.Error("not all services are running")
return nil, agentErrors.ErrInitServicesNotReady
}

return bt, nil
return b, nil
}

// Run starts kong_traceability_agent.
func (bt *customLogBeater) Run(b *beat.Beat) error {
logp.Info("kong_traceability_agent is running! Hit CTRL-C to stop it.")
func (b *httpLogBeater) Run(beater *beat.Beat) error {
b.logger.Info("kong_traceability_agent is running! Hit CTRL-C to stop it.")

var err error
bt.client, err = b.Publisher.Connect()
b.client, err = beater.Publisher.Connect()
if err != nil {
return err
}

http.HandleFunc(traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Path,
http.HandleFunc(config.GetAgentConfig().HttpLogPluginConfig.Path,
func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
b.logger.Trace("received a non post request")
w.WriteHeader(http.StatusMethodNotAllowed)
return
}

body, err := ioutil.ReadAll(r.Body)
ctx := context.WithValue(context.Background(), processor.CtxTransactionID, uuid.NewString())
logData, err := io.ReadAll(r.Body)
defer r.Body.Close()

if err != nil {
logp.Error(fmt.Errorf("error while reading request body: %s", err))
b.logger.WithError(err).Error("reading request body")
}

w.WriteHeader(200)
bt.processAndDispatchEvent(string(body))
})
go b.processAndDispatchEvent(ctx, logData)
},
)

/* Start a new HTTP server in a separate Go routine that will be the target
for the HTTP Log plugin. It should write events it gets to eventChannel */
go func() {
if err := http.ListenAndServe(fmt.Sprintf(":%d", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port),
nil); err != nil {
log.Fatalf("Unable to start the HTTP Server: %s", err)
err := http.ListenAndServe(fmt.Sprintf(":%d", config.GetAgentConfig().HttpLogPluginConfig.Port), nil)
if err != nil {
b.logger.WithError(err).Fatalf("unable to start the HTTP Server")
}
fmt.Printf("Started HTTP server on port %d to receive request logs", traceabilityconfig.GetAgentConfig().HttpLogPluginConfig.Port)
b.logger.WithField("port", config.GetAgentConfig().HttpLogPluginConfig.Port).WithField("path", config.GetAgentConfig().HttpLogPluginConfig.Path).Info("started HTTP server")
}()

<-bt.done
<-b.done
return nil
}

// Stop stops kong_traceability_agent.
func (bt *customLogBeater) Stop() {
func (bt *httpLogBeater) Stop() {
bt.client.Close()
close(bt.done)
}

func (bt *customLogBeater) processAndDispatchEvent(logEvent string) {
eventsToPublish := bt.eventProcessor.ProcessRaw([]byte(logEvent))
func (bt *httpLogBeater) processAndDispatchEvent(ctx context.Context, logData []byte) {
log := log.UpdateLoggerWithContext(ctx, bt.logger)
log.WithField("data", logData).Trace("handling log data")
eventsToPublish := bt.eventProcessor.ProcessRaw(ctx, logData)
if eventsToPublish != nil {
log.Trace("finished handling data")
bt.client.PublishAll(eventsToPublish)
}
}
50 changes: 3 additions & 47 deletions pkg/cmd/discovery/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,14 @@ import (
corecmd "github.com/Axway/agent-sdk/pkg/cmd"
corecfg "github.com/Axway/agent-sdk/pkg/config"
"github.com/Axway/agent-sdk/pkg/util/log"

config "github.com/Axway/agents-kong/pkg/config/discovery"
"github.com/Axway/agents-kong/pkg/gateway"
)

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"
cfgKongDevPortalEnabled = "kong.spec.devPortalEnabled"
)

func init() {
// Create new root command with callbacks to initialize the agent config and command execution.
// The first parameter identifies the name of the yaml file that agent will look for to load the config
Expand All @@ -38,15 +27,7 @@ func init() {

// Get the root command properties and bind the config property in YAML definition
rootProps := DiscoveryCmd.GetProperties()
rootProps.AddStringProperty(cfgKongAdminURL, "", "The Kong admin endpoint")
rootProps.AddStringProperty(cfgKongAdminAPIKey, "", "API Key value to authenticate with Kong Gateway")
rootProps.AddStringProperty(cfgKongAdminAPIKeyHeader, "", "API Key header to authenticate with Kong Gateway")
rootProps.AddStringProperty(cfgKongProxyHost, "", "The Kong proxy endpoint")
rootProps.AddIntProperty(cfgKongProxyPortHttp, 80, "The Kong proxy http port")
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(cfgKongDevPortalEnabled, false, "Dev Portal is used to download spec files")
config.AddKongProperties(rootProps)
}

// Callback that agent will call to process the execution
Expand Down Expand Up @@ -82,34 +63,9 @@ func run() error {
func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) {
rootProps := DiscoveryCmd.GetProperties()

// Parse the config from bound properties and setup gateway config
gatewayConfig := &config.KongGatewayConfig{
Admin: config.KongAdminConfig{
URL: rootProps.StringPropertyValue(cfgKongAdminURL),
Auth: config.KongAdminAuthConfig{
APIKey: config.KongAdminAuthAPIKeyConfig{
Value: rootProps.StringPropertyValue(cfgKongAdminAPIKey),
Header: rootProps.StringPropertyValue(cfgKongAdminAPIKeyHeader),
},
},
},
Proxy: config.KongProxyConfig{
Host: rootProps.StringPropertyValue(cfgKongProxyHost),
Port: config.KongProxyPortConfig{
HTTP: rootProps.IntPropertyValue(cfgKongProxyPortHttp),
HTTPS: rootProps.IntPropertyValue(cfgKongProxyPortHttps),
},
},
Spec: config.KongSpecConfig{
URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths),
LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath),
DevPortalEnabled: rootProps.BoolPropertyValue(cfgKongDevPortalEnabled),
},
}

agentConfig = config.AgentConfig{
CentralCfg: centralConfig,
KongGatewayCfg: gatewayConfig,
KongGatewayCfg: config.ParseProperties(rootProps),
}
return agentConfig, nil
}
Expand Down
21 changes: 9 additions & 12 deletions pkg/cmd/traceability/cmd.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package traceability

import (
libcmd "github.com/elastic/beats/v7/libbeat/cmd"
"github.com/elastic/beats/v7/libbeat/cmd/instance"

corecmd "github.com/Axway/agent-sdk/pkg/cmd"
corecfg "github.com/Axway/agent-sdk/pkg/config"

"github.com/Axway/agents-kong/pkg/beater"
config "github.com/Axway/agents-kong/pkg/config/traceability"
libcmd "github.com/elastic/beats/v7/libbeat/cmd"
"github.com/elastic/beats/v7/libbeat/cmd/instance"
)

var TraceCmd corecmd.AgentRootCmd
Expand All @@ -15,8 +17,9 @@ var beatCmd *libcmd.BeatsRootCmd
func init() {
name := "kong_traceability_agent"
settings := instance.Settings{
Name: name,
HasDashboards: true,
Name: name,
HasDashboards: true,
ConfigOverrides: corecfg.LogConfigOverrides(),
}

beatCmd = libcmd.GenRootCmdWithSettings(beater.New, settings)
Expand All @@ -33,8 +36,7 @@ func init() {
)

rootProps := TraceCmd.GetProperties()
rootProps.AddStringProperty("http_log_plugin_config.path", "/requestlogs", "Path on which the HTTP Log plugin sends request logs")
rootProps.AddIntProperty("http_log_plugin_config.port", 9000, "Port that listens for request logs from HTTP Log plugin")
config.AddKongProperties(rootProps)
}

func run() error {
Expand All @@ -47,14 +49,9 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) {

rootProps := TraceCmd.GetProperties()

httpLogPluginConfig := &config.HttpLogPluginConfig{
Port: rootProps.IntPropertyValue("http_log_plugin_config.port"),
Path: rootProps.StringPropertyValue("http_log_plugin_config.path"),
}

agentConfig := &config.AgentConfig{
CentralCfg: centralConfig,
HttpLogPluginConfig: httpLogPluginConfig,
HttpLogPluginConfig: config.ParseProperties(rootProps),
}

config.SetAgentConfig(agentConfig)
Expand Down
49 changes: 49 additions & 0 deletions pkg/config/discovery/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,32 @@ package config
import (
"fmt"

"github.com/Axway/agent-sdk/pkg/cmd/properties"
corecfg "github.com/Axway/agent-sdk/pkg/config"
)

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"
)

func AddKongProperties(rootProps properties.Properties) {
rootProps.AddStringProperty(cfgKongAdminURL, "", "The Kong admin endpoint")
rootProps.AddStringProperty(cfgKongAdminAPIKey, "", "API Key value to authenticate with Kong Gateway")
rootProps.AddStringProperty(cfgKongAdminAPIKeyHeader, "", "API Key header to authenticate with Kong Gateway")
rootProps.AddStringProperty(cfgKongProxyHost, "", "The Kong proxy endpoint")
rootProps.AddIntProperty(cfgKongProxyPortHttp, 80, "The Kong proxy http port")
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")
}

// AgentConfig - represents the config for agent
type AgentConfig struct {
CentralCfg corecfg.CentralConfig `config:"central"`
Expand Down Expand Up @@ -63,3 +86,29 @@ func (c *KongGatewayConfig) ValidateCfg() (err error) {
}
return
}

func ParseProperties(rootProps properties.Properties) *KongGatewayConfig {
// Parse the config from bound properties and setup gateway config
return &KongGatewayConfig{
Admin: KongAdminConfig{
URL: rootProps.StringPropertyValue(cfgKongAdminURL),
Auth: KongAdminAuthConfig{
APIKey: KongAdminAuthAPIKeyConfig{
Value: rootProps.StringPropertyValue(cfgKongAdminAPIKey),
Header: rootProps.StringPropertyValue(cfgKongAdminAPIKeyHeader),
},
},
},
Proxy: KongProxyConfig{
Host: rootProps.StringPropertyValue(cfgKongProxyHost),
Port: KongProxyPortConfig{
HTTP: rootProps.IntPropertyValue(cfgKongProxyPortHttp),
HTTPS: rootProps.IntPropertyValue(cfgKongProxyPortHttps),
},
},
Spec: KongSpecConfig{
URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths),
LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath),
},
}
}
Loading

0 comments on commit 0291b2b

Please sign in to comment.