这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ curl -L https://raw.githubusercontent.com/apigee/apigeecli/main/downloadLatest.s

NOTE: The signature is not verified and the original zip is not preserved.

<details>
<summary>Signature Verification</summary>

### Signature Verification
To test the signature of the binary, import the gpg public key:

```sh
Expand All @@ -39,6 +42,8 @@ gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 72D1 1E3A 3B1E 9FE2 2110 EC45 A714 872F 32F3 4390
```

</details>

## Getting Started

### User Tokens
Expand All @@ -50,23 +55,15 @@ token=$(gcloud auth print-access-token)
apigeecli orgs list -t $token
```

### Set Preferences
If you are using the same GCP project for Apigee, then consider setting up preferences so they don't have to be included in every command. Preferences are written to the `$HOME/.apigeecli` folder

```
project=$(gcloud config get-value project | head -n 1)

apigeecli prefs set -o $project
```
### Metadata OAuth2 Access Tokens

Subsequent commands can be like this:
If you are using `apigeecli` on Cloud Shell, GCE instances, Cloud Build, then you can use the metadata to get the access token

```
token=$(gcloud auth print-access-token)
apigeecli orgs get -t $token #fetches the org details of the org set in preferences
```sh
apigeecli orgs list --metadata-token
```

### Access Token Generation
### Access Token Generation from Service Accounts

`apigeecli` can use the service account directly and obtain an access token.

Expand Down Expand Up @@ -95,6 +92,27 @@ token=$(gcloud auth print-access-token)
apigeecli token cache -t $token
```

or
```bash
apigeecli token cache --metadata-token
```

## Set Preferences
If you are using the same GCP project for Apigee, then consider setting up preferences so they don't have to be included in every command. Preferences are written to the `$HOME/.apigeecli` folder

```
project=$(gcloud config get-value project | head -n 1)

apigeecli prefs set -o $project
```

Subsequent commands can be like this:

```
token=$(gcloud auth print-access-token)
apigeecli orgs get -t $token #fetches the org details of the org set in preferences
```

## Container download
The lastest container version for apigeecli can be downloaded via

Expand Down
25 changes: 21 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,18 @@ var RootCmd = &cobra.Command{
Short: "Utility to work with Apigee APIs.",
Long: "This command lets you interact with Apigee APIs.",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
apiclient.SetServiceAccount(serviceAccount)
apiclient.SetApigeeToken(accessToken)
if metadataToken && (serviceAccount != "" || accessToken != "") {
return fmt.Errorf("metadata-token cannot be used with token or account flags")
}

if serviceAccount != "" && accessToken != "" {
return fmt.Errorf("token and account flags cannot be used together")
}

if !metadataToken {
apiclient.SetServiceAccount(serviceAccount)
apiclient.SetApigeeToken(accessToken)
}

if !disableCheck {
if ok, _ := apiclient.TestAndUpdateLastCheck(); !ok {
Expand All @@ -78,6 +88,10 @@ var RootCmd = &cobra.Command{
}
}

if metadataToken {
return apiclient.GetDefaultAccessToken()
}

_ = apiclient.SetAccessToken()

return nil
Expand All @@ -93,8 +107,8 @@ func Execute() {
}

var (
accessToken, serviceAccount string
disableCheck, printOutput, noOutput bool
accessToken, serviceAccount string
disableCheck, printOutput, noOutput, metadataToken bool
)

const ENABLED = "true"
Expand All @@ -117,6 +131,9 @@ func init() {
RootCmd.PersistentFlags().BoolVarP(&noOutput, "no-output", "",
false, "Disable printing all statements to stdout")

RootCmd.PersistentFlags().BoolVarP(&metadataToken, "metadata-token", "",
false, "Metadata OAuth2 access token")

RootCmd.AddCommand(apis.Cmd)
RootCmd.AddCommand(org.Cmd)
RootCmd.AddCommand(sync.Cmd)
Expand Down
1 change: 1 addition & 0 deletions internal/apiclient/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type ApigeeClientOptions struct {
PrintOutput bool // prints output from http calls
NoOutput bool // Disable all statements to stdout
ProxyUrl string // use a proxy url
MetadataToken bool // use metadata outh2 token
APIRate Rate // throttle api calls to Apigee
}

Expand Down
79 changes: 79 additions & 0 deletions internal/apiclient/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,82 @@ func SetAccessToken() error {
}
return fmt.Errorf("token expired: request a new access token or pass the service account")
}

func getMetadata(metadata string) (respBpdy []byte, err error) {
var req *http.Request

metadataURL := fmt.Sprintf(
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/%s", metadata)

err = GetHttpClient()
if err != nil {
return nil, err
}

if DryRun() {
return nil, nil
}

clilog.Debug.Println("Connecting to: ", metadataURL)

req, err = http.NewRequest(http.MethodGet, metadataURL, nil)
if err != nil {
clilog.Error.Println("error in client: ", err)
return nil, err
}

req.Header.Set("Metadata-Flavor", "Google")
resp, err := ApigeeAPIClient.Do(req)
if err != nil {
clilog.Error.Println("error connecting: ", err)
return nil, err
}

if resp != nil {
defer resp.Body.Close()
}

if resp == nil {
clilog.Error.Println("error in response: Response was null")
return nil, fmt.Errorf("error in response: Response was null")
}

respBody, err := io.ReadAll(resp.Body)
if err != nil {
clilog.Error.Println("error in response: ", err)
return nil, err
} else if resp.StatusCode > 399 {
clilog.Debug.Printf("status code %d, error in response: %s\n", resp.StatusCode, string(respBody))
clilog.HttpError.Println(string(respBody))
return nil, errors.New(getErrorMessage(resp.StatusCode))
}
return respBody, err
}

// GetDefaultAccessToken
func GetDefaultAccessToken() (err error) {
var tokenResponse map[string]interface{}

respBody, err := getMetadata("token")
if err != nil {
return err
}

err = json.Unmarshal(respBody, &tokenResponse)
if err != nil {
return err
}

SetApigeeToken(tokenResponse["access_token"].(string))

ClientPrintHttpResponse.Set(false)
defer ClientPrintHttpResponse.Set(GetCmdPrintHttpResponseSetting())

respBody, _ = getMetadata("email")
clilog.Debug.Println("service token email: ", string(respBody))

respBody, _ = getMetadata("scopes")
clilog.Debug.Println("scopes: ", string(respBody))

return nil
}