Skip to content

Commit

Permalink
Updated the cluster definition of the adapter in the native envoy tem…
Browse files Browse the repository at this point in the history
…plate config (#107)
  • Loading branch information
rockspore authored Nov 19, 2020
1 parent 408f75b commit 2c8c82e
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 53 deletions.
6 changes: 3 additions & 3 deletions bin/build_templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ if [ ! -d "${TEMPLATES_DIR}" ]; then
fi


cp -r "${TEMPLATES_SOURCE_DIR}/native" $TEMPLATES_DIR
cp -r "${TEMPLATES_SOURCE_DIR}/istio-1.6" $TEMPLATES_DIR
cp -r "${TEMPLATES_SOURCE_DIR}/istio-1.7" $TEMPLATES_DIR
cp -r "${TEMPLATES_SOURCE_DIR}/envoy-1.16" $TEMPLATES_DIR
cp -r "${TEMPLATES_SOURCE_DIR}/istio-1.6" $TEMPLATES_DIR
cp -r "${TEMPLATES_SOURCE_DIR}/istio-1.7" $TEMPLATES_DIR

# create resource
RESOURCE_FILE="${ROOTDIR}/templates/templates.go"
Expand Down
104 changes: 97 additions & 7 deletions cmd/samples/samples.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"net/url"
"os"
"path"
"sort"
"strings"
"text/template"

Expand All @@ -31,12 +32,28 @@ import (
"github.com/spf13/cobra"
)

var (
supportedTemplates = map[string]string{
"native": "envoy-1.16", // deprecated
"envoy-1.14": "envoy-1.16",
"envoy-1.15": "envoy-1.16",
"envoy-1.16": "envoy-1.16",
"istio-1.5": "istio-1.6",
"istio-1.6": "istio-1.6",
"istio-1.7": "istio-1.7",
}
)

type samples struct {
*shared.RootArgs
template string
templateDir string
outDir string
overwrite bool
RuntimeHost string
RuntimePort string
RuntimeTLS bool
AdapterHost string
TargetService targetService
TLS tls
EncodedName string
Expand Down Expand Up @@ -71,10 +88,34 @@ func Cmd(rootArgs *shared.RootArgs, printf shared.FormatFn) *cobra.Command {
}

c.AddCommand(cmdCreateSampleConfig(s, printf))
c.AddCommand(cmdListTemplateOptions(printf))

return c
}

func cmdListTemplateOptions(printf shared.FormatFn) *cobra.Command {
return &cobra.Command{
Use: "templates",
Short: "list available options for --template flag in \"samples create\" command",
Long: `List available options for --template flag in "samples create" command.
Values outside those that are listed here will not be accepted.
Note the "native" options has been deprecated.`,
Args: cobra.NoArgs,

Run: func(cmd *cobra.Command, _ []string) {
printf("Supported templates (native is deprecated):")
keys := []string{}
for k := range supportedTemplates {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
printf(" %s", k)
}
},
}
}

func cmdCreateSampleConfig(s *samples, printf shared.FormatFn) *cobra.Command {
c := &cobra.Command{
Use: "create",
Expand All @@ -91,7 +132,12 @@ files related to deployment of their target services.`,
Args: cobra.NoArgs,

RunE: func(cmd *cobra.Command, _ []string) error {
err := s.loadConfig()
var err error
err = s.validateFieldsFromFlags()
if err != nil {
return errors.Wrap(err, "validating flags")
}
err = s.loadConfig()
if err != nil {
return errors.Wrap(err, "loading config yaml file")
}
Expand All @@ -100,40 +146,84 @@ files related to deployment of their target services.`,
return errors.Wrap(err, "creating sample config files")
}
printf("Config files successfully generated.")
if s.template != "native" {
if strings.Contains(s.template, "istio") {
printf("Please enable istio sidecar injection on the default namespace before running kubectl apply on the directory with config files.")
}
return nil
},
}

c.Flags().StringVarP(&s.ConfigPath, "config", "c", "", "path to Apigee Remote Service config file")
c.Flags().StringVarP(&s.template, "template", "t", "istio-1.6", "template name (options are istio-1.6, istio-1.7, native)")
c.Flags().StringVarP(&s.template, "template", "t", "istio-1.6", "template name (run \"samples templates\" to see available options)")
c.Flags().BoolVarP(&s.overwrite, "force", "f", false, "force overwriting existing directory")
c.Flags().StringVarP(&s.outDir, "out", "", "./samples", "directory to create config files within")
c.Flags().StringVarP(&s.TargetService.Name, "name", "n", "httpbin", "target service name")
c.Flags().StringVarP(&s.TargetService.Host, "host", "", "httpbin.org", "target service host")
c.Flags().StringVarP(&s.TLS.Dir, "tls", "", "", "directory for tls key and crt")
c.Flags().StringVarP(&s.ImageTag, "tag", "", getTagFromBuildVersion(), "version tag of the Envoy Adapter image")
c.Flags().StringVarP(&s.TargetService.Host, "host", "", "", "target service host (envoy templates only)")
c.Flags().StringVarP(&s.AdapterHost, "adapter-host", "", "", "adapter host name (envoy templates only)")
c.Flags().StringVarP(&s.TLS.Dir, "tls", "", "", "directory containing tls.key and tls.crt used for the adapter service (envoy templates only)")
c.Flags().StringVarP(&s.ImageTag, "tag", "", "", "version tag of the Envoy Adapter image (istio templates only)")

_ = c.MarkFlagRequired("config")

return c
}

func (s *samples) validateFieldsFromFlags() error {
dir, ok := supportedTemplates[s.template]
if !ok {
return fmt.Errorf("template option: %q not found", s.template)
}
s.templateDir = dir

if strings.Contains(s.template, "envoy") || s.template == "native" {
if s.ImageTag != "" {
return fmt.Errorf("flag --tag should only be used for the istio template")
}
if s.AdapterHost == "" {
s.AdapterHost = "localhost"
}
if s.TargetService.Host == "" {
s.TargetService.Host = "httpbin.org"
}
} else {
if s.AdapterHost != "" || s.TargetService.Host != "" || s.TLS.Dir != "" {
return fmt.Errorf("flags --adapter-host, --host or --tls should only be used for envoy templates")
}
if s.ImageTag == "" {
s.ImageTag = getTagFromBuildVersion()
}
}

return nil
}

func (s *samples) loadConfig() error {
s.ServerConfig = &server.Config{}
err := s.ServerConfig.Load(s.ConfigPath, "", "", false)
if err != nil {
return err
}

return s.parseConfig()
}

func (s *samples) parseConfig() error {
s.RuntimeBase = strings.Split(s.ServerConfig.Tenant.RemoteServiceAPI, "/remote-service")[0]
url, err := url.Parse(s.RuntimeBase)
if err != nil {
return err
}
s.RuntimeHost = url.Hostname()
if url.Scheme == "https" {
s.RuntimeTLS = true
s.RuntimePort = "443"
} else {
s.RuntimeTLS = false
s.RuntimePort = "80"
}
if url.Port() != "" {
s.RuntimePort = url.Port()
}
s.Org = s.ServerConfig.Tenant.OrgName
s.Env = s.ServerConfig.Tenant.EnvName
s.Namespace = s.ServerConfig.Global.Namespace
Expand Down Expand Up @@ -185,7 +275,7 @@ func (s *samples) createSampleConfigs(printf shared.FormatFn) error {
return fmt.Errorf("output directory already exists")
}
printf("Generating %s configuration files...", s.template)
return s.createConfig(s.template, printf)
return s.createConfig(s.templateDir, printf)
}

func (s *samples) createConfig(templateDir string, printf shared.FormatFn) error {
Expand Down
136 changes: 130 additions & 6 deletions cmd/samples/samples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,132 @@ import (
"gopkg.in/yaml.v3"
)

func TestCreateNativeConfigs(t *testing.T) {
print := testutil.Printer("TestCreateNativeConfigs")
func TestFlagValidation(t *testing.T) {
testSamples := []*samples{
&samples{
template: "native",
},
&samples{
template: "native",
ImageTag: "tag",
},
&samples{
template: "istio-1.6",
},
&samples{
template: "istio-1.6",
AdapterHost: "localhost",
},
&samples{
template: "istio-1.6",
TargetService: targetService{
Host: "targethost",
},
},
&samples{
template: "istio-1.6",
TLS: tls{
Dir: "tls-dir",
},
},
&samples{
template: "istio-0.9",
},
}

wantedErrors := []string{
"",
"flag --tag should only be used for the istio template",
"",
"flags --adapter-host, --host or --tls should only be used for envoy templates",
"flags --adapter-host, --host or --tls should only be used for envoy templates",
"flags --adapter-host, --host or --tls should only be used for envoy templates",
"template option: \"istio-0.9\" not found",
}

for i, s := range testSamples {
err := s.validateFieldsFromFlags()
testutil.ErrorContains(t, err, wantedErrors[i])
}
}

func TestTemplatesListing(t *testing.T) {
print := testutil.Printer("TemplatesListing")

// a good command
rootArgs := &shared.RootArgs{}
flags := []string{"samples", "templates"}
rootCmd := cmd.GetRootCmd(flags, print.Printf)
shared.AddCommandWithFlags(rootCmd, rootArgs, Cmd(rootArgs, print.Printf))

if err := rootCmd.Execute(); err != nil {
t.Errorf("want no error: %v", err)
}

want := []string{
"Supported templates (native is deprecated):",
" envoy-1.14",
" envoy-1.15",
" envoy-1.16",
" istio-1.5",
" istio-1.6",
" istio-1.7",
" native",
}

print.CheckPrefix(t, want)
}

func TestSamplesParseConfigs(t *testing.T) {
cfg := server.DefaultConfig()
cfg.Tenant.RemoteServiceAPI = "http://runtime/remote-service"
cfg.Tenant.OrgName = "hi"
cfg.Tenant.EnvName = "test"
cfg.Analytics.FluentdEndpoint = "fluentd"

s := &samples{
RootArgs: &shared.RootArgs{
ServerConfig: cfg,
},
TargetService: targetService{},
TLS: tls{},
}

if err := s.parseConfig(); err != nil {
t.Errorf("want no error, got %v", err)
}
if s.RuntimeTLS {
t.Errorf("runtime TLS should not be true")
}
if s.RuntimePort != "80" {
t.Errorf("want runtime port to be %q got %q", "80", s.RuntimePort)
}
if n := envScopeEncodedName("hi", "test"); n != s.EncodedName {
t.Errorf("want encoded name to be %q got %q", n, s.EncodedName)
}

cfg.Analytics.CredentialsJSON = []byte("secret")
if err := s.parseConfig(); err != nil {
t.Errorf("want no error, got %v", err)
}
if s.EncodedName != "" {
t.Errorf("want encoded name to be empty, got %q", s.EncodedName)
}

s.TLS.Dir = "dir"
if err := s.parseConfig(); err != nil {
t.Errorf("want no error, got %v", err)
}
if s.TLS.Key != "dir/tls.key" {
t.Errorf("want tls key to be %q got %q", "dir/tls.key", s.TLS.Key)
}
if s.TLS.Crt != "dir/tls.crt" {
t.Errorf("want tls cert to be %q got %q", "dir/tls.cert", s.TLS.Crt)
}
}

func TestCreateEnvoyConfigs(t *testing.T) {
print := testutil.Printer("TestCreateEnvoyConfigs")

tmpDir, err := ioutil.TempDir("", "samples")
if err != nil {
Expand All @@ -54,7 +178,7 @@ func TestCreateNativeConfigs(t *testing.T) {

// a good command
rootArgs := &shared.RootArgs{}
flags := []string{"samples", "create", "-t", "native", "--out", path.Join(tmpDir, "native"), "-c", tmpFile.Name(), "--tls", "./"}
flags := []string{"samples", "create", "-t", "envoy-1.16", "--out", path.Join(tmpDir, "native"), "-c", tmpFile.Name(), "--tls", "./"}
rootCmd := cmd.GetRootCmd(flags, print.Printf)
shared.AddCommandWithFlags(rootCmd, rootArgs, Cmd(rootArgs, print.Printf))

Expand All @@ -63,7 +187,7 @@ func TestCreateNativeConfigs(t *testing.T) {
}

want := []string{
"Generating native configuration files...",
"Generating envoy-1.16 configuration files...",
" generating envoy-config.yaml...",
"Config files successfully generated.",
}
Expand Down Expand Up @@ -183,7 +307,7 @@ func TestCreateIstioConfigWithAnalyticsSecret(t *testing.T) {

// a good command
rootArgs := &shared.RootArgs{}
flags := []string{"samples", "create", "--out", path.Join(tmpDir, "istio-samples"), "-c", tmpFile.Name()}
flags := []string{"samples", "create", "--template", "istio-1.7", "--out", path.Join(tmpDir, "istio-samples"), "-c", tmpFile.Name()}
rootCmd := cmd.GetRootCmd(flags, print.Printf)
shared.AddCommandWithFlags(rootCmd, rootArgs, Cmd(rootArgs, print.Printf))

Expand Down Expand Up @@ -308,7 +432,7 @@ func generateConfig(t *testing.T, isGCPManaged bool, analyticsSecret bool) []byt
if !isGCPManaged {
config.Tenant.InternalAPI = server.LegacySaaSInternalBase
}
config.Tenant.RemoteServiceAPI = "https://RUNTIME/remote-service"
config.Tenant.RemoteServiceAPI = "https://RUNTIME:9001/remote-service"
config.Tenant.OrgName = "hi"
config.Tenant.EnvName = "test"
config.Analytics.FluentdEndpoint = "apigee-udca-hi-test-1q2w3e4r.apigee:20001"
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand Down Expand Up @@ -787,6 +788,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
Expand Down
Loading

0 comments on commit 2c8c82e

Please sign in to comment.