diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 1875b1c..d83cf06 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "github.com/Khan/genqlient/graphql" + providerGraphql "github.com/fly-apps/terraform-provider-fly/graphql" "github.com/fly-apps/terraform-provider-fly/internal/utils" + "github.com/fly-apps/terraform-provider-fly/internal/wg" hreq "github.com/imroc/req/v3" "net/http" "os" @@ -28,8 +30,11 @@ type provider struct { } type providerData struct { - FlyToken types.String `tfsdk:"fly_api_token"` - FlyHttpEndpoint types.String `tfsdk:"fly_http_endpoint"` + FlyToken types.String `tfsdk:"fly_api_token"` + FlyHttpEndpoint types.String `tfsdk:"fly_http_endpoint"` + UseInternalTunnel types.Bool `tfsdk:"useinternaltunnel"` + InternalTunnelOrg types.String `tfsdk:"internaltunnelorg"` + InternalTunnelRegion types.String `tfsdk:"internaltunnelregion"` } func (p *provider) Configure(ctx context.Context, req tfsdkprovider.ConfigureRequest, resp *tfsdkprovider.ConfigureResponse) { @@ -96,6 +101,20 @@ func (p *provider) Configure(ctx context.Context, req tfsdkprovider.ConfigureReq client := graphql.NewClient("https://api.fly.io/graphql", &h) p.client = &client + if data.UseInternalTunnel.Value { + org, err := providerGraphql.Organization(context.Background(), client, data.InternalTunnelOrg.Value) + if err != nil { + resp.Diagnostics.AddError("Could not resolve organization", err.Error()) + return + } + tunnel, err := wg.Establish(ctx, org.Organization.Id, data.InternalTunnelRegion.Value, token, &client) + if err != nil { + resp.Diagnostics.AddError("failed to open internal tunnel", err.Error()) + return + } + p.httpClient.SetDial(tunnel.NetStack().DialContext) + p.httpEndpoint = "_api.internal:4280" + } p.configured = true } @@ -131,6 +150,18 @@ func (p *provider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostic Optional: true, Type: types.StringType, }, + "useinternaltunnel": { + Optional: true, + Type: types.BoolType, + }, + "internaltunnelorg": { + Optional: true, + Type: types.StringType, + }, + "internaltunnelregion": { + Optional: true, + Type: types.StringType, + }, }, }, nil } diff --git a/internal/wg/tunnel.go b/internal/wg/tunnel.go index 0594ae3..046206e 100644 --- a/internal/wg/tunnel.go +++ b/internal/wg/tunnel.go @@ -9,7 +9,6 @@ import ( "fmt" rawgql "github.com/Khan/genqlient/graphql" "github.com/fly-apps/terraform-provider-fly/graphql" - "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/miekg/dns" "golang.org/x/crypto/curve25519" "golang.zx2c4.com/wireguard/conn" @@ -274,6 +273,10 @@ func (t *Tunnel) NewHttpClient() Client { return Client{HttpClient: http.Client{Transport: &transport}} } +func (t *Tunnel) NetStack() *netstack.Net { + return t.net +} + func (t *Tunnel) Down() error { _, err := graphql.RemoveWireguardPeer(context.Background(), *t.apiClient, graphql.RemoveWireGuardPeerInput{ OrganizationId: t.State.Org, @@ -329,10 +332,8 @@ func (t *Tunnel) QueryDNS(ctx context.Context, msg *dns.Msg) (*dns.Msg, error) { return r, err } -func Establish(ctx context.Context, org string, region string, username string, token string, client *rawgql.Client) (*Tunnel, error) { - fmt.Println("terraform-tunnel-" + username + strconv.FormatInt(time.Now().Unix(), 10)) - peerName := "terraform-tunnel-" + username + strconv.FormatInt(time.Now().Unix(), 10) - tflog.Info(ctx, peerName) +func Establish(ctx context.Context, org string, region string, token string, client *rawgql.Client) (*Tunnel, error) { + peerName := "terraform-tunnel-" + strconv.FormatInt(time.Now().Unix(), 10) public, private := C25519pair() peer, err := graphql.AddWireguardPeer(ctx, *client, graphql.AddWireGuardPeerInput{ diff --git a/pkg/apiv1/machines.go b/pkg/apiv1/machines.go index 3c63ffb..640a314 100644 --- a/pkg/apiv1/machines.go +++ b/pkg/apiv1/machines.go @@ -46,7 +46,7 @@ type MachineConfig struct { Init InitConfig `json:"init,omitempty"` Mounts []MachineMount `json:"mounts,omitempty"` Services []Service `json:"services"` - Guest GuestConfig `json:"guest,omitempty"` + Guest GuestConfig `json:"guest,omitempty"` } type GuestConfig struct { @@ -141,7 +141,7 @@ func (a *MachineAPI) WaitForMachine(app string, id string, instanceID string) er // CreateMachine takes a MachineCreateOrUpdateRequest and creates the requested machine in the given app and then writes the response into the `res` param func (a *MachineAPI) CreateMachine(req MachineCreateOrUpdateRequest, app string, res *MachineResponse) error { if req.Config.Guest.CpuType == "" { - req.Config.Guest.CpuType = "shared" + req.Config.Guest.CpuType = "shared" } createResponse, err := a.httpClient.R().SetBody(req).SetResult(res).Post(fmt.Sprintf("http://%s/v1/apps/%s/machines", a.endpoint, app)) @@ -157,7 +157,7 @@ func (a *MachineAPI) CreateMachine(req MachineCreateOrUpdateRequest, app string, func (a *MachineAPI) UpdateMachine(req MachineCreateOrUpdateRequest, app string, id string, res *MachineResponse) error { if req.Config.Guest.CpuType == "" { - req.Config.Guest.CpuType = "shared" + req.Config.Guest.CpuType = "shared" } lease, err := a.LockMachine(app, id, 30) if err != nil { diff --git a/tools/tools.go b/tools/tools.go index d9fc137..3ff95e7 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -27,7 +27,7 @@ func main() { token := os.Getenv("FLY_API_TOKEN") h := http.Client{Timeout: 60 * time.Second, Transport: &transport{underlyingTransport: http.DefaultTransport, token: token, ctx: ctx}} client := graphql.NewClient("https://api.fly.io/graphql", &h) - tunnel, err := wg.Establish(ctx, "P7lZB0nw2ylg8smzmMLA9eVLAQuRL6", "ewr", "DAlperin", token, &client) + tunnel, err := wg.Establish(ctx, "P7lZB0nw2ylg8smzmMLA9eVLAQuRL6", "ewr", token, &client) if err != nil { fmt.Println(err.Error()) os.Exit(1)