From 074530d3d4c2b2735f3be6840e39287126875043 Mon Sep 17 00:00:00 2001 From: Charles Treatman Date: Wed, 27 Sep 2023 13:56:08 -0500 Subject: [PATCH] exchange Metal API key for LB OAuth tokenbefore making LB API requests --- metal/loadbalancers/emlb/emlb.go | 37 ++++++++++++ .../emlb/metal_token_exchanger.go | 57 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 metal/loadbalancers/emlb/metal_token_exchanger.go diff --git a/metal/loadbalancers/emlb/emlb.go b/metal/loadbalancers/emlb/emlb.go index 533c2ded..cf203fdf 100644 --- a/metal/loadbalancers/emlb/emlb.go +++ b/metal/loadbalancers/emlb/emlb.go @@ -21,10 +21,47 @@ func NewLB(k8sclient kubernetes.Interface, config string) *LB { } func (l *LB) AddService(ctx context.Context, svcNamespace, svcName, ip string, nodes []loadbalancers.Node) error { + tokenExchanger := &MetalTokenExchanger{ + metalAPIKey: "TODO", + client: l.client.GetConfig().HTTPClient, + } + ctx = context.WithValue(ctx, lbaas.ContextOAuth2, tokenExchanger) + + lbCreateRequest := lbaas.LoadBalancerCreate{ + Name: "", + LocationId: "", + PortIds: []string{}, + ProviderId: "", + } + + // TODO lb, resp, err := + _, _, err := l.client.ProjectsApi.CreateLoadBalancer(ctx, "TODO: project ID").LoadBalancerCreate(lbCreateRequest).Execute() + if err != nil { + return err + } + + // TODO create other resources + return nil } func (l *LB) RemoveService(ctx context.Context, svcNamespace, svcName, ip string) error { + tokenExchanger := &MetalTokenExchanger{ + metalAPIKey: "TODO", + client: l.client.GetConfig().HTTPClient, + } + ctx = context.WithValue(ctx, lbaas.ContextOAuth2, tokenExchanger) + + loadBalancerId := "TODO" + + // TODO delete other resources + + // TODO lb, resp, err := + _, err := l.client.LoadBalancersApi.DeleteLoadBalancer(ctx, loadBalancerId).Execute() + if err != nil { + return err + } + return nil } diff --git a/metal/loadbalancers/emlb/metal_token_exchanger.go b/metal/loadbalancers/emlb/metal_token_exchanger.go new file mode 100644 index 00000000..0157f470 --- /dev/null +++ b/metal/loadbalancers/emlb/metal_token_exchanger.go @@ -0,0 +1,57 @@ +package emlb + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + "golang.org/x/oauth2" +) + +type MetalTokenExchanger struct { + metalAPIKey string + client *http.Client +} + +func (m *MetalTokenExchanger) Token() (*oauth2.Token, error) { + tokenExchangeURL := "https://iam.metalctrl.io/api-keys/exchange" + tokenExchangeRequest, err := http.NewRequest("POST", tokenExchangeURL, nil) + if err != nil { + return nil, err + } + tokenExchangeRequest.Header.Add("Authorization", fmt.Sprintf("Bearer %v", m.metalAPIKey)) + + resp, err := m.client.Do(tokenExchangeRequest) + if err != nil { + return nil, err + } + + body, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("token exchange request failed with status %v, body %v", resp.StatusCode, body) + } + + token := oauth2.Token{} + err = json.Unmarshal(body, &token) + if err != nil { + fmt.Println(len(body)) + fmt.Println(token) + fmt.Println(err) + return nil, err + } + + expiresIn := token.Extra("expires_in") + if expiresIn != nil { + expiresInSeconds := expiresIn.(int) + token.Expiry = time.Now().Add(time.Second * time.Duration(expiresInSeconds)) + } + + return &token, nil +}