From 1a4686bf4f0347dda30da4b0edb5da3f99cd87bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20R=C3=B6hrich?= Date: Thu, 22 Aug 2024 13:51:30 +0200 Subject: [PATCH] IPPool and LoadBalancer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More functionality, especially around the LoadBalancer resource Signed-off-by: Moritz Röhrich --- internal/provider/ippool/resource_ippool.go | 12 ++-- .../ippool/resource_ippool_constructor.go | 2 +- .../loadbalancer/resource_loadbalancer.go | 58 ++++++++++++++++++- .../resource_loadbalancer_constructor.go | 23 +++++++- internal/tests/resource_ippool_test.go | 3 +- internal/tests/resource_loadbalancer_test.go | 38 ++++++++++++ pkg/constants/constants_loadbalancer.go | 10 ++-- 7 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 internal/tests/resource_loadbalancer_test.go diff --git a/internal/provider/ippool/resource_ippool.go b/internal/provider/ippool/resource_ippool.go index 08a3096d..bd2659d1 100644 --- a/internal/provider/ippool/resource_ippool.go +++ b/internal/provider/ippool/resource_ippool.go @@ -65,7 +65,8 @@ func resourceIPPoolRead(ctx context.Context, data *schema.ResourceData, meta int ippool, err := c.HarvesterLoadbalancerClient. LoadbalancerV1beta1(). - IPPools().Get(ctx, name, metav1.GetOptions{}) + IPPools(). + Get(ctx, name, metav1.GetOptions{}) if err != nil { return diag.FromErr(err) } @@ -82,7 +83,8 @@ func resourceIPPoolUpdate(ctx context.Context, data *schema.ResourceData, meta i obj, err := c.HarvesterLoadbalancerClient. LoadbalancerV1beta1(). - IPPools().Get(ctx, name, metav1.GetOptions{}) + IPPools(). + Get(ctx, name, metav1.GetOptions{}) if err != nil { return diag.FromErr(err) } @@ -94,7 +96,8 @@ func resourceIPPoolUpdate(ctx context.Context, data *schema.ResourceData, meta i ippool, err := c.HarvesterLoadbalancerClient. LoadbalancerV1beta1(). - IPPools().Update(ctx, toUpdate.(*loadbalancerv1.IPPool), metav1.UpdateOptions{}) + IPPools(). + Update(ctx, toUpdate.(*loadbalancerv1.IPPool), metav1.UpdateOptions{}) if err != nil { return diag.FromErr(err) } @@ -110,7 +113,8 @@ func resourceIPPoolDelete(ctx context.Context, data *schema.ResourceData, meta i err = c.HarvesterLoadbalancerClient. LoadbalancerV1beta1(). - IPPools().Delete(ctx, name, metav1.DeleteOptions{}) + IPPools(). + Delete(ctx, name, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { return diag.FromErr(err) } diff --git a/internal/provider/ippool/resource_ippool_constructor.go b/internal/provider/ippool/resource_ippool_constructor.go index 54bb516f..c183cf65 100644 --- a/internal/provider/ippool/resource_ippool_constructor.go +++ b/internal/provider/ippool/resource_ippool_constructor.go @@ -82,7 +82,7 @@ func (c *Constructor) subresourceIPPoolRangeParser(data interface{}) error { func (c *Constructor) subresourceIPPoolSelectorParser(data interface{}) error { ippoolSelector := data.(map[string]interface{}) - priority := uint32(ippoolSelector[constants.FieldSelectorPriority].(int)) + priority := ippoolSelector[constants.FieldSelectorPriority].(uint32) network := ippoolSelector[constants.FieldSelectorNetwork].(string) scopesData := ippoolSelector[constants.SubresourceTypeIPPoolSelectorScope].([]interface{}) diff --git a/internal/provider/loadbalancer/resource_loadbalancer.go b/internal/provider/loadbalancer/resource_loadbalancer.go index 6e439c8f..818950f2 100644 --- a/internal/provider/loadbalancer/resource_loadbalancer.go +++ b/internal/provider/loadbalancer/resource_loadbalancer.go @@ -5,6 +5,7 @@ import ( "time" loadbalancerv1 "github.com/harvester/harvester-load-balancer/pkg/apis/loadbalancer.harvesterhci.io/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -57,14 +58,67 @@ func resourceLoadBalancerCreate(ctx context.Context, data *schema.ResourceData, } func resourceLoadBalancerRead(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { - return diag.FromErr(nil) + c := meta.(*client.Client) + namespace, name, err := helper.IDParts(data.Id()) + if err != nil { + return diag.FromErr(err) + } + + loadbalancer, err := c.HarvesterLoadbalancerClient. + LoadbalancerV1beta1(). + LoadBalancers(namespace). + Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return diag.FromErr(err) + } + + return diag.FromErr(resourceLoadBalancerImport(data, loadbalancer)) } func resourceLoadBalancerUpdate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { - return diag.FromErr(nil) + c := meta.(*client.Client) + namespace, name, err := helper.IDParts(data.Id()) + if err != nil { + return diag.FromErr(err) + } + + obj, err := c.HarvesterLoadbalancerClient. + LoadbalancerV1beta1(). + LoadBalancers(namespace). + Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return diag.FromErr(err) + } + + toUpdate, err := util.ResourceConstruct(data, Updater(obj)) + if err != nil { + return diag.FromErr(err) + } + + loadbalancer, err := c.HarvesterLoadbalancerClient. + LoadbalancerV1beta1(). + LoadBalancers(namespace). + Update(ctx, toUpdate.(*loadbalancerv1.LoadBalancer), metav1.UpdateOptions{}) + if err != nil { + return diag.FromErr(err) + } + return diag.FromErr(resourceLoadBalancerImport(data, loadbalancer)) } func resourceLoadBalancerDelete(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { + c := meta.(*client.Client) + namespace, name, err := helper.IDParts(data.Id()) + if err != nil { + return diag.FromErr(err) + } + + err = c.HarvesterLoadbalancerClient. + LoadbalancerV1beta1(). + LoadBalancers(namespace). + Delete(ctx, name, metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return diag.FromErr(err) + } return diag.FromErr(nil) } diff --git a/internal/provider/loadbalancer/resource_loadbalancer_constructor.go b/internal/provider/loadbalancer/resource_loadbalancer_constructor.go index 4f105a17..14516214 100644 --- a/internal/provider/loadbalancer/resource_loadbalancer_constructor.go +++ b/internal/provider/loadbalancer/resource_loadbalancer_constructor.go @@ -72,6 +72,9 @@ func Creator(namespace, name string) util.Constructor { } func Updater(loadbalancer *loadbalancerv1.LoadBalancer) util.Constructor { + loadbalancer.Spec.Listeners = []loadbalancerv1.Listener{} + loadbalancer.Spec.HealthCheck = &loadbalancerv1.HealthCheck{} + return newLoadBalancerConstructor(loadbalancer) } @@ -102,9 +105,9 @@ func (c *Constructor) subresourceLoadBalancerListenerParser(data interface{}) er listener := data.(map[string]interface{}) name := listener[constants.FieldListenerName].(string) - port := int32(listener[constants.FieldListenerPort].(int)) + port := listener[constants.FieldListenerPort].(int32) protocol := corev1.Protocol(listener[constants.FieldListenerProtocol].(string)) - backendPort := int32(listener[constants.FieldListenerBackendPort].(int)) + backendPort := listener[constants.FieldListenerBackendPort].(int32) c.LoadBalancer.Spec.Listeners = append(c.LoadBalancer.Spec.Listeners, loadbalancerv1.Listener{ Name: name, @@ -117,5 +120,21 @@ func (c *Constructor) subresourceLoadBalancerListenerParser(data interface{}) er } func (c *Constructor) subresourceLoadBalancerHealthCheckParser(data interface{}) error { + healthcheck := data.(map[string]interface{}) + + port := healthcheck[constants.FieldHealthCheckPort].(uint) + success := healthcheck[constants.FieldHealthCheckSuccessThreshold].(uint) + failure := healthcheck[constants.FieldHealthCheckFailureThreshold].(uint) + period := healthcheck[constants.FieldHealthCheckPeriodSeconds].(uint) + timeout := healthcheck[constants.FieldHealthCheckTimeoutSeconds].(uint) + + c.LoadBalancer.Spec.HealthCheck = &loadbalancerv1.HealthCheck{ + Port: port, + SuccessThreshold: success, + FailureThreshold: failure, + PeriodSeconds: period, + TimeoutSeconds: timeout, + } + return nil } diff --git a/internal/tests/resource_ippool_test.go b/internal/tests/resource_ippool_test.go index e7d2f130..b6a0c0c8 100644 --- a/internal/tests/resource_ippool_test.go +++ b/internal/tests/resource_ippool_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - // loadbalancerv1 "github.com/harvester/harvester-load-balancer/pkg/apis/loadbalancer.harvesterhci.io/v1beta1" ) @@ -15,7 +14,7 @@ func TestIPPoolBasic(t *testing.T) { // ) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { diff --git a/internal/tests/resource_loadbalancer_test.go b/internal/tests/resource_loadbalancer_test.go new file mode 100644 index 00000000..43b23c0c --- /dev/null +++ b/internal/tests/resource_loadbalancer_test.go @@ -0,0 +1,38 @@ +package tests + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + // loadbalancerv1 "github.com/harvester/harvester-load-balancer/pkg/apis/loadbalancer.harvesterhci.io/v1beta1" +) + +func TestLoadBalancerBasic(t *testing.T) { + // var ( + // loadbalancer *loadbalancerv1.LoadBalancer + // ctx = context.Background() + // ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: ` +resource harvester_loadbalancer \"test_loadbalancer\" { + name = \"test_loadbalancer\" + + listener { + port = 443 + protocol = \"tcp\" + backend_port = 8080 + } +} +`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("harvester_loadbalancer.test_loadbalancer", "name", "test_loadbalancer"), + ), + }, + }, + }) +} diff --git a/pkg/constants/constants_loadbalancer.go b/pkg/constants/constants_loadbalancer.go index d1a46d64..51fe19e4 100644 --- a/pkg/constants/constants_loadbalancer.go +++ b/pkg/constants/constants_loadbalancer.go @@ -22,11 +22,11 @@ const ( const ( SubresourceTypeLoadBalancerHealthCheck = "healthcheck" - FieldHealthcheckPort = "port" - FieldHealthcheckSuccessThreshold = "success_threshold" - FieldHealthcheckFailureThreshold = "failure_threshold" - FieldHealthcheckPeriodSeconds = "period_seconds" - FieldHealthcheckTimeoutSeconds = "timeout_seconds" + FieldHealthCheckPort = "port" + FieldHealthCheckSuccessThreshold = "success_threshold" + FieldHealthCheckFailureThreshold = "failure_threshold" + FieldHealthCheckPeriodSeconds = "period_seconds" + FieldHealthCheckTimeoutSeconds = "timeout_seconds" ) const (