diff --git a/config/.env b/config/.env index c61beb1..9ae246a 100644 --- a/config/.env +++ b/config/.env @@ -35,3 +35,7 @@ INFLUXDB_PORT=8086 JAEGER_ENABLED=false JAEGER_HOST=jaeger JAEGER_PORT=14268 # accept jaeger.thrift directly from clients + +# registry +REGISTRY_HOST=registry +REGISTRY_PORT=5000 diff --git a/config/.env.envsubst b/config/.env.envsubst index e07f027..ab0c45d 100644 --- a/config/.env.envsubst +++ b/config/.env.envsubst @@ -31,3 +31,7 @@ INFLUXDB_PORT=${INFLUXDB_PORT} JAEGER_ENABLED=${JAEGER_ENABLED} JAEGER_HOST=${JAEGER_HOST} JAEGER_PORT=${JAEGER_PORT} + +# registry +REGISTRY_HOST=${REGISTRY_HOST} +REGISTRY_PORT=${REGISTRY_PORT} diff --git a/config/base.json b/config/base.json index f03f1da..3a5f6a2 100644 --- a/config/base.json +++ b/config/base.json @@ -32,11 +32,14 @@ {{ template "influxdb_metrics.tmpl" . }}, {{ template "cors.tmpl" . }}, "plugin/http-server": { - "name": ["multi-auth", "grpc-proxy-server"], + "name": ["multi-auth", "grpc-proxy-server", "registry"], "multi-auth":{ - "grpc_server": "{{ .backends.mgmt_grpc }}" + "grpc_server": "{{ .plugins.mgmt_grpc }}" }, - "grpc-proxy-server": {} + "grpc-proxy-server": {}, + "registry": { + "hostport": "{{ .plugins.registry_hostport }}" + } } }, "endpoints": [ diff --git a/config/settings-env/backends.json b/config/settings-env/backends.json index a423483..9e683f4 100644 --- a/config/settings-env/backends.json +++ b/config/settings-env/backends.json @@ -1,7 +1,6 @@ { "debug": "https://${API_GATEWAY_HOST}:${API_GATEWAY_PORT}", "mgmt": "http://${MGMT_BACKEND_HOST}:${MGMT_BACKEND_PUBLICPORT}", - "mgmt_grpc": "${MGMT_BACKEND_HOST}:${MGMT_BACKEND_PUBLICPORT}", "model": "http://${MODEL_BACKEND_HOST}:${MODEL_BACKEND_PUBLICPORT}", "pipeline": "http://${PIPELINE_BACKEND_HOST}:${PIPELINE_BACKEND_PUBLICPORT}" } \ No newline at end of file diff --git a/config/settings-env/endpoints.json b/config/settings-env/endpoints.json index 93ba759..9489384 100644 --- a/config/settings-env/endpoints.json +++ b/config/settings-env/endpoints.json @@ -1248,7 +1248,6 @@ "method": "POST", "timeout": "600s" }, - { "endpoint": "/vdp.pipeline.v1beta.PipelinePublicService/CreateOrganizationPipeline", "url_pattern": "/vdp.pipeline.v1beta.PipelinePublicService/CreateOrganizationPipeline", @@ -1375,7 +1374,6 @@ "method": "POST", "timeout": "600s" }, - { "endpoint": "/vdp.pipeline.v1beta.PipelinePublicService/GetOperation", "url_pattern": "/vdp.pipeline.v1beta.PipelinePublicService/GetOperation", @@ -2088,4 +2086,4 @@ } ] } -} +} \ No newline at end of file diff --git a/config/settings-env/plugins.json b/config/settings-env/plugins.json new file mode 100644 index 0000000..9d84bf5 --- /dev/null +++ b/config/settings-env/plugins.json @@ -0,0 +1,4 @@ +{ + "mgmt_grpc": "${MGMT_BACKEND_HOST}:${MGMT_BACKEND_PUBLICPORT}", + "registry_hostport": "${REGISTRY_HOST}:${REGISTRY_PORT}" +} \ No newline at end of file diff --git a/registry-plugin/go.mod b/registry-plugin/go.mod new file mode 100644 index 0000000..9e704f7 --- /dev/null +++ b/registry-plugin/go.mod @@ -0,0 +1,3 @@ +module registry-plugin + +go 1.21 \ No newline at end of file diff --git a/registry-plugin/go.sum b/registry-plugin/go.sum new file mode 100644 index 0000000..2d29b57 --- /dev/null +++ b/registry-plugin/go.sum @@ -0,0 +1,14 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/registry-plugin/main.go b/registry-plugin/main.go new file mode 100644 index 0000000..f38d224 --- /dev/null +++ b/registry-plugin/main.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "strings" +) + +// pluginName is the plugin name +var pluginName = "registry" + +// HandlerRegisterer is the symbol the plugin loader will try to load. It must implement the Registerer interface +var HandlerRegisterer = registerer(pluginName) + +type registerer string + +func (r registerer) RegisterHandlers(f func( + name string, + handler func(context.Context, map[string]interface{}, http.Handler) (http.Handler, error), +)) { + f(string(r), r.registerHandlers) +} + +func (r registerer) registerHandlers(_ context.Context, extra map[string]interface{}, h http.Handler) (http.Handler, error) { + + config, ok := extra[pluginName].(map[string]interface{}) + if !ok { + return h, errors.New("configuration not found") + } + + hostport, _ := config["hostport"].(string) + + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + + // If the URL path contains /v2/, indicating a request to Distribution Registry HTTP API V2, + // the traffic is hijacked and directed to the registry + if strings.Contains(req.URL.Path, "/v2/") { + req.URL.Scheme = "http" + req.URL.Host = hostport + req.RequestURI = "" + + resp, err := http.DefaultClient.Do(req) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Copy headers, status codes, and body from the backend to the response writer + for k, hs := range resp.Header { + for _, h := range hs { + w.Header().Add(k, h) + } + } + w.WriteHeader(resp.StatusCode) + io.Copy(w, resp.Body) + resp.Body.Close() + } else { + h.ServeHTTP(w, req) + } + + }), nil +} + +func main() {} + +// This logger is replaced by the RegisterLogger method to load the one from KrakenD +var logger Logger = noopLogger{} + +func (registerer) RegisterLogger(v interface{}) { + l, ok := v.(Logger) + if !ok { + return + } + logger = l + logger.Debug(fmt.Sprintf("[PLUGIN: %s] Logger loaded", HandlerRegisterer)) +} + +// Logger is an interface for logging functionality. +type Logger interface { + Debug(v ...interface{}) + Info(v ...interface{}) + Warning(v ...interface{}) + Error(v ...interface{}) + Critical(v ...interface{}) + Fatal(v ...interface{}) +} + +// Empty logger implementation +type noopLogger struct{} + +func (n noopLogger) Debug(_ ...interface{}) {} +func (n noopLogger) Info(_ ...interface{}) {} +func (n noopLogger) Warning(_ ...interface{}) {} +func (n noopLogger) Error(_ ...interface{}) {} +func (n noopLogger) Critical(_ ...interface{}) {} +func (n noopLogger) Fatal(_ ...interface{}) {}