forked from TrueCloudLab/certificates
Create method for onboard action and clean code.
This commit is contained in:
parent
c0d1399c38
commit
0c654d93ea
1 changed files with 82 additions and 60 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -17,6 +18,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/smallstep/cli/crypto/randutil"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/authority"
|
"github.com/smallstep/certificates/authority"
|
||||||
"github.com/smallstep/certificates/ca"
|
"github.com/smallstep/certificates/ca"
|
||||||
|
@ -25,7 +28,7 @@ import (
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type onboardingConfiguration struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
DNS string `json:"dns"`
|
DNS string `json:"dns"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
|
@ -190,65 +193,10 @@ intermediate private key.`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "onboard",
|
Name: "onboard",
|
||||||
Usage: "Configure and run step-ca from the onboarding guide",
|
Usage: "Configure and run step-ca from the onboarding guide",
|
||||||
// TODO this should accept an optional config parameter that defaults to ~/.step/config/ca.json
|
UsageText: "**step-ca onboard** <token>",
|
||||||
// as well as an optional token parameter for connecting to the onboarding flow
|
Action: onboardAction,
|
||||||
Action: func(c *cli.Context) error {
|
|
||||||
fmt.Printf("Connecting to onboarding guide...\n\n")
|
|
||||||
|
|
||||||
token := c.Args().Get(0)
|
|
||||||
|
|
||||||
res, err := http.Get("http://localhost:3002/onboarding/" + token)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
configuration := config{}
|
|
||||||
err = json.Unmarshal(body, &configuration)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Connected! Initializing step-ca with the following configuration...\n\n")
|
|
||||||
fmt.Printf("Name: %s\n", configuration.Name)
|
|
||||||
fmt.Printf("DNS: %s\n", configuration.DNS)
|
|
||||||
fmt.Printf("Address: %s\n", configuration.Address)
|
|
||||||
// TODO generate this password
|
|
||||||
fmt.Printf("Provisioner Password: abcdef1234567890\n\n")
|
|
||||||
|
|
||||||
// TODO actually initialize the CA config (automatically add an "admin" JWT provisioner)
|
|
||||||
// and start listening
|
|
||||||
// TODO get the root cert fingerprint to post back to the onboarding guide
|
|
||||||
payload, err := json.Marshal(onboardingPayload{Fingerprint: "foobarbatbaz"})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "http://localhost:3002/onboarding/"+token, bytes.NewBuffer(payload))
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
resp.Body.Close()
|
|
||||||
|
|
||||||
fmt.Printf("Initialized!\n")
|
|
||||||
fmt.Printf("Step CA has been started. Please return to the onboarding guide in your browser to continue.\n")
|
|
||||||
for {
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
|
@ -324,6 +272,80 @@ func startAction(ctx *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func onboardAction(ctx *cli.Context) error {
|
||||||
|
if ctx.NArg() == 0 {
|
||||||
|
return cli.ShowAppHelp(ctx)
|
||||||
|
}
|
||||||
|
if err := errs.NumberOfArguments(ctx, 1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get onboarding url
|
||||||
|
onboarding := "http://localhost:3002/onboarding/"
|
||||||
|
if v := os.Getenv("STEP_CA_ONBOARDING_URL"); v != "" {
|
||||||
|
onboarding = v
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(onboarding)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error parsing %s", onboarding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Connecting to onboarding guide...\n\n")
|
||||||
|
|
||||||
|
token := ctx.Args().Get(0)
|
||||||
|
onboardingURL := u.ResolveReference(&url.URL{Path: token}).String()
|
||||||
|
|
||||||
|
res, err := http.Get(onboardingURL)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "http GET %s failed", onboardingURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error reading response")
|
||||||
|
}
|
||||||
|
|
||||||
|
var config onboardingConfiguration
|
||||||
|
err = json.Unmarshal(body, &config)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error unmarshaling response")
|
||||||
|
}
|
||||||
|
|
||||||
|
password, err := randutil.ASCII(32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Connected! Initializing step-ca with the following configuration...\n\n")
|
||||||
|
fmt.Printf("Name: %s\n", config.Name)
|
||||||
|
fmt.Printf("DNS: %s\n", config.DNS)
|
||||||
|
fmt.Printf("Address: %s\n", config.Address)
|
||||||
|
fmt.Printf("Provisioner Password: %s\n\n", password)
|
||||||
|
|
||||||
|
// TODO actually initialize the CA config (automatically add an "admin" JWT provisioner)
|
||||||
|
// and start listening
|
||||||
|
// TODO get the root cert fingerprint to post back to the onboarding guide
|
||||||
|
payload, err := json.Marshal(onboardingPayload{Fingerprint: "foobarbatbaz"})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error marshalling payload")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(onboardingURL, "application/json", bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "http POST %s failed", onboardingURL)
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
fmt.Printf("Initialized!\n")
|
||||||
|
fmt.Printf("Step CA has been started. Please return to the onboarding guide in your browser to continue.\n")
|
||||||
|
for {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// fatal writes the passed error on the standard error and exits with the exit
|
// fatal writes the passed error on the standard error and exits with the exit
|
||||||
// code 1. If the environment variable STEPDEBUG is set to 1 it shows the
|
// code 1. If the environment variable STEPDEBUG is set to 1 it shows the
|
||||||
// stack trace of the error.
|
// stack trace of the error.
|
||||||
|
|
Loading…
Reference in a new issue