mirror of
https://github.com/kittywitch/nixfiles.git
synced 2026-02-09 12:29:19 -08:00
ops: refactor + CA stuff
This commit is contained in:
parent
5da80d3c52
commit
671d858731
11 changed files with 426 additions and 171 deletions
200
main.go
200
main.go
|
|
@ -3,196 +3,56 @@ package main
|
|||
import (
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
tailscale "github.com/pulumi/pulumi-tailscale/sdk/go/tailscale"
|
||||
cloudflare "github.com/pulumi/pulumi-cloudflare/sdk/v4/go/cloudflare"
|
||||
"gopkg.in/yaml.v3"
|
||||
"github.com/creasty/defaults"
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
iac "kittywitch/iac"
|
||||
)
|
||||
|
||||
type DNSRecordType string
|
||||
|
||||
const (
|
||||
A DNSRecordType = "a"
|
||||
AAAA = "aaaa"
|
||||
MX = "mx"
|
||||
TXT = "txt"
|
||||
CAA = "caa"
|
||||
)
|
||||
|
||||
type DNSRecord struct {
|
||||
Name string `default:"@" yaml:"name"`
|
||||
Kind DNSRecordType `yaml:"kind"`
|
||||
Value string `yaml:"value,omitempty"`
|
||||
Priority int `yaml:"priority,omitempty"`
|
||||
Flags string `yaml:"flags,omitempty"`
|
||||
Tag string `yaml:"tag,omitempty"`
|
||||
Ttl int `default:"3600" yaml:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
func (r *DNSRecord) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
defaults.Set(r)
|
||||
|
||||
type plain DNSRecord
|
||||
if err := unmarshal((*plain)(r)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *DNSRecord) getZone( Zone *cloudflare.Zone) (pulumi.StringOutput) {
|
||||
return Zone.ID().ToStringOutput()
|
||||
}
|
||||
|
||||
func (r *DNSRecord) getName(ZoneName string, Zone *cloudflare.Zone) (string) {
|
||||
base := fmt.Sprintf("%s-%s-%s", ZoneName, r.Kind, r.Name)
|
||||
|
||||
hash := md5.Sum([]byte(r.Value))
|
||||
hashString := hex.EncodeToString(hash[:])[:5]
|
||||
suffix := ""
|
||||
switch r.Kind {
|
||||
case MX:
|
||||
suffix = fmt.Sprintf("-%d-%s", r.Priority, hashString)
|
||||
case CAA:
|
||||
suffix = fmt.Sprintf("%s-%s", r.Flags, r.Tag)
|
||||
case A, AAAA, TXT:
|
||||
suffix = fmt.Sprintf("-%s", hashString)
|
||||
}
|
||||
|
||||
built := base + suffix
|
||||
return built
|
||||
}
|
||||
|
||||
func (r *DNSRecord) handle(ctx *pulumi.Context, ZoneName string, zone *cloudflare.Zone) (*cloudflare.Record, error) {
|
||||
var recordArgs *cloudflare.RecordArgs
|
||||
switch r.Kind {
|
||||
case CAA:
|
||||
recordArgs = &cloudflare.RecordArgs{
|
||||
ZoneId: r.getZone(zone),
|
||||
Name: pulumi.String(r.Name),
|
||||
Type: pulumi.String(strings.ToUpper(string(r.Kind))),
|
||||
Ttl: pulumi.Int(r.Ttl),
|
||||
Data: &cloudflare.RecordDataArgs{
|
||||
Flags: pulumi.String(r.Flags),
|
||||
Tag: pulumi.String(r.Tag),
|
||||
Value: pulumi.String(r.Value),
|
||||
},
|
||||
}
|
||||
default:
|
||||
recordArgs = &cloudflare.RecordArgs{
|
||||
ZoneId: r.getZone(zone),
|
||||
Name: pulumi.String(r.Name),
|
||||
Type: pulumi.String(strings.ToUpper(string(r.Kind))),
|
||||
Ttl: pulumi.Int(r.Ttl),
|
||||
Priority: pulumi.Int(r.Priority),
|
||||
Value: pulumi.String(r.Value),
|
||||
}
|
||||
}
|
||||
return cloudflare.NewRecord(ctx, r.getName(ZoneName, zone), recordArgs)
|
||||
}
|
||||
|
||||
type Zone struct {
|
||||
Zone string `yaml:"name"`
|
||||
Records []DNSRecord `yaml:"records"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Zones map[string]Zone `yaml:"zones"`
|
||||
}
|
||||
|
||||
func (z *Zone) handle(ctx *pulumi.Context, name string) (*cloudflare.Zone, error) {
|
||||
return cloudflare.NewZone(ctx, name, &cloudflare.ZoneArgs{
|
||||
Zone: pulumi.String(z.Zone),
|
||||
Plan: pulumi.String("free"),
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := Config{}
|
||||
katConfig := iac.KatConfig{}
|
||||
|
||||
configFile, err := os.ReadFile("config.yaml")
|
||||
|
||||
configfile, err := os.ReadFile("config.yaml")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := yaml.Unmarshal(configfile, &config); err != nil {
|
||||
|
||||
if err := yaml.Unmarshal(configFile, &katConfig); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
pulumi.Run(func(ctx *pulumi.Context) error {
|
||||
ctx.Log.Info(fmt.Sprintf("%v\n", config), nil)
|
||||
tailnet, err := tailscale.GetDevices(ctx, &tailscale.GetDevicesArgs{}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zones := make(map[string]*cloudflare.Zone)
|
||||
dnssec := make(map[string]*cloudflare.ZoneDnssec)
|
||||
records := make(map[string][]*cloudflare.Record)
|
||||
for name, zone := range config.Zones {
|
||||
ctx.Log.Info(name, nil)
|
||||
zones[name], err = zone.handle(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dnssec[name], err = cloudflare.NewZoneDnssec(ctx, fmt.Sprintf("%s-dnssec", name), &cloudflare.ZoneDnssecArgs{
|
||||
ZoneId: zones[name].ID(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, record := range zone.Records {
|
||||
_, exists := records[name]
|
||||
if exists {
|
||||
record_, err := record.handle(ctx, name, zones[name])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
records[name] = append(records[name], record_)
|
||||
} else {
|
||||
record_, err := record.handle(ctx, name, zones[name])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
records[name] = []*cloudflare.Record{record_}
|
||||
}
|
||||
}
|
||||
|
||||
// zones, dnssec, records
|
||||
zones, _, records, err := iac.HandleDNS(ctx, katConfig)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, device := range tailnet.Devices {
|
||||
if device.User != "kat@inskip.me" {
|
||||
continue
|
||||
}
|
||||
device_name := strings.Split(device.Name, ".")[0]
|
||||
ipv4 := DNSRecord{
|
||||
Name: device_name,
|
||||
Kind: A,
|
||||
Value: device.Addresses[0],
|
||||
Ttl: 3600,
|
||||
}
|
||||
recv4, err := ipv4.handle(ctx, "inskip", zones["inskip"])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ipv6 := DNSRecord{
|
||||
Name: device_name,
|
||||
Kind: AAAA,
|
||||
Value: device.Addresses[1],
|
||||
Ttl: 3600,
|
||||
}
|
||||
recv6, err := ipv6.handle(ctx, "inskip", zones["inskip"])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
records["inskip"] = append(records["inskip"], recv4, recv6)
|
||||
records, err = iac.HandleTSRecords(ctx, tailnet, zones, records)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
ca_key, ca_cert, err := iac.GenerateTLSCA(ctx)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// keys, crs, certs
|
||||
_, _, _, err = iac.HandleTSHostCerts(ctx, tailnet, ca_key, ca_cert)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue