tessl install tessl/golang-cloud-google-com--go--kms@1.24.0Go Client Library for Google Cloud Key Management Service (KMS) API for managing cryptographic keys and performing cryptographic operations
KMS list operations return iterator types for efficient pagination through large result sets. All iterators follow the same pattern and provide three methods for accessing results: Next(), PageInfo(), and All().
Packages:
cloud.google.com/go/kms/apiv1 - Main KMS iteratorscloud.google.com/go/kms/inventory/apiv1 - Inventory iteratorsimport "google.golang.org/api/iterator"
it := client.ListCryptoKeys(ctx, req)
for {
item, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// Handle error
}
// Use item
}it := client.ListCryptoKeys(ctx, req)
for item, err := range it.All() {
if err != nil {
// Handle error
}
// Use item
}it := client.ListCryptoKeys(ctx, req)
pageInfo := it.PageInfo()
pageInfo.MaxSize = 50 // Items per page
for pageInfo.HasNext() {
page := make([]*kmspb.CryptoKey, 0, pageInfo.PageSize())
nextPageToken, err := iterator.NewPager(it, pageInfo.PageSize(), "").NextPage(&page)
if err != nil {
// Handle error
}
// Process page
for _, item := range page {
// Use item
}
}type CryptoKeyIterator struct {
Response interface{} // Raw response for current page (cast to RPC response type)
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.CryptoKey, nextPageToken string, err error)
}Manages a stream of *kmspb.CryptoKey for paginated list results.
Methods:
func (it *CryptoKeyIterator) Next() (*kmspb.CryptoKey, error)
func (it *CryptoKeyIterator) PageInfo() *iterator.PageInfo
func (it *CryptoKeyIterator) All() iter.Seq2[*kmspb.CryptoKey, error]Returned By:
KeyManagementClient.ListCryptoKeys()KeyDashboardClient.ListCryptoKeys()Example:
req := &kmspb.ListCryptoKeysRequest{
Parent: "projects/my-project/locations/us-central1/keyRings/my-keyring",
PageSize: 100,
}
it := client.ListCryptoKeys(ctx, req)
count := 0
for {
key, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
count++
fmt.Printf("CryptoKey %d: %s\n", count, key.Name)
}
fmt.Printf("Total: %d keys\n", count)type CryptoKeyVersionIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.CryptoKeyVersion, nextPageToken string, err error)
}Manages a stream of *kmspb.CryptoKeyVersion for paginated list results.
Methods:
func (it *CryptoKeyVersionIterator) Next() (*kmspb.CryptoKeyVersion, error)
func (it *CryptoKeyVersionIterator) PageInfo() *iterator.PageInfo
func (it *CryptoKeyVersionIterator) All() iter.Seq2[*kmspb.CryptoKeyVersion, error]Returned By:
KeyManagementClient.ListCryptoKeyVersions()Example:
req := &kmspb.ListCryptoKeyVersionsRequest{
Parent: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",
}
it := client.ListCryptoKeyVersions(ctx, req)
for {
version, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Version: %s (State: %v)\n", version.Name, version.State)
}type KeyRingIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.KeyRing, nextPageToken string, err error)
}Manages a stream of *kmspb.KeyRing for paginated list results.
Methods:
func (it *KeyRingIterator) Next() (*kmspb.KeyRing, error)
func (it *KeyRingIterator) PageInfo() *iterator.PageInfo
func (it *KeyRingIterator) All() iter.Seq2[*kmspb.KeyRing, error]Returned By:
KeyManagementClient.ListKeyRings()type ImportJobIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.ImportJob, nextPageToken string, err error)
}Manages a stream of *kmspb.ImportJob for paginated list results.
Methods:
func (it *ImportJobIterator) Next() (*kmspb.ImportJob, error)
func (it *ImportJobIterator) PageInfo() *iterator.PageInfo
func (it *ImportJobIterator) All() iter.Seq2[*kmspb.ImportJob, error]Returned By:
KeyManagementClient.ListImportJobs()type KeyHandleIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.KeyHandle, nextPageToken string, err error)
}Manages a stream of *kmspb.KeyHandle for paginated list results.
Methods:
func (it *KeyHandleIterator) Next() (*kmspb.KeyHandle, error)
func (it *KeyHandleIterator) PageInfo() *iterator.PageInfo
func (it *KeyHandleIterator) All() iter.Seq2[*kmspb.KeyHandle, error]Returned By:
AutokeyClient.ListKeyHandles()type EkmConnectionIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*kmspb.EkmConnection, nextPageToken string, err error)
}Manages a stream of *kmspb.EkmConnection for paginated list results.
Methods:
func (it *EkmConnectionIterator) Next() (*kmspb.EkmConnection, error)
func (it *EkmConnectionIterator) PageInfo() *iterator.PageInfo
func (it *EkmConnectionIterator) All() iter.Seq2[*kmspb.EkmConnection, error]Returned By:
EkmClient.ListEkmConnections()type LocationIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*locationpb.Location, nextPageToken string, err error)
}Manages a stream of *locationpb.Location for paginated list results.
Methods:
func (it *LocationIterator) Next() (*locationpb.Location, error)
func (it *LocationIterator) PageInfo() *iterator.PageInfo
func (it *LocationIterator) All() iter.Seq2[*locationpb.Location, error]Returned By:
KeyManagementClient.ListLocations()AutokeyClient.ListLocations()AutokeyAdminClient.ListLocations()EkmClient.ListLocations()KeyDashboardClient.ListLocations()KeyTrackingClient.ListLocations()type ProtectedResourceIterator struct {
Response interface{}
InternalFetch func(pageSize int, pageToken string) (results []*inventorypb.ProtectedResource, nextPageToken string, err error)
}Manages a stream of *inventorypb.ProtectedResource for search results.
Methods:
func (it *ProtectedResourceIterator) Next() (*inventorypb.ProtectedResource, error)
func (it *ProtectedResourceIterator) PageInfo() *iterator.PageInfo
func (it *ProtectedResourceIterator) All() iter.Seq2[*inventorypb.ProtectedResource, error]Returned By:
KeyTrackingClient.SearchProtectedResources()Example:
import "cloud.google.com/go/kms/inventory/apiv1/inventorypb"
req := &inventorypb.SearchProtectedResourcesRequest{
Scope: "organizations/123456789",
CryptoKey: "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key",
PageSize: 100,
}
it := trackingClient.SearchProtectedResources(ctx, req)
for {
resource, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Protected: %s (%s in %s)\n", resource.Name, resource.ResourceType, resource.Location)
}All iterators provide a PageInfo() method that returns *iterator.PageInfo:
type PageInfo struct {
// MaxSize is the maximum number of items returned per page.
// If zero or negative, the iterator will determine a reasonable page size.
MaxSize int
// Token is the page token to use for the next request.
Token string
}
func (p *PageInfo) HasNext() bool
func (p *PageInfo) Remaining() int
func (p *PageInfo) PageSize() intExample:
it := client.ListCryptoKeys(ctx, req)
pageInfo := it.PageInfo()
pageInfo.MaxSize = 50 // Request 50 items per page
for pageInfo.HasNext() {
key, err := it.Next()
if err != nil {
log.Fatal(err)
}
// Process key
}func collectAllKeys(it *CryptoKeyIterator) ([]*kmspb.CryptoKey, error) {
var keys []*kmspb.CryptoKey
for {
key, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, err
}
keys = append(keys, key)
}
return keys, nil
}func findEnabledVersions(it *CryptoKeyVersionIterator) ([]*kmspb.CryptoKeyVersion, error) {
var enabled []*kmspb.CryptoKeyVersion
for {
version, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, err
}
if version.State == kmspb.CryptoKeyVersion_ENABLED {
enabled = append(enabled, version)
}
}
return enabled, nil
}func processInBatches(it *CryptoKeyIterator, batchSize int) error {
pageInfo := it.PageInfo()
pageInfo.MaxSize = batchSize
batch := make([]*kmspb.CryptoKey, 0, batchSize)
for {
key, err := it.Next()
if err == iterator.Done {
if len(batch) > 0 {
// Process final batch
if err := processBatch(batch); err != nil {
return err
}
}
break
}
if err != nil {
return err
}
batch = append(batch, key)
if len(batch) >= batchSize {
// Process batch
if err := processBatch(batch); err != nil {
return err
}
batch = batch[:0] // Reset batch
}
}
return nil
}func findFirstMatchingKey(it *CryptoKeyIterator, predicate func(*kmspb.CryptoKey) bool) (*kmspb.CryptoKey, error) {
for {
key, err := it.Next()
if err == iterator.Done {
return nil, nil // Not found
}
if err != nil {
return nil, err
}
if predicate(key) {
return key, nil
}
}
}
// Usage
key, err := findFirstMatchingKey(it, func(k *kmspb.CryptoKey) bool {
return k.Purpose == kmspb.CryptoKey_ENCRYPT_DECRYPT
})func countItems(it *CryptoKeyIterator) (int, error) {
count := 0
for {
_, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return 0, err
}
count++
}
return count, nil
}it := client.ListCryptoKeys(ctx, req)
for {
key, err := it.Next()
if err == iterator.Done {
// Normal completion
break
}
if err != nil {
// Check for specific error types
if status.Code(err) == codes.PermissionDenied {
log.Printf("Permission denied: %v", err)
return err
}
// Handle other errors
return fmt.Errorf("iteration error: %w", err)
}
// Process key
}iterator.Done to detect normal completionNext() call after a page boundary makes a new API call