cmd/k8s-operator: use the client's authkey method to create auth keys.

Also introduces an intermediary interface for the tailscale client, in
preparation for operator tests that fake out the Tailscale API interaction.

Updates #502.

Signed-off-by: David Anderson <danderson@tailscale.com>
pull/6719/head
David Anderson 1 year ago committed by Dave Anderson
parent ca08e316af
commit 3b7ae39a06

@ -7,14 +7,10 @@
package main package main
import ( import (
"bytes"
"context" "context"
_ "embed" _ "embed"
"encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"net/http"
"os" "os"
"strings" "strings"
"time" "time"
@ -182,7 +178,13 @@ const (
type ServiceReconciler struct { type ServiceReconciler struct {
client.Client client.Client
defaultTags []string defaultTags []string
tsClient *tailscale.Client tsClient tsClient
}
type tsClient interface {
DeleteDevice(ctx context.Context, id string) error
Tailnet() string
CreateKey(ctx context.Context, caps tailscale.KeyCapabilities) (string, *tailscale.Key, error)
} }
func childResourceLabels(parent *corev1.Service) map[string]string { func childResourceLabels(parent *corev1.Service) map[string]string {
@ -414,7 +416,7 @@ func (a *ServiceReconciler) createOrGetSecret(ctx context.Context, svc, hsvc *co
} }
secret.StringData = map[string]string{ secret.StringData = map[string]string{
"authkey": authKey.Key, "authkey": authKey,
} }
if err := a.Create(ctx, secret); err != nil { if err := a.Create(ctx, secret); err != nil {
return "", err return "", err
@ -463,36 +465,21 @@ type capability struct {
} `json:"devices"` } `json:"devices"`
} }
func (a *ServiceReconciler) newAuthKey(ctx context.Context, tags []string) (*authKey, error) { func (a *ServiceReconciler) newAuthKey(ctx context.Context, tags []string) (string, error) {
var nkr newKeyRequest caps := tailscale.KeyCapabilities{
nkr.Capabilities.Devices.Create.Reusable = false Devices: tailscale.KeyDeviceCapabilities{
nkr.Capabilities.Devices.Create.Preauthorized = true Create: tailscale.KeyDeviceCreateCapabilities{
nkr.Capabilities.Devices.Create.Tags = tags Reusable: false,
jc, err := json.Marshal(nkr) Preauthorized: true,
if err != nil { Tags: tags,
return nil, err },
} },
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("https://unused/api/v2/tailnet/%s/keys", a.tsClient.Tailnet()), bytes.NewReader(jc))
if err != nil {
return nil, err
} }
resp, err := a.tsClient.Do(req) key, _, err := a.tsClient.CreateKey(ctx, caps)
if err != nil { if err != nil {
return nil, err return "", err
}
defer resp.Body.Close()
slurp := new(bytes.Buffer)
if _, err := io.Copy(slurp, resp.Body); err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d; %v", resp.StatusCode, slurp.String())
}
var ak authKey
if err := json.NewDecoder(slurp).Decode(&ak); err != nil {
return nil, err
} }
return &ak, nil return key, nil
} }
//go:embed manifests/proxy.yaml //go:embed manifests/proxy.yaml

Loading…
Cancel
Save