diff --git a/internal/networkinterfaceplugin/apinet.go b/internal/networkinterfaceplugin/apinet.go index 778cefae..8c5865ed 100644 --- a/internal/networkinterfaceplugin/apinet.go +++ b/internal/networkinterfaceplugin/apinet.go @@ -5,11 +5,14 @@ package networkinterfaceplugin import ( "fmt" + "time" + + "github.com/spf13/pflag" apinetv1alpha1 "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1" providernetworkinterface "github.com/ironcore-dev/libvirt-provider/internal/plugins/networkinterface" "github.com/ironcore-dev/libvirt-provider/internal/plugins/networkinterface/apinet" - "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -18,9 +21,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -var ( - scheme = runtime.NewScheme() -) +var scheme = runtime.NewScheme() func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) @@ -28,8 +29,10 @@ func init() { } type apinetOptions struct { - APInetNodeName string - ApinetKubeconfig string + APInetNodeName string + ApinetKubeconfig string + APInetPollingDuration time.Duration + APInetPollingInterval time.Duration } func (o *apinetOptions) PluginName() string { @@ -39,6 +42,8 @@ func (o *apinetOptions) PluginName() string { func (o *apinetOptions) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&o.APInetNodeName, "apinet-node-name", "", "APInet node name") fs.StringVar(&o.ApinetKubeconfig, "apinet-kubeconfig", "", "Path to the kubeconfig file for the apinet-cluster.") + fs.DurationVar(&o.APInetPollingDuration, "apinet-polling-duration", time.Second*30, "The maximum time the apinet plugin will wait until the networkinterface becomes ready.") + fs.DurationVar(&o.APInetPollingInterval, "apinet-polling-interval", time.Second*1, "The polling interval the apinet plugin uses to check if the networkinterface became ready.") } func (o *apinetOptions) NetworkInterfacePlugin() (providernetworkinterface.Plugin, func(), error) { @@ -67,7 +72,7 @@ func (o *apinetOptions) NetworkInterfacePlugin() (providernetworkinterface.Plugi return nil, nil, fmt.Errorf("failed to initialize api-net client: %w", err) } - return apinet.NewPlugin(o.APInetNodeName, apinetClient), nil, nil + return apinet.NewPlugin(o.APInetNodeName, apinetClient, o.APInetPollingDuration, o.APInetPollingInterval), nil, nil } func init() { diff --git a/internal/plugins/networkinterface/apinet/apinet.go b/internal/plugins/networkinterface/apinet/apinet.go index c8c14331..2f99307c 100644 --- a/internal/plugins/networkinterface/apinet/apinet.go +++ b/internal/plugins/networkinterface/apinet/apinet.go @@ -15,12 +15,14 @@ import ( "time" "github.com/google/uuid" + apinetv1alpha1 "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1" apinet "github.com/ironcore-dev/ironcore-net/apimachinery/api/net" "github.com/ironcore-dev/ironcore-net/apinetlet/provider" "github.com/ironcore-dev/libvirt-provider/api" providerhost "github.com/ironcore-dev/libvirt-provider/internal/host" providernetworkinterface "github.com/ironcore-dev/libvirt-provider/internal/plugins/networkinterface" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -34,24 +36,32 @@ const ( defaultAPINetConfigFile = "api-net.json" - perm = 0777 - filePerm = 0666 + perm = 0o777 + filePerm = 0o666 pluginAPInet = "apinet" ) type Plugin struct { - nodeName string - host providerhost.LibvirtHost - apinetClient client.Client + nodeName string + host providerhost.LibvirtHost + apinetClient client.Client + pollingInterval time.Duration + pollingDuration time.Duration } -func NewPlugin(nodeName string, client client.Client) providernetworkinterface.Plugin { +func NewPlugin(nodeName string, client client.Client, duration, interval time.Duration) providernetworkinterface.Plugin { return &Plugin{ - nodeName: nodeName, - apinetClient: client, + nodeName: nodeName, + apinetClient: client, + pollingDuration: duration, + pollingInterval: interval, } } +func GetAPInetPlugin() *Plugin { + return &Plugin{} +} + func (p *Plugin) Init(host providerhost.LibvirtHost) error { p.host = host return nil @@ -69,11 +79,11 @@ type apiNetNetworkInterfaceConfig struct { Namespace string `json:"namespace"` } -func (p *Plugin) apiNetNetworkInterfaceConfigFile(machineID string, networkInterfaceName string) string { +func (p *Plugin) apiNetNetworkInterfaceConfigFile(machineID, networkInterfaceName string) string { return filepath.Join(p.host.MachineNetworkInterfaceDir(machineID, networkInterfaceName), defaultAPINetConfigFile) } -func (p *Plugin) writeAPINetNetworkInterfaceConfig(machineID string, networkInterfaceName string, cfg *apiNetNetworkInterfaceConfig) error { +func (p *Plugin) writeAPINetNetworkInterfaceConfig(machineID, networkInterfaceName string, cfg *apiNetNetworkInterfaceConfig) error { data, err := json.Marshal(cfg) if err != nil { return err @@ -82,7 +92,7 @@ func (p *Plugin) writeAPINetNetworkInterfaceConfig(machineID string, networkInte return os.WriteFile(p.apiNetNetworkInterfaceConfigFile(machineID, networkInterfaceName), data, filePerm) } -func (p *Plugin) readAPINetNetworkInterfaceConfig(machineID string, networkInterfaceName string) (*apiNetNetworkInterfaceConfig, error) { +func (p *Plugin) readAPINetNetworkInterfaceConfig(machineID, networkInterfaceName string) (*apiNetNetworkInterfaceConfig, error) { data, err := os.ReadFile(p.apiNetNetworkInterfaceConfigFile(machineID, networkInterfaceName)) if err != nil { return nil, err @@ -95,7 +105,7 @@ func (p *Plugin) readAPINetNetworkInterfaceConfig(machineID string, networkInter return cfg, nil } -func (p *Plugin) APInetNicName(machineID string, networkInterfaceName string) string { +func (p *Plugin) APInetNicName(machineID, networkInterfaceName string) string { return uuid.NewHash(sha256.New(), uuid.Nil, []byte(fmt.Sprintf("%s/%s", machineID, networkInterfaceName)), 5).String() } @@ -176,7 +186,7 @@ func (p *Plugin) Apply(ctx context.Context, spec *api.NetworkInterfaceSpec, mach log.V(1).Info("Waiting for apinet network interface to become ready") apinetNicKey := client.ObjectKeyFromObject(apinetNic) - if err := wait.PollUntilContextTimeout(ctx, 50*time.Millisecond, 5*time.Second, true, func(ctx context.Context) (done bool, err error) { + if err := wait.PollUntilContextTimeout(ctx, p.pollingInterval, p.pollingDuration, true, func(ctx context.Context) (done bool, err error) { if err := p.apinetClient.Get(ctx, apinetNicKey, apinetNic); err != nil { return false, fmt.Errorf("error getting apinet nic %s: %w", apinetNicKey, err) } @@ -259,7 +269,7 @@ func getHostDevice(apinetNic *apinetv1alpha1.NetworkInterface) (*providernetwork } } -func (p *Plugin) Delete(ctx context.Context, computeNicName string, machineID string) error { +func (p *Plugin) Delete(ctx context.Context, computeNicName, machineID string) error { log := ctrl.LoggerFrom(ctx) log.V(1).Info("Reading APINet network interface config file")