internal/cmd/root.go (187 lines of code) (raw):
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"context"
"encoding/json"
"fmt"
"internal/apiclient"
"internal/clilog"
"internal/cmd/authconfigs"
"internal/cmd/certificates"
"internal/cmd/connectors"
"internal/cmd/endpoints"
"internal/cmd/integrations"
"internal/cmd/preferences"
"internal/cmd/provision"
"internal/cmd/render"
"internal/cmd/sfdcchannels"
"internal/cmd/sfdcinstances"
"internal/cmd/token"
"internal/cmd/tree"
"internal/cmd/utils"
"io"
"net/http"
"os"
"strconv"
"github.com/spf13/cobra"
)
// RootCmd to manage integrationcli
var RootCmd = &cobra.Command{
Use: "integrationcli",
Short: "Utility to work with GCP App Integration & Connectors",
Long: "This command lets you interact with GCP Application Integration and Integration Connector APIs.",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
cmdServiceAccount := utils.GetStringParam(cmd.Flag("account"))
cmdToken := utils.GetStringParam(cmd.Flag("token"))
if metadataToken && defaultToken {
return fmt.Errorf("metadata-token and default-token cannot be used together")
}
if metadataToken && (cmdServiceAccount != "" || cmdToken != "") {
return fmt.Errorf("metadata-token cannot be used with token or account flags")
}
if defaultToken && (cmdServiceAccount != "" || cmdToken != "") {
return fmt.Errorf("default-token cannot be used with token or account flags")
}
if cmdServiceAccount != "" && cmdToken != "" {
return fmt.Errorf("token and account flags cannot be used together")
}
if !disableCheck {
if ok, _ := apiclient.TestAndUpdateLastCheck(); !ok {
latestVersion, _ := getLatestVersion()
if cmd.Version == "" {
clilog.Debug.Println("integrationcli wasn't built with a valid Version tag.")
} else if latestVersion != "" && cmd.Version != latestVersion {
clilog.Info.Printf("You are using %s, the latest version %s is available for download\n",
cmd.Version, latestVersion)
}
}
}
apiclient.SetAPI(api)
if !metadataToken && !defaultToken {
apiclient.SetServiceAccount(cmdServiceAccount)
apiclient.SetIntegrationToken(cmdToken)
}
if metadataToken {
return apiclient.GetMetadataAccessToken()
}
if defaultToken {
return apiclient.GetDefaultAccessToken()
}
_ = apiclient.SetAccessToken()
return nil
},
SilenceUsage: getUsageFlag(),
SilenceErrors: getErrorsFlag(),
}
func Execute() {
if err := RootCmd.Execute(); err != nil {
clilog.Error.Println(err)
}
}
var (
disableCheck, printOutput, noOutput, suppressWarnings, verbose, metadataToken, defaultToken bool
api apiclient.API
)
const ENABLED = "true"
func init() {
var accessToken, serviceAccount string
cobra.OnInitialize(initConfig)
RootCmd.PersistentFlags().StringVarP(&accessToken, "token", "t",
"", "Google OAuth Token")
RootCmd.PersistentFlags().StringVarP(&serviceAccount, "account", "a",
"", "Path Service Account private key in JSON")
RootCmd.PersistentFlags().BoolVarP(&disableCheck, "disable-check", "",
false, "Disable check for newer versions")
RootCmd.PersistentFlags().BoolVarP(&printOutput, "print-output", "",
true, "Control printing of info log statements")
RootCmd.PersistentFlags().BoolVarP(&noOutput, "no-output", "",
false, "Disable printing all statements to stdout")
RootCmd.Flags().BoolVarP(&suppressWarnings, "suppress-warnings", "",
false, "Disable printing warning statements to stderr")
RootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "",
false, "Enable verbose output from integrationcli")
RootCmd.PersistentFlags().BoolVarP(&metadataToken, "metadata-token", "",
false, "Metadata OAuth2 access token")
RootCmd.PersistentFlags().BoolVarP(&defaultToken, "default-token", "",
false, "Use Google default application credentials access token")
RootCmd.PersistentFlags().Var(&api, "api", "Sets the control plane API. Must be one of prod, "+
"staging or autopush; default is prod")
RootCmd.AddCommand(integrations.Cmd)
RootCmd.AddCommand(preferences.Cmd)
RootCmd.AddCommand(authconfigs.Cmd)
RootCmd.AddCommand(connectors.Cmd)
RootCmd.AddCommand(token.Cmd)
RootCmd.AddCommand(certificates.Cmd)
RootCmd.AddCommand(sfdcinstances.Cmd)
RootCmd.AddCommand(sfdcchannels.Cmd)
RootCmd.AddCommand(endpoints.Cmd)
RootCmd.AddCommand(provision.Cmd)
RootCmd.AddCommand(tree.Cmd)
RootCmd.AddCommand(render.Cmd)
}
func initConfig() {
debug := false
var skipCache bool
if os.Getenv("INTEGRATIONCLI_DEBUG") == ENABLED || verbose {
debug = true
}
skipCache, _ = strconv.ParseBool(os.Getenv("INTEGRATIONCLI_SKIPCACHE"))
if noOutput {
printOutput = noOutput
}
if os.Getenv("INTEGRATIONCLI_DISABLE_RATELIMIT") == ENABLED {
clilog.Debug.Println("integrationcli ratelimit is disabled")
apiclient.SetRate(apiclient.None)
} else {
apiclient.SetRate(apiclient.IntegrationAPI)
}
apiclient.NewIntegrationClient(apiclient.IntegrationClientOptions{
TokenCheck: true,
PrintOutput: printOutput,
NoOutput: noOutput,
DebugLog: debug,
SkipCache: skipCache,
MetadataToken: metadataToken,
})
}
// GetRootCmd returns the root of the cobra command-tree.
func GetRootCmd() *cobra.Command {
return RootCmd
}
func getLatestVersion() (version string, err error) {
var req *http.Request
const endpoint = "https://api.github.com/repos/GoogleCloudPlatform/" +
"application-integration-management-toolkit/releases/latest"
client := &http.Client{}
contentType := "application/json"
ctx := context.Background()
req, err = http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return "", err
}
req.Header.Set("Content-Type", contentType)
resp, err := client.Do(req)
if err != nil {
return "", err
}
if resp != nil {
defer resp.Body.Close()
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var result map[string]interface{}
err = json.Unmarshal(respBody, &result)
if err != nil {
return "", err
}
if result["tag_name"] == "" {
clilog.Debug.Println("Unable to determine latest tag, skipping this information")
return "", nil
}
return fmt.Sprintf("%s", result["tag_name"]), nil
}
// getUsageFlag
func getUsageFlag() bool {
return os.Getenv("INTEGRATIONCLI_NO_USAGE") == ENABLED
}
// getErrorsFlag
func getErrorsFlag() bool {
return os.Getenv("INTEGRATIONCLI_NO_ERRORS") == ENABLED
}