From f1570f7e050109c41676e0b9b3aa6b7f251d24ee Mon Sep 17 00:00:00 2001 From: leoporoli Date: Thu, 22 Jun 2023 16:46:49 -0300 Subject: [PATCH] feat: Implemented rename enclave method in container engine lib (#755) ## Description: Implemented rename enclave method in container engine lib ## Is this change user facing? NO ## References (if applicable): This is part of the enclave pool project, more context here: https://www.notion.so/kurtosistech/Enclave-Pool-Project-7273552e53e44b0f931a57568cd170a0 --- ...cker_kurtosis_backend_enclave_functions.go | 8 ++++ ...etes_kurtosis_backend_enclave_functions.go | 30 ++++++++++++ .../kubernetes_manager/kubernetes_manager.go | 29 ++++++++++++ .../metrics_reporting_kurtosis_backend.go | 13 ++++++ .../remote_context_kurtosis_backend.go | 4 ++ .../lib/backend_interface/kurtosis_backend.go | 9 +++- .../mock_kurtosis_backend.go | 46 ++++++++++++++++++- 7 files changed, 137 insertions(+), 2 deletions(-) diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_enclave_functions.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_enclave_functions.go index 2581713a3a..972eb03b9f 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_enclave_functions.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_enclave_functions.go @@ -357,6 +357,14 @@ func (backend *DockerKurtosisBackend) DestroyEnclaves( return successfulNetworkRemovalEnclaveUuids, erroredEnclaveUuids, nil } +func (backend *DockerKurtosisBackend) RenameEnclave( + ctx context.Context, + enclaveUuid enclave.EnclaveUUID, + newName string, +) error { + return stacktrace.NewError("RenameEnclave isn't implemented for Docker yet") +} + // ==================================================================================================== // // Private helper methods diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_enclave_functions.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_enclave_functions.go index 65f68150ec..0d832de6ae 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_enclave_functions.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_enclave_functions.go @@ -157,6 +157,36 @@ func (backend *KubernetesKurtosisBackend) GetEnclaves( return matchingEnclaves, nil } +func (backend *KubernetesKurtosisBackend) RenameEnclave( + ctx context.Context, + enclaveUuid enclave.EnclaveUUID, + newName string, +) error { + + enclave, kubernetesResources, err := backend.getSingleEnclaveAndKubernetesResources(ctx, enclaveUuid) + if err != nil { + return stacktrace.Propagate(err, "An error occurred getting enclave object and Kubernetes resources for enclave ID '%v'", enclaveUuid) + } + namespace := kubernetesResources.namespace + if namespace == nil { + return stacktrace.NewError("Cannot rename enclave '%v' because no Kubernetes namespace exists for it", enclaveUuid) + } + + updatedAnnotations := map[string]string{ + kubernetes_annotation_key_consts.EnclaveNameAnnotationKey.GetString(): newName, + } + + namespaceApplyConfigurator := func(namespaceApplyConfig *applyconfigurationsv1.NamespaceApplyConfiguration) { + namespaceApplyConfig.WithAnnotations(updatedAnnotations) + } + + if _, err := backend.kubernetesManager.UpdateNamespace(ctx, namespace.GetName(), namespaceApplyConfigurator); err != nil { + return stacktrace.Propagate(err, "An error occurred renaming enclave with UUID '%v', renaming from '%s' to '%s'", enclaveUuid, enclave.GetName(), newName) + } + + return nil +} + func (backend *KubernetesKurtosisBackend) StopEnclaves( ctx context.Context, filters *enclave.EnclaveFilters, diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_manager/kubernetes_manager.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_manager/kubernetes_manager.go index 3599fbf29d..a2ebf9021e 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_manager/kubernetes_manager.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_manager/kubernetes_manager.go @@ -432,6 +432,35 @@ func (manager *KubernetesManager) CreateNamespace( return namespaceResult, nil } +func (manager *KubernetesManager) UpdateNamespace( + ctx context.Context, + namespaceName string, + // We use a configurator, rather than letting the user pass in their own NamespaceApplyConfiguration, so that we ensure + // they use the constructor (and don't do struct instantiation and forget to add the object name, etc. which + // would result in removing the object name) + updateConfigurator func(configuration *applyconfigurationsv1.NamespaceApplyConfiguration), +) (*apiv1.Namespace, error) { + updatesToApply := applyconfigurationsv1.Namespace(namespaceName) + updateConfigurator(updatesToApply) + + namespaceClient := manager.kubernetesClientSet.CoreV1().Namespaces() + + applyOpts := metav1.ApplyOptions{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + DryRun: nil, + Force: true, //We need to use force to avoid conflict errors + FieldManager: fieldManager, + } + result, err := namespaceClient.Apply(ctx, updatesToApply, applyOpts) + if err != nil { + return nil, stacktrace.Propagate(err, "Failed to update namespace '%v' ", namespaceName) + } + return result, nil +} + func (manager *KubernetesManager) RemoveNamespace(ctx context.Context, namespace *apiv1.Namespace) error { name := namespace.Name namespaceClient := manager.kubernetesClientSet.CoreV1().Namespaces() diff --git a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go index e6a3fa28de..2f1f1c9bd9 100644 --- a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go @@ -120,6 +120,19 @@ func (backend *MetricsReportingKurtosisBackend) GetEnclaves( return results, nil } +func (backend *MetricsReportingKurtosisBackend) RenameEnclave( + ctx context.Context, + enclaveUuid enclave.EnclaveUUID, + newName string, +) error { + + if err := backend.underlying.RenameEnclave(ctx, enclaveUuid, newName); err != nil { + return stacktrace.Propagate(err, "An error occurred renaming enclave with UUID '%v' to '%s'", enclaveUuid, newName) + } + + return nil +} + func (backend *MetricsReportingKurtosisBackend) StopEnclaves( ctx context.Context, filters *enclave.EnclaveFilters, diff --git a/container-engine-lib/lib/backend_impls/remote_context_backend/remote_context_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/remote_context_backend/remote_context_kurtosis_backend.go index fa742936b8..b01cf49374 100644 --- a/container-engine-lib/lib/backend_impls/remote_context_backend/remote_context_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/remote_context_backend/remote_context_kurtosis_backend.go @@ -91,6 +91,10 @@ func (backend *RemoteContextKurtosisBackend) GetEnclaves(ctx context.Context, fi return backend.remoteKurtosisBackend.GetEnclaves(ctx, filters) } +func (backend *RemoteContextKurtosisBackend) RenameEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, newName string) error { + return backend.remoteKurtosisBackend.RenameEnclave(ctx, enclaveUuid, newName) +} + func (backend *RemoteContextKurtosisBackend) StopEnclaves(ctx context.Context, filters *enclave.EnclaveFilters) (successfulEnclaveIds map[enclave.EnclaveUUID]bool, erroredEnclaveIds map[enclave.EnclaveUUID]error, resultErr error) { return backend.remoteKurtosisBackend.StopEnclaves(ctx, filters) } diff --git a/container-engine-lib/lib/backend_interface/kurtosis_backend.go b/container-engine-lib/lib/backend_interface/kurtosis_backend.go index 22444febc9..c7ec40d81b 100644 --- a/container-engine-lib/lib/backend_interface/kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/kurtosis_backend.go @@ -67,9 +67,16 @@ type KurtosisBackend interface { // Dumps all of Kurtosis (engines + all enclaves) DumpKurtosis(ctx context.Context, outputDirpath string) error - // Creates an enclave with the given enclave ID + // Creates an enclave with the given enclave UUID CreateEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, enclaveName string, isPartitioningEnabled bool) (*enclave.Enclave, error) + // Rename an enclave with a new name by UUID + RenameEnclave( + ctx context.Context, + enclaveUuid enclave.EnclaveUUID, + newName string, + ) error + // Gets enclaves matching the given filters GetEnclaves( ctx context.Context, diff --git a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go index b0512ed3df..6fd6dd1df4 100644 --- a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.22.1. DO NOT EDIT. +// Code generated by mockery v2.29.0. DO NOT EDIT. package backend_interface @@ -1609,6 +1609,50 @@ func (_c *MockKurtosisBackend_RegisterUserServices_Call) RunAndReturn(run func(c return _c } +// RenameEnclave provides a mock function with given fields: ctx, enclaveUuid, newName +func (_m *MockKurtosisBackend) RenameEnclave(ctx context.Context, enclaveUuid enclave.EnclaveUUID, newName string) error { + ret := _m.Called(ctx, enclaveUuid, newName) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, enclave.EnclaveUUID, string) error); ok { + r0 = rf(ctx, enclaveUuid, newName) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockKurtosisBackend_RenameEnclave_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RenameEnclave' +type MockKurtosisBackend_RenameEnclave_Call struct { + *mock.Call +} + +// RenameEnclave is a helper method to define mock.On call +// - ctx context.Context +// - enclaveUuid enclave.EnclaveUUID +// - newName string +func (_e *MockKurtosisBackend_Expecter) RenameEnclave(ctx interface{}, enclaveUuid interface{}, newName interface{}) *MockKurtosisBackend_RenameEnclave_Call { + return &MockKurtosisBackend_RenameEnclave_Call{Call: _e.mock.On("RenameEnclave", ctx, enclaveUuid, newName)} +} + +func (_c *MockKurtosisBackend_RenameEnclave_Call) Run(run func(ctx context.Context, enclaveUuid enclave.EnclaveUUID, newName string)) *MockKurtosisBackend_RenameEnclave_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(enclave.EnclaveUUID), args[2].(string)) + }) + return _c +} + +func (_c *MockKurtosisBackend_RenameEnclave_Call) Return(_a0 error) *MockKurtosisBackend_RenameEnclave_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockKurtosisBackend_RenameEnclave_Call) RunAndReturn(run func(context.Context, enclave.EnclaveUUID, string) error) *MockKurtosisBackend_RenameEnclave_Call { + _c.Call.Return(run) + return _c +} + // RunNetworkingSidecarExecCommands provides a mock function with given fields: ctx, enclaveUuid, networkingSidecarsCommands func (_m *MockKurtosisBackend) RunNetworkingSidecarExecCommands(ctx context.Context, enclaveUuid enclave.EnclaveUUID, networkingSidecarsCommands map[service.ServiceUUID][]string) (map[service.ServiceUUID]*exec_result.ExecResult, map[service.ServiceUUID]error, error) { ret := _m.Called(ctx, enclaveUuid, networkingSidecarsCommands)