feat/multi provider support - #470
Conversation
31d11c8 to
f2aed7d
Compare
68eb544 to
b448d2a
Compare
|
Do not merge until the |
b448d2a to
1dd9e0a
Compare
Replace 'openconfig' with 'openconfig.networking.metal.ironcore.dev'. Signed-off-by: Sven Rosenzweig <sven.rosenzweig@sap.com>
With this commit, we do not use the provider flag anymore. The provider func now is loaded dynamically on every reconciliation. Requires the `device.spec.provider` field to be set on every device. Signed-off-by: Sven Rosenzweig <sven.rosenzweig@sap.com>
1dd9e0a to
33ea131
Compare
Merging this branch will decrease overall coverage
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
| // +required | ||
| Endpoint Endpoint `json:"endpoint"` | ||
|
|
||
| // Provider identifies the network provider plugin used to reconcile this Device and all CRDs that reference it. |
There was a problem hiding this comment.
| // Provider identifies the network provider plugin used to reconcile this Device and all CRDs that reference it. | |
| // Provider identifies the provider implementation used to reconcile this Device and all CRDs that reference it. |
| if device.Spec.Provider == "" { | ||
| return ctrl.Result{}, fmt.Errorf("device %q has no provider set", device.Name) | ||
| } |
There was a problem hiding this comment.
This is not possible as this is a required field. Therefore I wouldn't check this.
Applies to all controllers.
| // +required | ||
| // +immutable |
There was a problem hiding this comment.
| // +required | |
| // +immutable | |
| // Immutable. | |
| // +required | |
| // +kubebuilder:validation:MinLength=1 | |
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Provider is immutable" |
There is no +immutable marker.
|
|
||
| // Provider is the driver that will be used to create & delete the interface. | ||
| Provider provider.ProviderFunc | ||
| // Provider provider.ProviderFunc |
|
|
||
| // LoadProvider returns a provider instance cast to the requested interface type T. | ||
| // Returns NotFoundError if the provider is not registered, NotImplementedError if it does not implement T. | ||
| func LoadProvider[T Provider](providerName string) (T, error) { |
There was a problem hiding this comment.
| func LoadProvider[T Provider](providerName string) (T, error) { | |
| func LoadProvider[T Provider](providerName string) (zero T, _ error) { |
Safes you the var zero T statements.
| var zero T | ||
| return zero, NotFoundError{Message: fmt.Sprintf("Provider %q is not registered", providerName)} | ||
| } | ||
| genericProvider, ok := prov().(T) |
There was a problem hiding this comment.
| genericProvider, ok := prov().(T) | |
| provider, ok := prov().(T) |
That name doesn't seem fitting.
| type NotFoundError struct { | ||
| Message string | ||
| } | ||
|
|
||
| type NotImplementedError struct { | ||
| Message string | ||
| } | ||
|
|
||
| func (e NotImplementedError) Error() string { | ||
| return e.Message | ||
| } | ||
|
|
||
| func (e NotFoundError) Error() string { | ||
| return e.Message | ||
| } | ||
|
|
||
| func (e NotFoundError) Is(target error) bool { | ||
| _, ok := target.(NotFoundError) | ||
| return ok | ||
| } | ||
|
|
||
| func (e NotImplementedError) Is(target error) bool { | ||
| _, ok := target.(NotImplementedError) | ||
| return ok | ||
| } |
There was a problem hiding this comment.
| type NotFoundError struct { | |
| Message string | |
| } | |
| type NotImplementedError struct { | |
| Message string | |
| } | |
| func (e NotImplementedError) Error() string { | |
| return e.Message | |
| } | |
| func (e NotFoundError) Error() string { | |
| return e.Message | |
| } | |
| func (e NotFoundError) Is(target error) bool { | |
| _, ok := target.(NotFoundError) | |
| return ok | |
| } | |
| func (e NotImplementedError) Is(target error) bool { | |
| _, ok := target.(NotImplementedError) | |
| return ok | |
| } | |
| type NotFoundError struct | |
| func (e NotFoundError) Error() string | |
| func (e NotFoundError) Is(target error) bool | |
| type NotImplementedError struct | |
| func (e NotImplementedError) Error() string | |
| func (e NotImplementedError) Is(target error) bool |
This order is a bit better.
| ValidateSourceIP bool | ||
| Provider provider.ProvisioningProvider | ||
| Port int | ||
| // Provider provider.ProvisioningProvider |
| local_resource('controller-gen', 'make generate', deps=['api/', 'hack/boilerplate.go.txt']) | ||
| local_resource('crds', 'make install', deps=['api/']) | ||
|
|
||
| provider = os.getenv('PROVIDER', 'openconfig') |
There was a problem hiding this comment.
We wanted to still keep supporting this env variable for local development and set it on the device sample via the device_yaml function.
diff --git a/Tiltfile b/Tiltfile
index 65ac2499..0828a89e 100644
--- a/Tiltfile
+++ b/Tiltfile
@@ -21,6 +21,8 @@ docker_build('controller:latest', '.', only=[
local_resource('controller-gen', 'make generate', deps=['api/', 'hack/boilerplate.go.txt'])
local_resource('crds', 'make install', deps=['api/'])
+provider = os.getenv('PROVIDER', 'openconfig')
+
manager = kustomize('config/develop')
manager = str(manager)
@@ -30,6 +32,7 @@ k8s_resource('network-operator-controller-manager', resource_deps=['controller-g
# Sample resources with manual trigger mode
def device_yaml():
decoded = read_yaml_stream('./config/samples/v1alpha1_device.yaml')
+ decoded[0]['spec']['provider'] = provider
ip = str(local("docker run --rm busybox:1.37.0 nslookup -type=a host.docker.internal 2>/dev/null | grep 'Address:' | tail -n 1 | awk '{print $2}' || echo ''", quiet=True)).rstrip('\n')
if len(ip) > 0:
decoded[0]['spec']['endpoint']['address'] = ip+':9339'| // Provider identifies the network provider plugin used to reconcile this Device and all CRDs that reference it. | ||
| // +required | ||
| // +immutable | ||
| Provider string `json:"provider,omitempty"` |
There was a problem hiding this comment.
| Provider string `json:"provider,omitempty"` | |
| Provider string `json:"provider"` |
No omitempty when the field is required.
Migrate to Multi Provider Support
With this commit, we do not use the provider flag anymore.
The provider func now is loaded dynamically on every reconciliation.
Requires the
device.spec.providerfield to be set on every device.