Skip to content

Commit

Permalink
Add defaults for deployment manager backend URL and token
Browse files Browse the repository at this point in the history
Currently the backend URL and token don't have defaults. That means that
the user has to explicitly set them in the custom resource that
represents the O2 IMS deployment. That is reasonable for the URL, but
not for the token, because it is the token of a service account that is
created by the operator. That means that the user would have to create
the service account in advance, wait for the token to be created and
then read it and update the custom resource. That isn't practical. To
avoid that this patch changes the operator so that the token is the
default URL of the Kubernetes API server and the token is taken from the
`/run/secrets/kubernetes.io/serviceaccount/token` file.

Signed-off-by: Juan Hernandez <[email protected]>
Co-authored-by: Irina Mihai <[email protected]>
  • Loading branch information
jhernand and irinamihai committed Apr 3, 2024
1 parent fb5a1a1 commit 43df8a4
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 34 deletions.
2 changes: 1 addition & 1 deletion api/v1alpha1/orano2ims_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type ORANO2IMSSpec struct {
//+kubebuilder:default=false
DeploymentManagerServer bool `json:"deploymentManagerServer"`
//+kubebuilder:default=false
ResourceServer bool `json:"resourceServer"`
ResourceServer bool `json:"resourceServer"`
AlarmSubscriptionServer bool `json:"alarmSubscriptionServer"`
//+optional
IngressHost string `json:"ingressHost,omitempty"`
Expand Down
7 changes: 3 additions & 4 deletions config/crd/bases/oran.openshift.io_orano2imses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ spec:
spec:
description: ORANO2IMSSpec defines the desired state of ORANO2IMS
properties:
alarmSubscriptionServer:
type: boolean
backendToken:
type: string
backendType:
Expand All @@ -54,9 +56,6 @@ spec:
items:
type: string
type: array
alarmSubscriptionServer:
default: false
type: boolean
ingressHost:
type: string
metadataServer:
Expand All @@ -68,9 +67,9 @@ spec:
searchAPIBackendURL:
type: string
required:
- alarmSubscriptionServer
- cloudId
- deploymentManagerServer
- AlarmSubscriptionServer
- metadataServer
- resourceServer
type: object
Expand Down
4 changes: 2 additions & 2 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ generatorOptions:

images:
- name: controller
newName: quay.io/imihai/oran-o2ims-operator
newTag: 4.16.0
newName: quay.io/jhernand/o2ims-operator
newTag: "2"
68 changes: 65 additions & 3 deletions internal/cmd/server/start_deployment_manager_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"log/slog"
"net/http"
"os"
"strings"

"github.com/gorilla/mux"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -68,6 +70,11 @@ func DeploymentManagerServer() *cobra.Command {
"",
"Token for authenticating to the backend server.",
)
_ = flags.String(
backendTokenFileFlagName,
"",
"File containing the token for authenticating to the backend server.",
)
_ = flags.StringArray(
extensionsFlagName,
[]string{},
Expand Down Expand Up @@ -173,6 +180,15 @@ func (c *DeploymentManagerServerCommand) run(cmd *cobra.Command, argv []string)
)
return exit.Error(1)
}
backendTokenFile, err := flags.GetString(backendTokenFileFlagName)
if err != nil {
logger.Error(
"Failed to get backend token file flag",
slog.String("flag", backendTokenFileFlagName),
slog.String("error", err.Error()),
)
return exit.Error(1)
}
extensions, err := flags.GetStringArray(extensionsFlagName)
if err != nil {
logger.Error(
Expand All @@ -182,11 +198,56 @@ func (c *DeploymentManagerServerCommand) run(cmd *cobra.Command, argv []string)
)
return exit.Error(1)
}

// Check that the backend token and token file haven't been simultaneously provided:
if backendToken != "" && backendTokenFile != "" {
logger.Error(
"Backend token and token file have both been provided, but they are incompatible",
slog.Any(
"flags",
[]string{
backendTokenFlagName,
backendTokenFileFlagName,
},
),
slog.String("!token", backendToken),
slog.String("token_file", backendTokenFile),
)
return exit.Error(1)
}

// Read the backend token file if needed:
if backendToken == "" && backendTokenFile != "" {
backendTokenData, err := os.ReadFile(backendTokenFile)
if err != nil {
logger.Error(
"Failed to read backend token file",
slog.String("file", backendTokenFile),
slog.String("error", err.Error()),
)
return exit.Error(1)
}
backendToken = strings.TrimSpace(string(backendTokenData))
logger.Info(
"Loaded backend token from file",
slog.String("file", backendTokenFile),
slog.String("!token", backendToken),
)
}

// Check that we have a token:
if backendToken == "" {
logger.Error("Backend token or token file must be provided")
return exit.Error(1)
}

// Write the backend details to the log:
logger.Info(
"Backend details",
slog.String("type", string(backendType)),
slog.String("url", backendURL),
slog.String("!token", backendToken),
slog.String("token_file", backendTokenFile),
slog.Any("extensions", extensions),
)

Expand Down Expand Up @@ -312,7 +373,8 @@ func (c *DeploymentManagerServerCommand) run(cmd *cobra.Command, argv []string)

// Names of command line flags:
const (
backendTypeFlagName = "backend-type"
backendTokenFlagName = "backend-token"
backendURLFlagName = "backend-url"
backendTypeFlagName = "backend-type"
backendTokenFlagName = "backend-token"
backendTokenFileFlagName = "backend-token-file"
backendURLFlagName = "backend-url"
)
5 changes: 4 additions & 1 deletion internal/controllers/orano2ims_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ func (r *ORANO2IMSReconciler) deployServer(ctx context.Context, orano2ims *oranv
},
}

deploymentContainerArgs := utils.BuildServerContainerArgs(orano2ims, serverName)
deploymentContainerArgs, err := utils.BuildServerContainerArgs(orano2ims, serverName)
if err != nil {
return err
}

// Build the deployment's spec.
deploymentSpec := appsv1.DeploymentSpec{
Expand Down
6 changes: 6 additions & 0 deletions internal/controllers/utils/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,9 @@ var (
"--api-listener-tls-key=/secrets/tls/tls.key",
}
)

// Default values for backend URL and token:
const (
defaultBackendURL = "https://kubernetes.default.svc"
defaultBackendTokenFile = "/run/secrets/kubernetes.io/serviceaccount/token"
)
69 changes: 54 additions & 15 deletions internal/controllers/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"reflect"
"slices"

ctrl "sigs.k8s.io/controller-runtime"

Expand Down Expand Up @@ -150,40 +151,78 @@ func GetDeploymentVolumeMounts(serverName string) []corev1.VolumeMount {
return []corev1.VolumeMount{}
}

func BuildServerContainerArgs(orano2ims *oranv1alpha1.ORANO2IMS, serverName string) []string {
func BuildServerContainerArgs(orano2ims *oranv1alpha1.ORANO2IMS,
serverName string) (result []string, err error) {
if serverName == ORANO2IMSMetadataServerName {
containerArgs := MetadataServerArgs
containerArgs = append(containerArgs,
result = slices.Clone(MetadataServerArgs)
result = append(
result,
fmt.Sprintf("--cloud-id=%s", orano2ims.Spec.CloudId),
fmt.Sprintf("--external-address=https://%s", orano2ims.Spec.IngressHost))

return containerArgs
return
}

if serverName == ORANO2IMSResourceServerName {
containerArgs := ResourceServerArgs
containerArgs = append(containerArgs,
result = slices.Clone(ResourceServerArgs)
result = append(
result,
fmt.Sprintf("--cloud-id=%s", orano2ims.Spec.CloudId),
fmt.Sprintf("--backend-url=%s", orano2ims.Spec.SearchAPIBackendURL),
fmt.Sprintf("--backend-token=%s", orano2ims.Spec.BackendToken))

return containerArgs
return
}

if serverName == ORANO2IMSDeploymentManagerServerName {
containerArgs := DeploymentManagerServerArgs
result = slices.Clone(DeploymentManagerServerArgs)

containerArgs = append(containerArgs,
// Set the cloud identifier:
result = append(
result,
fmt.Sprintf("--cloud-id=%s", orano2ims.Spec.CloudId),
fmt.Sprintf("--backend-url=%s", orano2ims.Spec.BackendURL),
fmt.Sprintf("--backend-token=%s", orano2ims.Spec.BackendToken),
fmt.Sprintf("--backend-type=%s", orano2ims.Spec.BackendType))
)

// Set the backend type:
if orano2ims.Spec.BackendType != "" {
result = append(
result,
fmt.Sprintf("--backend-type=%s", orano2ims.Spec.BackendType),
)
}

// If no backend URL has been provided then use the default URL of the Kubernetes
// API server of the cluster:
backendURL := orano2ims.Spec.BackendURL
if backendURL == "" {
backendURL = defaultBackendURL
}
result = append(
result,
fmt.Sprintf("--backend-url=%s", backendURL),
)

// If no backend token has been provided then use the token of the service account
// that will eventually execute the server. Note that the file may not exist,
// but we can't check it here as that will be a different pod.
if orano2ims.Spec.BackendToken != "" {
result = append(
result,
fmt.Sprintf("--backend-token=%s", orano2ims.Spec.BackendToken),
)
} else {
result = append(
result,
fmt.Sprintf("--backend-token-file=%s", defaultBackendTokenFile),
)
}

// Add the extensions:
extensionsArgsArray := extensionsToExtensionArgs(orano2ims.Spec.Extensions)
containerArgs = append(containerArgs, extensionsArgsArray...)
result = append(result, extensionsArgsArray...)

return containerArgs
return
}

return nil
return
}
16 changes: 8 additions & 8 deletions internal/controllers/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ var _ = Describe("ExtensionUtils", func() {
},
},
}
actualArgs := BuildServerContainerArgs(orano2ims, ORANO2IMSDeploymentManagerServerName)
actualArgs, err := BuildServerContainerArgs(orano2ims, ORANO2IMSDeploymentManagerServerName)
Expect(err).ToNot(HaveOccurred())
expectedArgs := DeploymentManagerServerArgs
expectedArgs = append(expectedArgs,
fmt.Sprintf("--cloud-id=%s", orano2ims.Spec.CloudId),
fmt.Sprintf("--backend-url=%s", orano2ims.Spec.BackendURL),
fmt.Sprintf("--backend-token=%s", orano2ims.Spec.BackendToken),
fmt.Sprintf("--backend-type=%s", orano2ims.Spec.BackendType),
fmt.Sprintf("--backend-url=%s", defaultBackendURL),
fmt.Sprintf("--backend-token-file=%s", defaultBackendTokenFile),
)
expectedArgs = append(expectedArgs,
"--extensions=.metadata.labels[\"name\"] as $name |\n{\n name: $name,\n alias: $name\n}\n",
Expand All @@ -100,13 +100,13 @@ var _ = Describe("ExtensionUtils", func() {
},
}

actualArgs := BuildServerContainerArgs(orano2ims, ORANO2IMSDeploymentManagerServerName)
actualArgs, err := BuildServerContainerArgs(orano2ims, ORANO2IMSDeploymentManagerServerName)
Expect(err).ToNot(HaveOccurred())
expectedArgs := DeploymentManagerServerArgs
expectedArgs = append(expectedArgs,
fmt.Sprintf("--cloud-id=%s", orano2ims.Spec.CloudId),
fmt.Sprintf("--backend-url=%s", orano2ims.Spec.BackendURL),
fmt.Sprintf("--backend-token=%s", orano2ims.Spec.BackendToken),
fmt.Sprintf("--backend-type=%s", orano2ims.Spec.BackendType),
fmt.Sprintf("--backend-url=%s", defaultBackendURL),
fmt.Sprintf("--backend-token-file=%s", defaultBackendTokenFile),
)
Expect(actualArgs).To(Equal(expectedArgs))
})
Expand Down

0 comments on commit 43df8a4

Please sign in to comment.