From 4f9399d860cd9bef0f1cf12b61028966b4fa1ad9 Mon Sep 17 00:00:00 2001 From: lakshmimsft Date: Wed, 18 Dec 2024 14:32:40 -0800 Subject: [PATCH] rebase issue Signed-off-by: lakshmimsft --- cmd/ucpd/cmd/root.go | 1 + cmd/ucpd/ucp-dev.yaml | 6 +- deploy/Chart/templates/ucp/configmaps.yaml | 4 +- .../resourceprovider/create/create_test.go | 1 - pkg/ucp/config.go | 3 +- pkg/ucp/hostoptions/providerconfig.go | 74 ----------- pkg/ucp/initializer/service.go | 29 ++--- pkg/ucp/server/server.go | 120 +----------------- 8 files changed, 22 insertions(+), 216 deletions(-) delete mode 100644 pkg/ucp/hostoptions/providerconfig.go diff --git a/cmd/ucpd/cmd/root.go b/cmd/ucpd/cmd/root.go index 68b1ec15d5..d99e885800 100644 --- a/cmd/ucpd/cmd/root.go +++ b/cmd/ucpd/cmd/root.go @@ -19,6 +19,7 @@ package cmd import ( "context" "fmt" + "os" "github.com/go-logr/logr" "github.com/spf13/cobra" diff --git a/cmd/ucpd/ucp-dev.yaml b/cmd/ucpd/ucp-dev.yaml index 1fca19b4c6..a754c4579f 100644 --- a/cmd/ucpd/ucp-dev.yaml +++ b/cmd/ucpd/ucp-dev.yaml @@ -52,6 +52,8 @@ initialization: Applications.Datastores: "http://localhost:8080" Microsoft.Resources: "http://localhost:5017" kind: "UCPNative" + # This is the directory location which contains manifests to be registered. + manifestDirectory: "" identity: authMethod: default @@ -65,10 +67,6 @@ routing: # This is the default downstream (dynamic-rp) for UDT implementations. defaultDownstreamEndpoint: "http://localhost:8082" -initialization: - # This is the directory location which contains manifests to be registered. - manifestDirectory: "deploy/manifest/built-in-providers" - # Metrics configuration # port is not the same as metrics configuration in radius-self-hosted.yaml # so that we can run both services in debug mode. diff --git a/deploy/Chart/templates/ucp/configmaps.yaml b/deploy/Chart/templates/ucp/configmaps.yaml index 4fd08a954c..f6a93131a5 100644 --- a/deploy/Chart/templates/ucp/configmaps.yaml +++ b/deploy/Chart/templates/ucp/configmaps.yaml @@ -50,6 +50,7 @@ data: - id: "/planes/aws/aws" properties: kind: "AWS" + manifestDirectory: "" identity: authMethod: UCPCredential @@ -60,9 +61,6 @@ data: routing: defaultDownstreamEndpoint: "http://dynamic-rp.radius-sytem:8082" - initialization: - manifestDirectory: "deploy/manifest/built-in-providers" - metricsProvider: prometheus: enabled: true diff --git a/pkg/cli/cmd/resourceprovider/create/create_test.go b/pkg/cli/cmd/resourceprovider/create/create_test.go index 4e394c1db9..8ca83d351f 100644 --- a/pkg/cli/cmd/resourceprovider/create/create_test.go +++ b/pkg/cli/cmd/resourceprovider/create/create_test.go @@ -89,7 +89,6 @@ func Test_Validate(t *testing.T) { _ = cmd.MarkFlagFilename("from-file", "yaml", "json") return cmd, runner }, testcases) - } func Test_Run(t *testing.T) { diff --git a/pkg/ucp/config.go b/pkg/ucp/config.go index 7ef4a8ff56..dbb6088033 100644 --- a/pkg/ucp/config.go +++ b/pkg/ucp/config.go @@ -107,7 +107,8 @@ type RoutingConfig struct { // handles planes, and we need to support other kinds of resources. type InitializationConfig struct { // Planes is a list of planes to create at startup. - Planes []Plane `yaml:"planes,omitempty"` + Planes []Plane `yaml:"planes,omitempty"` + ManifestDirectory string `yaml:"manifestDirectory"` } // Plane is a configuration entry for a plane resource. This is used to create a plane resource at startup. diff --git a/pkg/ucp/hostoptions/providerconfig.go b/pkg/ucp/hostoptions/providerconfig.go deleted file mode 100644 index d77b362abc..0000000000 --- a/pkg/ucp/hostoptions/providerconfig.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2023 The Radius Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package hostoptions - -import ( - "github.com/radius-project/radius/pkg/components/database/databaseprovider" - "github.com/radius-project/radius/pkg/components/queue/queueprovider" - "github.com/radius-project/radius/pkg/components/secret/secretprovider" - metricsprovider "github.com/radius-project/radius/pkg/metrics/provider" - profilerprovider "github.com/radius-project/radius/pkg/profiler/provider" - "github.com/radius-project/radius/pkg/trace" - "github.com/radius-project/radius/pkg/ucp/config" - "github.com/radius-project/radius/pkg/ucp/rest" - "github.com/radius-project/radius/pkg/ucp/ucplog" -) - -// UCPConfig includes the resource provider configuration. -type UCPConfig struct { - DatabaseProvider databaseprovider.Options `yaml:"storageProvider"` - Planes []rest.Plane `yaml:"planes"` - SecretProvider secretprovider.SecretProviderOptions `yaml:"secretProvider"` - MetricsProvider metricsprovider.MetricsProviderOptions `yaml:"metricsProvider"` - ProfilerProvider profilerprovider.ProfilerProviderOptions `yaml:"profilerProvider"` - QueueProvider queueprovider.QueueProviderOptions `yaml:"queueProvider"` - TracerProvider trace.Options `yaml:"tracerProvider"` - Logging ucplog.LoggingOptions `yaml:"logging"` - Identity Identity `yaml:"identity,omitempty"` - UCP config.UCPOptions `yaml:"ucp"` - Location string `yaml:"location"` - Routing RoutingConfig `yaml:"routing"` - Initialization InitializationConfig `yaml:"initialization"` -} - -const ( - // AuthUCPCredential is the authentication method via UCP Credential API. - AuthUCPCredential = "UCPCredential" - // AuthDefault is the default authentication method, such as environment variables. - AuthDefault = "default" -) - -// Identity represents configuration options for authenticating with external systems like Azure and AWS. -type Identity struct { - // AuthMethod represents the method of authentication for authenticating with external systems like Azure and AWS. - AuthMethod string `yaml:"authMethod"` -} - -// RoutingConfig provides configuration for UCP routing. -type RoutingConfig struct { - // DefaultDownstreamEndpoint is the default destination when a resource provider does not provide a downstream endpoint. - // In practice, this points to the URL of dynamic-rp. - DefaultDownstreamEndpoint string `yaml:"defaultDownstreamEndpoint"` -} - -// InitializeConfig defines the configuration for initializing the UCP server. -// -// This includes resources that are added to UCP's data on startup. -type InitializationConfig struct { - // ManifestDirectory is the directory where UCP manifests are stored. - ManifestDirectory string `yaml:"manifestDirectory"` -} diff --git a/pkg/ucp/initializer/service.go b/pkg/ucp/initializer/service.go index 9da4e33d47..3d48dad2d7 100644 --- a/pkg/ucp/initializer/service.go +++ b/pkg/ucp/initializer/service.go @@ -27,25 +27,25 @@ import ( aztoken "github.com/radius-project/radius/pkg/azure/tokencredentials" "github.com/radius-project/radius/pkg/cli/manifest" "github.com/radius-project/radius/pkg/sdk" + "github.com/radius-project/radius/pkg/ucp" "github.com/radius-project/radius/pkg/ucp/api/v20231001preview" "github.com/radius-project/radius/pkg/ucp/hosting" - ucpoptions "github.com/radius-project/radius/pkg/ucp/hostoptions" + + //ucpoptions "github.com/radius-project/radius/pkg/ucp/hostoptions" "github.com/radius-project/radius/pkg/ucp/ucplog" ) // Service implements the hosting.Service interface for registering manifests. type Service struct { - ucpConnection sdk.Connection - options ucpoptions.UCPConfig + options *ucp.Options } var _ hosting.Service = (*Service)(nil) // NewService creates a server to register manifests. -func NewService(connection sdk.Connection, options ucpoptions.UCPConfig) *Service { +func NewService(options *ucp.Options) *Service { return &Service{ - ucpConnection: connection, - options: options, + options: options, } } @@ -54,7 +54,7 @@ func (s *Service) Name() string { return "initializer" } -func waitForServer(ctx context.Context, host, port string, retryInterval time.Duration, timeout time.Duration) error { +func waitForServer(ctx context.Context, host, port string, retryInterval time.Duration, connectionTimeout time.Duration, timeout time.Duration) error { address := net.JoinHostPort(host, port) deadline := time.Now().Add(timeout) @@ -63,7 +63,7 @@ func waitForServer(ctx context.Context, host, port string, retryInterval time.Du case <-ctx.Done(): return fmt.Errorf("connection attempts canceled or timed out: %w", ctx.Err()) default: - conn, err := net.DialTimeout("tcp", address, retryInterval) + conn, err := net.DialTimeout("tcp", address, connectionTimeout) if err == nil { conn.Close() return nil @@ -81,12 +81,12 @@ func waitForServer(ctx context.Context, host, port string, retryInterval time.Du func (w *Service) Run(ctx context.Context) error { logger := ucplog.FromContextOrDiscard(ctx) - if w.ucpConnection == nil || w.ucpConnection.Endpoint() == "" { + if w.options.UCP == nil || w.options.UCP.Endpoint() == "" { return fmt.Errorf("connection to UCP is not set") } // Parse the endpoint URL and extract host and port - parsedURL, err := url.Parse(w.ucpConnection.Endpoint()) + parsedURL, err := url.Parse(w.options.UCP.Endpoint()) if err != nil { return fmt.Errorf("failed to parse endpoint URL: %w", err) } @@ -98,14 +98,14 @@ func (w *Service) Run(ctx context.Context) error { logger.Info("Parsed Host and Port", "host", hostName, "port", port) // Attempt to connect to the server - err = waitForServer(ctx, hostName, port, 500*time.Millisecond, 5*time.Second) + err = waitForServer(ctx, hostName, port, 500*time.Millisecond, 500*time.Millisecond, 5*time.Second) if err != nil { logger.Error(err, "Server is not available for manifest registration") return nil } // Server is up, proceed to register manifests - manifestDir := w.options.Initialization.ManifestDirectory + manifestDir := w.options.Config.Initialization.ManifestDirectory if manifestDir == "" { logger.Info("No manifest directory specified") return nil @@ -117,12 +117,11 @@ func (w *Service) Run(ctx context.Context) error { return fmt.Errorf("error checking manifest directory: %w", err) } - clientOptions := sdk.NewClientOptions(w.ucpConnection) + clientOptions := sdk.NewClientOptions(w.options.UCP) clientFactory, err := v20231001preview.NewClientFactory(&aztoken.AnonymousCredential{}, clientOptions) if err != nil { - logger.Error(err, "Failed to create client factory") - return nil + return fmt.Errorf("error creating client factory: %w", err) } // Proceed with registering manifests diff --git a/pkg/ucp/server/server.go b/pkg/ucp/server/server.go index cc7c89ffce..74485a3d99 100644 --- a/pkg/ucp/server/server.go +++ b/pkg/ucp/server/server.go @@ -17,134 +17,18 @@ limitations under the License. package server import ( - "errors" - "fmt" - "os" - "strings" - "time" - - "github.com/radius-project/radius/pkg/kubeutil" - metricsprovider "github.com/radius-project/radius/pkg/metrics/provider" + "github.com/radius-project/radius/pkg/components/database/databaseprovider" metricsservice "github.com/radius-project/radius/pkg/metrics/service" profilerservice "github.com/radius-project/radius/pkg/profiler/service" - "github.com/radius-project/radius/pkg/sdk" "github.com/radius-project/radius/pkg/trace" "github.com/radius-project/radius/pkg/ucp" "github.com/radius-project/radius/pkg/ucp/backend" - "github.com/radius-project/radius/pkg/ucp/config" "github.com/radius-project/radius/pkg/ucp/data" - "github.com/radius-project/radius/pkg/ucp/databaseprovider" "github.com/radius-project/radius/pkg/ucp/frontend/api" "github.com/radius-project/radius/pkg/ucp/hosting" - "github.com/radius-project/radius/pkg/ucp/hostoptions" "github.com/radius-project/radius/pkg/ucp/initializer" - "github.com/radius-project/radius/pkg/ucp/queue/queueprovider" - "github.com/radius-project/radius/pkg/ucp/rest" - "github.com/radius-project/radius/pkg/ucp/secret/secretprovider" - "github.com/radius-project/radius/pkg/ucp/ucplog" - - kube_rest "k8s.io/client-go/rest" -) - -const ( - HTTPServerStopTimeout = time.Second * 10 - ServiceName = "ucp" ) -type Options struct { - Config *hostoptions.UCPConfig - Port string - DatabaseProviderOptions databaseprovider.Options - LoggingOptions ucplog.LoggingOptions - SecretProviderOptions secretprovider.SecretProviderOptions - QueueProviderOptions queueprovider.QueueProviderOptions - MetricsProviderOptions metricsprovider.MetricsProviderOptions - ProfilerProviderOptions profilerprovider.ProfilerProviderOptions - TracerProviderOptions trace.Options - TLSCertDir string - PathBase string - InitialPlanes []rest.Plane - Identity hostoptions.Identity - UCPConnection sdk.Connection - Location string -} - -const UCPProviderName = "System.Resources" - -// NewServerOptionsFromEnvironment creates a new Options struct from environment variables and returns it along with any errors. -func NewServerOptionsFromEnvironment(configFilePath string) (Options, error) { - basePath, ok := os.LookupEnv("BASE_PATH") - if ok && len(basePath) > 0 && (!strings.HasPrefix(basePath, "/") || strings.HasSuffix(basePath, "/")) { - return Options{}, errors.New("env: BASE_PATH must begin with '/' and must not end with '/'") - } - - tlsCertDir := os.Getenv("TLS_CERT_DIR") - port := os.Getenv("PORT") - if port == "" { - return Options{}, errors.New("UCP Port number must be set") - } - - opts, err := hostoptions.NewHostOptionsFromEnvironment(configFilePath) - if err != nil { - return Options{}, err - } - - storeOpts := opts.Config.DatabaseProvider - planes := opts.Config.Planes - secretOpts := opts.Config.SecretProvider - qproviderOpts := opts.Config.QueueProvider - metricsOpts := opts.Config.MetricsProvider - traceOpts := opts.Config.TracerProvider - profilerOpts := opts.Config.ProfilerProvider - loggingOpts := opts.Config.Logging - identity := opts.Config.Identity - // Set the default authentication method if AuthMethod is not set. - if identity.AuthMethod == "" { - identity.AuthMethod = hostoptions.AuthDefault - } - - location := opts.Config.Location - if location == "" { - location = "global" - } - - var cfg *kube_rest.Config - if opts.Config.UCP.Kind == config.UCPConnectionKindKubernetes { - cfg, err = kubeutil.NewClientConfig(&kubeutil.ConfigOptions{ - // TODO: Allow to use custom context via configuration. - https://github.com/radius-project/radius/issues/5433 - ContextName: "", - QPS: kubeutil.DefaultServerQPS, - Burst: kubeutil.DefaultServerBurst, - }) - if err != nil { - return Options{}, fmt.Errorf("failed to get kubernetes config: %w", err) - } - } - - ucpConn, err := config.NewConnectionFromUCPConfig(&opts.Config.UCP, cfg) - if err != nil { - return Options{}, err - } - - return Options{ - Config: opts.Config, - Port: port, - TLSCertDir: tlsCertDir, - PathBase: basePath, - DatabaseProviderOptions: storeOpts, - SecretProviderOptions: secretOpts, - QueueProviderOptions: qproviderOpts, - MetricsProviderOptions: metricsOpts, - TracerProviderOptions: traceOpts, - ProfilerProviderOptions: profilerOpts, - LoggingOptions: loggingOpts, - InitialPlanes: planes, - Identity: identity, - UCPConnection: ucpConn, - Location: location, - }, nil -} - // NewServer creates a new hosting.Host instance with services for API, EmbeddedETCD, Metrics, Profiler and Backend (if // enabled) based on the given Options. func NewServer(options *ucp.Options) (*hosting.Host, error) { @@ -174,7 +58,7 @@ func NewServer(options *ucp.Options) (*hosting.Host, error) { hostingServices = append(hostingServices, &trace.Service{Options: options.Config.Tracing}) - hostingServices = append(hostingServices, initializer.NewService(options.UCPConnection, *options.Config)) + hostingServices = append(hostingServices, initializer.NewService(options)) return &hosting.Host{ Services: hostingServices,