Skip to content

Commit

Permalink
First pass enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
codepope committed Jul 20, 2020
1 parent 533d52e commit ae2f0cf
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 11 deletions.
31 changes: 25 additions & 6 deletions api/resource_certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *Client) GetAppCertificate(appName string, hostname string) (*AppCertifi
return &data.App.Certificate, nil
}

func (c *Client) CheckAppCertificate(appName string, hostname string) (*AppCertificate, error) {
func (c *Client) CheckAppCertificate(appName string, hostname string) (*AppCertificate, *HostnameCheck, error) {
query := `
mutation($input: CheckCertificateInput!) {
checkCertificate(input: $input) {
Expand All @@ -95,6 +95,15 @@ func (c *Client) CheckAppCertificate(appName string, hostname string) (*AppCerti
}
}
}
check {
aRecords
aaaaRecords
cnameRecords
soa
dnsProvider
dnsVerificationRecord
resolvedAddresses
}
}
}
`
Expand All @@ -108,13 +117,13 @@ func (c *Client) CheckAppCertificate(appName string, hostname string) (*AppCerti

data, err := c.Run(req)
if err != nil {
return nil, err
return nil, nil, err
}

return data.CheckCertificate.Certificate, nil
return data.CheckCertificate.Certificate, data.CheckCertificate.Check, nil
}

func (c *Client) AddCertificate(appName string, hostname string) (*AppCertificate, error) {
func (c *Client) AddCertificate(appName string, hostname string) (*AppCertificate, *HostnameCheck, error) {
query := `
mutation($appId: ID!, $hostname: String!) {
addCertificate(appId: $appId, hostname: $hostname) {
Expand All @@ -132,13 +141,23 @@ func (c *Client) AddCertificate(appName string, hostname string) (*AppCertificat
id
source
clientStatus
isApex
issued {
nodes {
type
expiresAt
}
}
}
check {
aRecords
aaaaRecords
cnameRecords
soa
dnsProvider
dnsVerificationRecord
resolvedAddresses
}
}
}
`
Expand All @@ -150,10 +169,10 @@ func (c *Client) AddCertificate(appName string, hostname string) (*AppCertificat

data, err := c.Run(req)
if err != nil {
return nil, err
return nil, nil, err
}

return &data.AddCertificate.Certificate, nil
return data.AddCertificate.Certificate, data.AddCertificate.Check, nil
}

func (c *Client) DeleteCertificate(appName string, hostname string) (*DeleteCertificatePayload, error) {
Expand Down
15 changes: 14 additions & 1 deletion api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ type Query struct {
}

AddCertificate struct {
Certificate AppCertificate
Certificate *AppCertificate
Check *HostnameCheck
}

DeleteCertificate DeleteCertificatePayload

CheckCertificate struct {
App *App
Certificate *AppCertificate
Check *HostnameCheck
}

AllocateIPAddress struct {
Expand Down Expand Up @@ -313,6 +315,7 @@ type AppCertificate struct {
Hostname string
Source string
ClientStatus string
IsApex bool
Issued struct {
Nodes []struct {
ExpiresAt time.Time
Expand All @@ -321,6 +324,16 @@ type AppCertificate struct {
}
}

type HostnameCheck struct {
ARecords []string `json:"aRecords"`
AAAARecords []string `json:"aaaaRecords"`
CNAMERecords []string `json:"cnameRecords"`
SOA string `json:"soa"`
DNSProvider string `json:"dnsProvider"`
DNSVerificationRecord string `json:"dnsVerificationRecord"`
ResolvedAddresses []string `json:"resolvedAddresses"`
}

type DeleteCertificatePayload struct {
App App
Certificate AppCertificate
Expand Down
111 changes: 107 additions & 4 deletions cmd/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ package cmd

import (
"fmt"
"github.com/superfly/flyctl/cmdctx"
"net"
"os"
"strings"

"github.com/superfly/flyctl/api"
"github.com/superfly/flyctl/cmdctx"

"github.com/superfly/flyctl/docstrings"

"github.com/AlecAivazis/survey/v2"
"github.com/spf13/cobra"
"github.com/superfly/flyctl/cmd/presenters"
"golang.org/x/net/publicsuffix"
)

func newCertificatesCommand() *Command {
Expand Down Expand Up @@ -69,23 +74,121 @@ func runCertShow(commmandContext *cmdctx.CmdContext) error {
func runCertCheck(commandContext *cmdctx.CmdContext) error {
hostname := commandContext.Args[0]

cert, err := commandContext.Client.API().CheckAppCertificate(commandContext.AppName, hostname)
cert, hostcheck, err := commandContext.Client.API().CheckAppCertificate(commandContext.AppName, hostname)
if err != nil {
return err
}
commandContext.WriteJSON(hostcheck)

return commandContext.Frender(cmdctx.PresenterOption{Presentable: &presenters.Certificate{Certificate: cert}, Vertical: true})
}

func runCertAdd(commandContext *cmdctx.CmdContext) error {
hostname := commandContext.Args[0]

cert, err := commandContext.Client.API().AddCertificate(commandContext.AppName, hostname)
cert, hostcheck, err := commandContext.Client.API().AddCertificate(commandContext.AppName, hostname)
if err != nil {
return err
}

return commandContext.Frender(cmdctx.PresenterOption{Presentable: &presenters.Certificate{Certificate: cert}, Vertical: true})
//commandContext.WriteJSON(hostcheck)
// // These will be the DNS IPs
iprecords, _ := net.LookupIP(hostname)

//fmt.Println(iprecords)

// These are the IPs we have for the app
ips, err := commandContext.Client.API().GetIPAddresses(commandContext.AppName)
if err != nil {
return err
}

var ipV4 api.IPAddress
var ipV6 api.IPAddress
var configuredipV4 bool
var configuredipV6 bool

for _, x := range ips {
if x.Type == "v4" {
ipV4 = x
// Now we search the ipRecords to find a match
for _, c := range iprecords {
if c.String() == x.Address {
configuredipV4 = true
break
}
}
}
if x.Type == "v6" {
ipV6 = x
for _, c := range iprecords {
if c.String() == x.Address {
configuredipV6 = true
break
}
}
}
}

// fmt.Println("v4", configuredipV4, "v6", configuredipV6)

if cert.IsApex {
// If this is an apex domain we should guide towards creating A and AAAA records
addArecord := !configuredipV4
addAAAArecord := !cert.AcmeALPNConfigured

if addArecord || addAAAArecord {
stepcnt := 1
commandContext.Statusf("flyctl", cmdctx.SINFO, "You are creating a certificate for %s\n", hostname)
commandContext.Statusf("flyctl", cmdctx.SINFO, "We are using %s for this certificate.\n\n", cert.CertificateAuthority)
commandContext.Statusf("flyctl", cmdctx.SINFO, "You can validate your ownership of %s by:\n\n", hostname)
if addArecord {
commandContext.Statusf("flyctl", cmdctx.SINFO, "%d: Adding an A record to your DNS service which reads\n", stepcnt)
stepcnt = stepcnt + 1
commandContext.Statusf("flyctl", cmdctx.SINFO, "\n A @ %s\n\n", ipV4.Address)
}
if addAAAArecord {
commandContext.Statusf("flyctl", cmdctx.SINFO, "%d: Adding an AAAA record to your DNS service which reads:\n", stepcnt)
stepcnt = stepcnt + 1
commandContext.Statusf("flyctl", cmdctx.SINFO, "\n AAAA @ %s\n\n", ipV6.Address)
}
} else {
if cert.ClientStatus == "Ready" {
commandContext.Statusf("flyctl", cmdctx.SINFO, "Your certificate for %s has been issued\n", hostname)
} else {
commandContext.Statusf("flyctl", cmdctx.SINFO, "Your certificate for %s is being issued. Status is %s.\n", hostname, cert.ClientStatus)
}
}
} else {
// This is not an apex domain
// If A and AAAA record is not configured offer CNAME

nothingConfigured := !(configuredipV4 && configuredipV6)
onlyV4Configured := configuredipV4 && !configuredipV6

if nothingConfigured || onlyV4Configured {
commandContext.Statusf("flyctl", cmdctx.SINFO, "You can configure your DNS and validate your ownership of %s by:\n\n", hostname)

if nothingConfigured {
eTLD, _ := publicsuffix.PublicSuffix(hostname)
subdomainname := strings.TrimSuffix(hostname, eTLD)
commandContext.Statusf("flyctl", cmdctx.SINFO, "1: Adding an CNAME record to your DNS service which reads:\n")
commandContext.Statusf("flyctl", cmdctx.SINFO, "\n CNAME %s %s.fly.dev\n", subdomainname, commandContext.AppName)
} else if onlyV4Configured {
commandContext.Statusf("flyctl", cmdctx.SINFO, "1: Adding an CNAME record to your DNS service which reads:\n")
commandContext.Statusf("flyctl", cmdctx.SINFO, "CNAME acme-challenge %s\n", cert.DNSValidationTarget)

commandContext.Statusf("flyctl", cmdctx.SINFO, "2: Adding an CNAME record to your DNS service which reads:\n")
commandContext.Statusf("flyctl", cmdctx.SINFO, "CNAME _acme-challenge %s\n", cert.DNSValidationTarget)
}
} else {
commandContext.Statusf("flyctl", cmdctx.SINFO, "Awaiting text\n")
}
}

//return commandContext.Frender(cmdctx.PresenterOption{Presentable: &presenters.Certificate{Certificate: cert}, Vertical: true})

return nil
}

func runCertDelete(commandContext *cmdctx.CmdContext) error {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
github.com/machinebox/graphql v0.2.3-0.20181106130121-3a9253180225
github.com/matryer/is v1.3.0 // indirect
github.com/mattn/go-isatty v0.0.12
github.com/miekg/dns v1.0.14
github.com/mitchellh/mapstructure v1.3.1 // indirect
github.com/moby/buildkit v0.7.1
github.com/morikuni/aec v1.0.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex
github.com/michaeldwan/toml v0.3.2-0.20191213213541-3c5ced72b6f3 h1:fO9bKICUp3uSft7wDhdeAbXrwHsmko2JE/OewVp/jVc=
github.com/michaeldwan/toml v0.3.2-0.20191213213541-3c5ced72b6f3/go.mod h1:zs/AcS/gLJIa42aCC4p6n7sJIQIAV5LNLBu79EjGjt4=
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
Expand Down

0 comments on commit ae2f0cf

Please sign in to comment.