TUN-5754: Allow ingress validate to take plaintext option
Ingress validate currently validates config from a file. This PR adds a new --json/-j flag to provide the ingress/config data as a plaintext command line argument.
This commit is contained in:
parent
051b2cf352
commit
9909e9d63c
|
@ -1,6 +1,7 @@
|
|||
package tunnel
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
|
@ -12,6 +13,15 @@ import (
|
|||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const ingressDataJSONFlagName = "json"
|
||||
|
||||
var ingressDataJSON = &cli.StringFlag{
|
||||
Name: ingressDataJSONFlagName,
|
||||
Aliases: []string{"j"},
|
||||
Usage: `Accepts data in the form of json as an input rather than read from a file`,
|
||||
EnvVars: []string{"TUNNEL_INGRESS_VALIDATE_JSON"},
|
||||
}
|
||||
|
||||
func buildIngressSubcommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "ingress",
|
||||
|
@ -49,6 +59,7 @@ func buildValidateIngressCommand() *cli.Command {
|
|||
Usage: "Validate the ingress configuration ",
|
||||
UsageText: "cloudflared tunnel [--config FILEPATH] ingress validate",
|
||||
Description: "Validates the configuration file, ensuring your ingress rules are OK.",
|
||||
Flags: []cli.Flag{ingressDataJSON},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,12 +80,11 @@ func buildTestURLCommand() *cli.Command {
|
|||
|
||||
// validateIngressCommand check the syntax of the ingress rules in the cloudflared config file
|
||||
func validateIngressCommand(c *cli.Context, warnings string) error {
|
||||
conf := config.GetConfiguration()
|
||||
if conf.Source() == "" {
|
||||
fmt.Println("No configuration file was found. Please create one, or use the --config flag to specify its filepath. You can use the help command to learn more about configuration files")
|
||||
return nil
|
||||
conf, err := getConfiguration(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Validating rules from", conf.Source())
|
||||
|
||||
if _, err := ingress.ParseIngress(conf); err != nil {
|
||||
return errors.Wrap(err, "Validation failed")
|
||||
}
|
||||
|
@ -90,6 +100,22 @@ func validateIngressCommand(c *cli.Context, warnings string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getConfiguration(c *cli.Context) (*config.Configuration, error) {
|
||||
var conf *config.Configuration
|
||||
if c.IsSet(ingressDataJSONFlagName) {
|
||||
ingressJSON := c.String(ingressDataJSONFlagName)
|
||||
fmt.Println("Validating rules from cmdline flag --json")
|
||||
err := json.Unmarshal([]byte(ingressJSON), &conf)
|
||||
return conf, err
|
||||
}
|
||||
conf = config.GetConfiguration()
|
||||
if conf.Source() == "" {
|
||||
return nil, errors.New("No configuration file was found. Please create one, or use the --config flag to specify its filepath. You can use the help command to learn more about configuration files")
|
||||
}
|
||||
fmt.Println("Validating rules from", conf.Source())
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// testURLCommand checks which ingress rule matches the given URL.
|
||||
func testURLCommand(c *cli.Context) error {
|
||||
requestArg := c.Args().First()
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cfapi"
|
||||
|
@ -322,3 +323,48 @@ func Test_subcommandContext_Delete(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_subcommandContext_ValidateIngressCommand(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
c *cli.Context
|
||||
wantErr bool
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "read a valid configuration from data",
|
||||
c: func() *cli.Context {
|
||||
data := `{ "warp-routing": {"enabled": true}, "originRequest" : {"connectTimeout": 10}, "ingress" : [ {"hostname": "test", "service": "https://localhost:8000" } , {"service": "http_status:404"} ]}`
|
||||
flagSet := flag.NewFlagSet("json", flag.PanicOnError)
|
||||
flagSet.String(ingressDataJSONFlagName, data, "")
|
||||
c := cli.NewContext(cli.NewApp(), flagSet, nil)
|
||||
_ = c.Set(ingressDataJSONFlagName, data)
|
||||
return c
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "read an invalid configuration with multiple mistakes",
|
||||
c: func() *cli.Context {
|
||||
data := `{ "ingress" : [ {"hostname": "test", "service": "localhost:8000" } , {"service": "http_status:invalid_status"} ]}`
|
||||
flagSet := flag.NewFlagSet("json", flag.PanicOnError)
|
||||
flagSet.String(ingressDataJSONFlagName, data, "")
|
||||
c := cli.NewContext(cli.NewApp(), flagSet, nil)
|
||||
_ = c.Set(ingressDataJSONFlagName, data)
|
||||
return c
|
||||
}(),
|
||||
wantErr: true,
|
||||
expectedErr: errors.New("Validation failed: localhost:8000 is an invalid address, please make sure it has a scheme and a hostname"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validateIngressCommand(tt.c, "")
|
||||
if tt.wantErr {
|
||||
assert.Equal(t, tt.expectedErr.Error(), err.Error())
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue