diff --git a/apiclient/token.go b/apiclient/token.go index b7ce8876..d34d4770 100644 --- a/apiclient/token.go +++ b/apiclient/token.go @@ -92,6 +92,7 @@ func generateAccessToken(privateKey string) (string, error) { const tokenEndpoint = "https://oauth2.googleapis.com/token" const grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" + var respBody []byte //oAuthAccessToken is a structure to hold OAuth response type oAuthAccessToken struct { @@ -125,19 +126,32 @@ func generateAccessToken(privateKey string) (string, error) { clilog.Error.Println("failed to generate oauth token: ", err) return "", err } - defer resp.Body.Close() - if resp.StatusCode != 200 { - bodyBytes, _ := ioutil.ReadAll(resp.Body) - clilog.Error.Println("error in response: ", string(bodyBytes)) - return "", errors.New("error in response") + + if resp != nil { + defer resp.Body.Close() } - decoder := json.NewDecoder(resp.Body) - accessToken := oAuthAccessToken{} - if err := decoder.Decode(&accessToken); err != nil { + + if resp == nil { + clilog.Error.Println("error in response: Response was null") + return "", errors.New("error in response: Response was null") + } + + respBody, err = ioutil.ReadAll(resp.Body) + if err != nil { clilog.Error.Println("error in response: ", err) - return "", errors.New("error in response") + return "", fmt.Errorf("error in response: ", err) + } else if resp.StatusCode > 399 { + clilog.Error.Printf("status code %d, error in response: %s\n", resp.StatusCode, string(respBody)) + return "", fmt.Errorf("status code %d, error in response: %s\n", resp.StatusCode, string(respBody)) } + + accessToken := oAuthAccessToken{} + if err = json.Unmarshal(respBody, &accessToken); err != nil { + return "", err + } + clilog.Info.Println("access token : ", accessToken) + SetApigeeToken(accessToken.AccessToken) _ = WriteToken(accessToken.AccessToken) return accessToken.AccessToken, nil diff --git a/bundlegen/proxybundle/proxybundle.go b/bundlegen/proxybundle/proxybundle.go index 9e261725..8b9065f9 100644 --- a/bundlegen/proxybundle/proxybundle.go +++ b/bundlegen/proxybundle/proxybundle.go @@ -139,6 +139,10 @@ func writeXMLData(fileName string, data string) error { return nil } +func GenerateArchiveBundle(pathToZip, destinationPath string) error { + return archiveBundle(pathToZip, destinationPath) +} + func archiveBundle(pathToZip, destinationPath string) error { destinationFile, err := os.Create(destinationPath) if err != nil { diff --git a/cmd/env/crtarchive.go b/cmd/env/crtarchive.go index 5f7157ca..3df5f70d 100644 --- a/cmd/env/crtarchive.go +++ b/cmd/env/crtarchive.go @@ -15,34 +15,119 @@ package env import ( + "encoding/json" + "fmt" + "strings" + "time" + "github.com/spf13/cobra" "github.com/srinandan/apigeecli/apiclient" + "github.com/srinandan/apigeecli/bundlegen/proxybundle" "github.com/srinandan/apigeecli/client/env" + "github.com/srinandan/apigeecli/client/operations" ) +type op struct { + Name string `json:"name,omitempty"` + Metadata metadata `json:"metadata,omitempty"` + Done bool `json:"done,omitempty"` + Error operationError `json:"error,omitempty"` +} + +type operationError struct { + Message string `json:"message,omitempty"` + Code int `json:"code,omitempty"` +} + +type metadata struct { + Type string `json:"@type,omitempty"` + OperationType string `json:"operationType,omitempty"` + TargetResourceName string `json:"targetResourceName,omitempty"` + State string `json:"state,omitempty"` +} + //CreateArchiveCmd to create env archive var CreateArchiveCmd = &cobra.Command{ Use: "create", Short: "Create a new revision of archive in the environment", Long: "Create a new revision of archive in the environment", Args: func(cmd *cobra.Command, args []string) (err error) { + if zipfile != "" && folder != "" { + return fmt.Errorf("Both zipfile and folder path cannot be passed") + } apiclient.SetApigeeEnv(environment) return apiclient.SetApigeeOrg(org) }, RunE: func(cmd *cobra.Command, args []string) (err error) { - _, err = env.CreateArchive(name, zipfile) + + if folder != "" { + zipfile = name + ".zip" + proxybundle.GenerateArchiveBundle(folder, zipfile) + } + + respBody, err := env.CreateArchive(name, zipfile) + if wait { + archiveResponse := op{} + if err = json.Unmarshal(respBody, &archiveResponse); err != nil { + return + } + + s := strings.Split(archiveResponse.Name, "/") + operationId := s[len(s)-1] + + fmt.Printf("Deployment operation id is %s\n", operationId) + fmt.Printf("Checking deployment status in %d seconds\n", interval) + + apiclient.SetPrintOutput(false) + + stop := apiclient.Every(interval*time.Second, func(time.Time) bool { + var respOpsBody []byte + respMap := op{} + if respOpsBody, err = operations.Get(operationId); err != nil { + return true + } + + if err = json.Unmarshal(respOpsBody, &respMap); err != nil { + return true + } + + if respMap.Metadata.State == "IN_PROGRESS" { + fmt.Printf("Archive deployment status is: %s. Waiting %d seconds.\n", respMap.Metadata.State, interval) + return true + } else if respMap.Metadata.State == "FINISHED" { + if respMap.Error == (operationError{}) { + fmt.Println("Archive deployment completed with status: ", respMap.Metadata.State) + } else { + fmt.Printf("Archive deployment failed with status: %s", respMap.Error.Message) + } + return false + } else { + fmt.Printf("Unknown state %s", respMap.Metadata.State) + return false + } + }) + + <-stop + + } return }, } -var zipfile string +var zipfile, folder string +var wait bool + +const interval = 10 func init() { CreateArchiveCmd.Flags().StringVarP(&name, "name", "n", "", "Archive name") CreateArchiveCmd.Flags().StringVarP(&zipfile, "zipfile", "z", "", "Archive Zip file") + CreateArchiveCmd.Flags().StringVarP(&folder, "folder", "f", + "", "Archive Folder") + CreateArchiveCmd.Flags().BoolVarP(&wait, "wait", "w", + false, "Wait for deployment") _ = CreateArchiveCmd.MarkFlagRequired("name") - _ = CreateArchiveCmd.MarkFlagRequired("zipfile") } diff --git a/test/apigee-eg4a-err.zip b/test/apigee-eg4a-err.zip new file mode 100644 index 00000000..316f051f Binary files /dev/null and b/test/apigee-eg4a-err.zip differ diff --git a/test/apigee-eg4a.zip b/test/apigee-eg4a.zip new file mode 100644 index 00000000..f05099fa Binary files /dev/null and b/test/apigee-eg4a.zip differ