From 5aaddb69a865ca01c5a6d9df48adae79b51e791f Mon Sep 17 00:00:00 2001 From: Srinandan Sridhar <13950006+srinandan@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:34:03 -0700 Subject: [PATCH] feat: adds support for deployment type #521 (#522) * feat: adds support for deployment type #521 * chore: refactor methods #521 * bug: handles different billing types and plans #521 --- internal/client/env/env.go | 59 +++++++++++ internal/client/env/reports.go | 142 +++++++++++++++++++++------ internal/client/orgs/orgs.go | 13 ++- internal/client/orgs/reports.go | 77 +++++---------- internal/client/orgs/reports_test.go | 2 +- internal/cmd/org/reportmonthly.go | 36 +++++-- internal/cmd/org/reports.go | 3 + internal/cmd/org/reportyearly.go | 32 ++++-- internal/cmd/org/setaddons.go | 6 +- 9 files changed, 267 insertions(+), 103 deletions(-) diff --git a/internal/client/env/env.go b/internal/client/env/env.go index 1df0e5f2f..75a181941 100644 --- a/internal/client/env/env.go +++ b/internal/client/env/env.go @@ -47,6 +47,17 @@ type Property struct { Value string `json:"value,omitempty"` } +type AddonsConfig struct { + AnalyticsConfig AnalyticsConfig `json:"analyticsConfig,omitempty"` +} + +type AnalyticsConfig struct { + Enabled bool `json:"enabled,omitempty"` + ExpireTimeMills string `json:"expireTimeMills,omitempty"` + State string `json:"state,omitempty"` + UpdateTime string `json:"updateTime,omitempty"` +} + // Create func Create(envType string, deploymentType string, fwdProxyURI string) (respBody []byte, err error) { environment := []string{} @@ -390,3 +401,51 @@ func MarshalEnvironmentList(contents []byte) (envronmentList Environments, err e } return envronmentList, nil } + +func GetAddonsConfig(environment string) (respBody []byte, err error) { + + if environment == "" { + environment = apiclient.GetApigeeEnv() + } + + u, _ := url.Parse(apiclient.GetApigeeBaseURL()) + u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "environments", + environment, "addonsConfig") + + respBody, err = apiclient.HttpClient(u.String()) + return respBody, err +} + +func IsAnalyticsEnabled(environment string) (enabled bool, err error) { + var tmp string + apiclient.ClientPrintHttpResponse.Set(false) + tmp = apiclient.GetApigeeEnv() + apiclient.SetApigeeEnv(environment) + respBody, err := Get(false) + apiclient.SetApigeeEnv(tmp) + if err != nil { + return false, err + } + e := Environment{} + + if err = json.Unmarshal(respBody, &e); err != nil { + return false, err + } + + if e.Type == "BASE" { + return false, nil + } + + respBody, err = GetAddonsConfig(environment) + apiclient.ClientPrintHttpResponse.Set(apiclient.GetCmdPrintHttpResponseSetting()) + + if err != nil { + return false, err + } + addonsConfig := AddonsConfig{} + err = json.Unmarshal(respBody, &addonsConfig) + if err != nil { + return false, err + } + return addonsConfig.AnalyticsConfig.Enabled, nil +} diff --git a/internal/client/env/reports.go b/internal/client/env/reports.go index b8eeca518..d58eb0760 100644 --- a/internal/client/env/reports.go +++ b/internal/client/env/reports.go @@ -31,8 +31,9 @@ import ( ) const ( - proxy_dimension = "apiproxy" - selection = "sum(message_count)" + proxy_dimension = "apiproxy" + proxy_deployment_type = "proxy_deployment_type" + selection = "sum(message_count)" ) type report struct { @@ -55,32 +56,96 @@ type metric struct { } type apiCalls struct { - count int + count int + standardCount int + extensibleCount int sync.Mutex } var ApiCalls = &apiCalls{count: 0} -func TotalAPICallsInMonthAsync(environment string, month int, year int, envDetails bool, wg *sync.WaitGroup) { - defer wg.Done() - var total int +func TotalAPICallsInMonth(dimension bool, environment string, month int, year int, + envDetails bool, billingType string) { + + var totalApiCalls, totalExtensible, totalStandard int var err error + var analyticsAddon bool + + if billingType == "PAYG" { + if analyticsAddon, err = IsAnalyticsEnabled(environment); err != nil { + clilog.Error.Printf("error getting analytics addon information: %s\n", err) + return + } + + if !analyticsAddon { + return + } + } - if total, err = TotalAPICallsInMonth(environment, month, year); err != nil { + if totalApiCalls, totalExtensible, totalStandard, err = totalAPICallsInMonth(dimension, environment, month, year); err != nil { clilog.Error.Println(err) return } - ApiCalls.incrementCount(total) - if envDetails { - w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0) - fmt.Fprintf(w, "%s\t%d/%d\t%d", environment, month, year, total) - fmt.Fprintln(w) - w.Flush() + + if dimension { + ApiCalls.incrementExtensibleCount(totalExtensible) + ApiCalls.incrementStandardCount(totalStandard) + ApiCalls.incrementCount(totalApiCalls) + if envDetails { + w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0) + fmt.Fprintf(w, "%s\t%d/%d\t%d\t%d", environment, month, year, totalExtensible, totalStandard) + fmt.Fprintln(w) + w.Flush() + + } + } else { + ApiCalls.incrementCount(totalApiCalls) + if envDetails { + w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0) + fmt.Fprintf(w, "%s\t%d/%d\t%d", environment, month, year, totalApiCalls) + fmt.Fprintln(w) + w.Flush() + + } + } +} + +func totalAPICallsInMonth(dimension bool, environment string, month int, year int) (totalApiCalls int, totalExtensible int, totalStandard int, err error) { + environmentReport, err := getReport(proxy_deployment_type, environment, month, year) + if err != nil { + return -1, -1, -1, err + } + for _, e := range environmentReport.Environments { + for _, d := range e.Dimensions { + if dimension { + if d.Name == "EXTENSIBLE" { + for _, m := range d.Metrics { + calls, _ := strconv.Atoi(m.Values[0]) + totalExtensible = totalExtensible + calls + } + } else if d.Name == "STANDARD" { + for _, m := range d.Metrics { + calls, _ := strconv.Atoi(m.Values[0]) + totalStandard = totalStandard + calls + } + } else if d.Name == "(not set)" { + for _, m := range d.Metrics { + calls, _ := strconv.Atoi(m.Values[0]) + totalApiCalls = totalApiCalls + calls + } + } + } else { + for _, m := range d.Metrics { + calls, _ := strconv.Atoi(m.Values[0]) + totalApiCalls = totalApiCalls + calls + } + } + } } + return totalApiCalls, totalExtensible, totalStandard, nil } -func TotalAPICallsInMonth(environment string, month int, year int) (total int, err error) { - var apiCalls int +func getReport(dimension string, environment string, month int, year int) (r report, err error) { var respBody []byte // throttle API Calls @@ -97,28 +162,17 @@ func TotalAPICallsInMonth(environment string, month int, year int) (total int, e q.Set("timeRange", timeRange) u.RawQuery = q.Encode() - u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "environments", environment, "stats", proxy_dimension) + u.Path = path.Join(u.Path, apiclient.GetApigeeOrg(), "environments", environment, "stats", dimension) if respBody, err = apiclient.HttpClient(u.String()); err != nil { - return -1, err + return r, err } - environmentReport := report{} - - if err = json.Unmarshal(respBody, &environmentReport); err != nil { - return -1, err - } - - for _, e := range environmentReport.Environments { - for _, d := range e.Dimensions { - for _, m := range d.Metrics { - calls, _ := strconv.Atoi(m.Values[0]) - apiCalls = apiCalls + calls - } - } + if err = json.Unmarshal(respBody, &r); err != nil { + return r, err } - return apiCalls, nil + return r, nil } // GetCount @@ -126,11 +180,23 @@ func (c *apiCalls) GetCount() int { return c.count } +// GetExtensibleCount +func (c *apiCalls) GetExtensibleCount() int { + return c.extensibleCount +} + +// GetStandardCount +func (c *apiCalls) GetStandardCount() int { + return c.standardCount +} + // ResetCount func (c *apiCalls) ResetCount() { c.Lock() defer c.Unlock() c.count = 0 + c.extensibleCount = 0 + c.standardCount = 0 } // daysIn returns the number of days in a month for a given year. @@ -146,3 +212,17 @@ func (c *apiCalls) incrementCount(total int) { defer c.Unlock() c.count = c.count + total } + +// incrementStandardCount synchronizes counting +func (c *apiCalls) incrementStandardCount(total int) { + c.Lock() + defer c.Unlock() + c.standardCount = c.standardCount + total +} + +// incrementExtensibleCount synchronizes counting +func (c *apiCalls) incrementExtensibleCount(total int) { + c.Lock() + defer c.Unlock() + c.extensibleCount = c.extensibleCount + total +} diff --git a/internal/client/orgs/orgs.go b/internal/client/orgs/orgs.go index 0d168c104..c15273ff9 100644 --- a/internal/client/orgs/orgs.go +++ b/internal/client/orgs/orgs.go @@ -66,6 +66,7 @@ type organization struct { ApiConsumerDataLocation string `json:"apiConsumerDataLocation,omitempty"` ApigeeProjectId string `json:"apigeeProjectId,omitempty"` DisableVpcPeering bool `json:"disableVpcPeering,omitempty"` + SubscriptionPlan string `json:"subscriptionPlan,omitempty"` } type addonsConfig struct { @@ -74,6 +75,7 @@ type addonsConfig struct { MonetizationConfig addon `json:"monetizationConfig,omitempty"` ConnectorsPlatformConfig addon `json:"connectorsPlatformConfig,omitempty"` AdvancedApiSecurityConfig addon `json:"apiSecurityConfig,omitempty"` + AnalyticsConfig addon `json:"analyticsConfig,omitempty"` } type addon struct { @@ -197,7 +199,7 @@ func GetAddOn(addon string) (enabled bool) { u.Path = path.Join(u.Path, apiclient.GetApigeeOrg()) apiclient.DisableCmdPrintHttpResponse() - defer apiclient.EnableCmdPrintHttpResponse() + defer apiclient.SetPrintOutput(apiclient.GetCmdPrintHttpResponseSetting()) orgBody, err := apiclient.HttpClient(u.String()) if err != nil { @@ -219,6 +221,8 @@ func GetAddOn(addon string) (enabled bool) { return o.AddOnsConfig.AdvancedApiSecurityConfig.Enabled case "connectorsPlatformConfig": return o.AddOnsConfig.ConnectorsPlatformConfig.Enabled + case "analyticsConfig": + return o.AddOnsConfig.AnalyticsConfig.Enabled default: return false } @@ -367,7 +371,8 @@ func Update(description string, authorizedNetwork string) (respBody []byte, err } // SetAddons -func SetAddons(advancedApiOpsConfig bool, integrationConfig bool, monetizationConfig bool, connectorsConfig bool, apiSecurityConfig bool) (respBody []byte, err error) { +func SetAddons(advancedApiOpsConfig bool, integrationConfig bool, monetizationConfig bool, connectorsConfig bool, + apiSecurityConfig bool, analyticsConfig bool) (respBody []byte, err error) { apiclient.ClientPrintHttpResponse.Set(false) orgRespBody, err := Get() @@ -410,6 +415,10 @@ func SetAddons(advancedApiOpsConfig bool, integrationConfig bool, monetizationCo addonPayload = append(addonPayload, "\"apiSecurityConfig\":{\"enabled\":true}") } + if analyticsConfig || org.AddOnsConfig.AnalyticsConfig.Enabled { + addonPayload = append(addonPayload, "\"analyticsConfig\":{\"enabled\":true}") + } + payload := "{\"addonsConfig\":{" + strings.Join(addonPayload, ",") + "}}" u, _ := url.Parse(apiclient.GetApigeeBaseURL()) diff --git a/internal/client/orgs/reports.go b/internal/client/orgs/reports.go index cf197e19e..2679bf13d 100644 --- a/internal/client/orgs/reports.go +++ b/internal/client/orgs/reports.go @@ -17,7 +17,6 @@ package orgs import ( "encoding/json" "fmt" - "sync" "time" "internal/apiclient" @@ -27,8 +26,9 @@ import ( "internal/client/env" ) -func TotalAPICallsInMonth(month int, year int, envDetails bool, conn int) (total int, err error) { - var pwg sync.WaitGroup +func TotalAPICallsInMonth(month int, year int, envDetails bool, + proxyType bool, billingType string) (apiCalls int, extensibleApiCalls int, standardApiCalls int, err error) { + var envListBytes []byte var envList []string @@ -39,85 +39,60 @@ func TotalAPICallsInMonth(month int, year int, envDetails bool, conn int) (total defer apiclient.ClientPrintHttpResponse.Set(apiclient.GetCmdPrintHttpResponseSetting()) if envListBytes, err = env.List(); err != nil { - return -1, err + return -1, -1, -1, err } if err = json.Unmarshal(envListBytes, &envList); err != nil { - return -1, err + return -1, -1, -1, err } numEntities := len(envList) clilog.Debug.Printf("Found %d environments\n", numEntities) - clilog.Debug.Printf("Generate report with %d connections\n", conn) - - numOfLoops, remaining := numEntities/conn, numEntities%conn - - // ensure connections aren't greater than entities - if conn > numEntities { - conn = numEntities - } - - start := 0 - for i, end := 0, 0; i < numOfLoops; i++ { - pwg.Add(1) - end = (i * conn) + conn - clilog.Debug.Printf("Creating reports for a batch %d of environments\n", (i + 1)) - go batchReport(envList[start:end], month, year, envDetails, &pwg) - start = end - pwg.Wait() - } + batchReport(envList, month, year, envDetails, proxyType, billingType) - if remaining > 0 { - pwg.Add(1) - clilog.Debug.Printf("Creating reports for remaining %d environments\n", remaining) - go batchReport(envList[start:numEntities], month, year, envDetails, &pwg) - pwg.Wait() - } - - return env.ApiCalls.GetCount(), nil + return env.ApiCalls.GetCount(), env.ApiCalls.GetExtensibleCount(), env.ApiCalls.GetStandardCount(), nil } -func batchReport(envList []string, month int, year int, envDetails bool, pwg *sync.WaitGroup) { - defer pwg.Done() - // batch workgroup - var bwg sync.WaitGroup - - bwg.Add(len(envList)) - +func batchReport(envList []string, month int, year int, envDetails bool, proxyType bool, billingType string) { for _, environment := range envList { - go env.TotalAPICallsInMonthAsync(environment, month, year, envDetails, &bwg) + env.TotalAPICallsInMonth(proxyType, environment, month, year, envDetails, billingType) } - - bwg.Wait() } -func TotalAPICallsInYear(year int, envDetails bool, conn int) (total int, err error) { - var monthlyTotal int +func TotalAPICallsInYear(year int, envDetails bool, + proxyType bool, billingType string) (apiCalls int, extensibleApiCalls int, standardApiCalls int, err error) { + var monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal int t := time.Now() currentYear := t.Year() if year > currentYear { - return -1, fmt.Errorf("Invalid year. Year cannot be greater than current year") + return -1, -1, -1, fmt.Errorf("Invalid year. Year cannot be greater than current year") } if currentYear == year { currentMonth := t.Month() for i := 1; i <= int(currentMonth); i++ { // run the loop only till the current month - if monthlyTotal, err = TotalAPICallsInMonth(i, year, envDetails, conn); err != nil { - return -1, err + if monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal, err = + TotalAPICallsInMonth(i, year, envDetails, proxyType, billingType); err != nil { + return -1, -1, -1, err } - total = total + monthlyTotal + apiCalls = apiCalls + monthlyApiTotal + extensibleApiCalls = extensibleApiCalls + monthlyExtensibleTotal + standardApiCalls = standardApiCalls + monthlyStandardTotal } } else { for i := 1; i <= 12; i++ { // run the loop for each month - if monthlyTotal, err = TotalAPICallsInMonth(i, year, envDetails, conn); err != nil { - return -1, err + if monthlyApiTotal, monthlyExtensibleTotal, monthlyStandardTotal, err = + TotalAPICallsInMonth(i, year, envDetails, proxyType, billingType); err != nil { + return -1, -1, -1, err } - total = total + monthlyTotal + apiCalls = apiCalls + monthlyApiTotal + extensibleApiCalls = extensibleApiCalls + monthlyExtensibleTotal + standardApiCalls = standardApiCalls + monthlyStandardTotal } } - return total, nil + return apiCalls, extensibleApiCalls, standardApiCalls, nil } diff --git a/internal/client/orgs/reports_test.go b/internal/client/orgs/reports_test.go index b1fe44e31..a5d949ac6 100644 --- a/internal/client/orgs/reports_test.go +++ b/internal/client/orgs/reports_test.go @@ -33,7 +33,7 @@ func TestTotalAPICallsInMonth(t *testing.T) { currentMonth := int(currentTime.Month()) currentYear := int(currentTime.Year()) - if _, err := TotalAPICallsInMonth(currentMonth, currentYear, true, 1); err != nil { + if _, _, _, err := TotalAPICallsInMonth(currentMonth, currentYear, true, false, "PAYG"); err != nil { t.Fatalf("%v", err) } } diff --git a/internal/cmd/org/reportmonthly.go b/internal/cmd/org/reportmonthly.go index 9d8cfb8a8..ddd78c045 100644 --- a/internal/cmd/org/reportmonthly.go +++ b/internal/cmd/org/reportmonthly.go @@ -40,7 +40,20 @@ var MonthlyCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) (err error) { cmd.SilenceUsage = true - var apiCalls int + var apiCalls, extensibleApiCalls, standardApiCalls int + var apiHeader, billingType string + + apiclient.DisableCmdPrintHttpResponse() + if billingType, err = orgs.GetOrgField("billingType"); err != nil { + return err + } + + if proxyType { + apiHeader = proxyTypeHeader + } else { + apiHeader = apiCallsHeader + } + w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0) clilog.Warning.Println("This API is rate limited to 1 API Call per second") @@ -50,11 +63,12 @@ var MonthlyCmd = &cobra.Command{ } if envDetails { - fmt.Fprintln(w, "ENVIRONMENT\tMONTH\tAPI CALLS") + fmt.Fprintln(w, "ENVIRONMENT\tMONTH"+apiHeader) w.Flush() } - if apiCalls, err = orgs.TotalAPICallsInMonth(month, year, envDetails, conn); err != nil { + if apiCalls, extensibleApiCalls, standardApiCalls, err = orgs.TotalAPICallsInMonth(month, + year, envDetails, proxyType, billingType); err != nil { return err } @@ -62,8 +76,12 @@ var MonthlyCmd = &cobra.Command{ fmt.Printf("\nSummary\n\n") } - fmt.Fprintln(w, "ORGANIATION\tMONTH\tAPI CALLS") - fmt.Fprintf(w, "%s\t%d/%d\t%d\n", apiclient.GetApigeeOrg(), month, year, apiCalls) + fmt.Fprintln(w, "ORGANIZATION\tMONTH"+apiHeader) + if proxyType { + fmt.Fprintf(w, "%s\t%d/%d\t%d\t%d\n", apiclient.GetApigeeOrg(), month, year, extensibleApiCalls, standardApiCalls) + } else { + fmt.Fprintf(w, "%s\t%d/%d\t%d\n", apiclient.GetApigeeOrg(), month, year, apiCalls) + } fmt.Fprintln(w) w.Flush() @@ -72,8 +90,8 @@ var MonthlyCmd = &cobra.Command{ } var ( - month, year int - envDetails bool + month, year int + envDetails, proxyType bool ) func init() { @@ -83,8 +101,8 @@ func init() { -1, "Year") MonthlyCmd.Flags().BoolVarP(&envDetails, "env-details", "", false, "Print details of each environment") - MonthlyCmd.Flags().IntVarP(&conn, "conn", "c", - 4, "Number of connections") + MonthlyCmd.Flags().BoolVarP(&proxyType, "proxy-type", "", + false, "Split the API Calls by proxy type, standard vs extensible proxy") MonthlyCmd.Flags().StringVarP(&org, "org", "o", "", "Apigee organization name") diff --git a/internal/cmd/org/reports.go b/internal/cmd/org/reports.go index 32227431f..02800f50c 100644 --- a/internal/cmd/org/reports.go +++ b/internal/cmd/org/reports.go @@ -26,6 +26,9 @@ var ReportCmd = &cobra.Command{ Long: "Report Apigee Org Usage", } +const apiCallsHeader = "\tAPI CALLS" +const proxyTypeHeader = "\tEXTENSIBLE PROXY\tSTANDARD PROXY" + func init() { ReportCmd.AddCommand(MonthlyCmd) ReportCmd.AddCommand(YearlyCmd) diff --git a/internal/cmd/org/reportyearly.go b/internal/cmd/org/reportyearly.go index e81a5f9b2..176f6c1cf 100644 --- a/internal/cmd/org/reportyearly.go +++ b/internal/cmd/org/reportyearly.go @@ -40,7 +40,20 @@ var YearlyCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) (err error) { cmd.SilenceUsage = true - var apiCalls int + var apiCalls, extensibleApiCalls, standardApiCalls int + var apiHeader, billingType string + + apiclient.DisableCmdPrintHttpResponse() + if billingType, err = orgs.GetOrgField("billingType"); err != nil { + return err + } + + if proxyType { + apiHeader = proxyTypeHeader + } else { + apiHeader = apiCallsHeader + } + w := tabwriter.NewWriter(os.Stdout, 32, 4, 0, ' ', 0) clilog.Warning.Println("This API is rate limited to 1 API Call per second") @@ -50,11 +63,12 @@ var YearlyCmd = &cobra.Command{ } if envDetails { - fmt.Fprintln(w, "ENVIRONMENT\tMONTH\tAPI CALLS") + fmt.Fprintln(w, "ENVIRONMENT\tMONTH"+apiHeader) w.Flush() } - if apiCalls, err = orgs.TotalAPICallsInYear(year, envDetails, conn); err != nil { + if apiCalls, extensibleApiCalls, standardApiCalls, err = orgs.TotalAPICallsInYear(year, + envDetails, proxyType, billingType); err != nil { return err } @@ -62,8 +76,12 @@ var YearlyCmd = &cobra.Command{ fmt.Printf("\nSummary\n\n") } - fmt.Fprintln(w, "ORGANIZATION\tYEAR\tAPI CALLS") - fmt.Fprintf(w, "%s\t%d\t%d\n", apiclient.GetApigeeOrg(), year, apiCalls) + fmt.Fprintln(w, "ORGANIZATION\tYEAR"+apiHeader) + if proxyType { + fmt.Fprintf(w, "%s\t%d\t%d\t%d\n", apiclient.GetApigeeOrg(), year, extensibleApiCalls, standardApiCalls) + } else { + fmt.Fprintf(w, "%s\t%d\t%d\n", apiclient.GetApigeeOrg(), year, apiCalls) + } fmt.Fprintln(w) w.Flush() @@ -76,8 +94,8 @@ func init() { -1, "Year") YearlyCmd.Flags().BoolVarP(&envDetails, "env-details", "", false, "Print details of each environment") - YearlyCmd.Flags().IntVarP(&conn, "conn", "c", - 4, "Number of connections") + YearlyCmd.Flags().BoolVarP(&proxyType, "proxy-type", "", + false, "Split the API Calls by proxy type, standard vs extensible proxy") YearlyCmd.Flags().StringVarP(&org, "org", "o", "", "Apigee organization name") diff --git a/internal/cmd/org/setaddons.go b/internal/cmd/org/setaddons.go index 24b635333..763c9e8fa 100644 --- a/internal/cmd/org/setaddons.go +++ b/internal/cmd/org/setaddons.go @@ -35,12 +35,12 @@ var SetAddonCmd = &cobra.Command{ cmd.SilenceUsage = true _, err = orgs.SetAddons(advancedAPIOpsConfig, integrationConfig, - monetizationConfig, connectorsConfig, apiSecurityConfig) + monetizationConfig, connectorsConfig, apiSecurityConfig, analyticsConfig) return }, } -var advancedAPIOpsConfig, integrationConfig, monetizationConfig, connectorsConfig, apiSecurityConfig bool +var advancedAPIOpsConfig, integrationConfig, monetizationConfig, connectorsConfig, apiSecurityConfig, analyticsConfig bool func init() { SetAddonCmd.Flags().StringVarP(&org, "org", "o", @@ -55,4 +55,6 @@ func init() { false, "Enable Apigee Connectors") SetAddonCmd.Flags().BoolVarP(&apiSecurityConfig, "advapisec", "", false, "Enable Apigee Advanced API Security") + SetAddonCmd.Flags().BoolVarP(&analyticsConfig, "analytics", "", + false, "Enable Apigee Analytics") }