Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Gemini Code Assist for Google Cloud resources #12181

Closed
Show file tree
Hide file tree
Changes from 11 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
110 changes: 110 additions & 0 deletions mmv1/products/cloudaicompanion/CodeRepositoryIndex.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Copyright 2024 Google Inc.
# 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.

---
name: CodeRepositoryIndex
description: The resource for managing Code Repository Indexes for Gemini Code Assist.
min_version: 'beta'
base_url: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes
self_link: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}
create_url: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes?codeRepositoryIndexId={{code_repository_index_id}}
id_format: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}
import_format:
- projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}
examples:
- name: "gemini_code_repository_index_basic"
min_version: 'beta'
primary_resource_id: "example"
test_vars_overrides:
cri_id: '"cri-example"'
exclude_test: true
autogen_async: true
async:
operation:
timeouts:
insert_minutes: 90
update_minutes: 90
delete_minutes: 90
path: name
base_url: "{{op_id}}"
wait_ms: 1000
actions:
- create
- delete
- update
type: OpAsync
result:
resource_inside_response: true
path: response
error:
path: error
message: message
include_project: false
custom_code:
custom_create: templates/terraform/custom_create/code_repository_index.go.tmpl
custom_update: templates/terraform/custom_update/code_repository_index.go.tmpl
parameters:
- name: location
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
min_version: 'beta'
immutable: true
url_param_only: true
required: true
- name: codeRepositoryIndexId
type: String
description: Required. Id of the requesting object
min_version: 'beta'
immutable: true
url_param_only: true
required: true
properties:
- name: updateTime
type: String
description: Output only. Update time stamp
min_version: 'beta'
output: true
- name: state
type: String
description: |-
Output only. Code Repository Index instance State
Possible values:
STATE_UNSPECIFIED
CREATING
ACTIVE
DELETING
SUSPENDED
min_version: 'beta'
output: true
- name: labels
type: KeyValueLabels
description: Optional. Labels as key value pairs
min_version: 'beta'
- name: kmsKey
type: String
description: |-
Optional. Immutable. Customer-managed encryption key name, in the format
projects/*/locations/*/keyRings/*/cryptoKeys/*.
min_version: 'beta'
immutable: true
- name: name
type: String
description: Immutable. Identifier. name of resource
min_version: 'beta'
output: true
immutable: true
- name: createTime
type: String
description: Output only. Create time stamp
min_version: 'beta'
output: true
141 changes: 141 additions & 0 deletions mmv1/products/cloudaicompanion/RepositoryGroup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Copyright 2024 Google Inc.
# 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.

---
name: RepositoryGroup
description: The resource for managing Repository Groups for Gemini Code Assist.
min_version: 'beta'
base_url: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups
self_link: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups/{{repository_group_id}}
create_url: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups?repositoryGroupId={{repository_group_id}}
id_format: projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups/{{repository_group_id}}
import_format:
- projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups/{{repository_group_id}}
examples:
- name: "gemini_repository_group_basic"
min_version: 'beta'
primary_resource_id: "example"
primary_resource_name: 'acctest.BootstrapSharedCodeRepositoryIndex(t, "basic-rg-example%{random_suffix}", "us-central1", "", ""), "test-rg-repository-group-id"'
vars:
repository_group_id: "example-repository-group-id"
git_repository_link_id: 'example-git-repository-link-id'
cri_id: "cri-example"
repository_resource: "projects/example-project/locations/us-central1/connections/example-connection/gitRepositoryLinks/example-repo"
connection_id: "example-connection-id"
test_vars_overrides:
repository_group_id: '"example_repository_group_idx"'
git_repository_link_id: 'acctest.BootstrapGitRepository(t, "basic", "us-central1", "https://github.com/CC-R-github-robot/tf-test.git", acctest.BootstrapDeveloperConnection(t, "basic", "us-central1", "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1", 54180648))'
cri_id: 'acctest.BootstrapSharedCodeRepositoryIndex(t, "test-rg", "us-central1", "", "")'
repository_resource: '"projects/"+envvar.GetTestProjectFromEnv()+"/locations/us-central1/connections/"+acctest.BootstrapDeveloperConnection(t, "basic", "us-central1", "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1", 54180648)+"/gitRepositoryLinks/"+acctest.BootstrapGitRepository(t, "basic", "us-central1", "https://github.com/CC-R-github-robot/tf-test.git", acctest.BootstrapDeveloperConnection(t, "basic", "us-central1", "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1", 54180648))'
connection_id: 'acctest.BootstrapDeveloperConnection(t, "basic", "us-central1", "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1", 54180648)'
exclude_test: true
autogen_async: true
async:
operation:
timeouts:
insert_minutes: 30
update_minutes: 30
delete_minutes: 30
path: name
base_url: "{{op_id}}"
wait_ms: 1000
actions:
- create
- delete
- update
type: OpAsync
result:
resource_inside_response: true
path: response
error:
path: error
message: message
include_project: false
iam_policy:
min_version: 'beta'
parent_resource_attribute: 'repository_group_id'
method_name_separator: ':'
fetch_iam_policy_verb: 'GET'
set_iam_policy_verb: 'POST'
import_format:
- 'projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{coderepositoryindex}}/repositoryGroups/{{repository_group_id}}'
- '{{repository_group_id}}'
allowed_iam_role: 'roles/cloudaicompanion.repositoryGroupsUser'
custom_code:
custom_create: templates/terraform/custom_create/repository_group.go.tmpl
custom_update: templates/terraform/custom_update/repository_group.go.tmpl
parameters:
- name: location
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
min_version: 'beta'
immutable: true
url_param_only: true
required: true
- name: coderepositoryindex
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
min_version: 'beta'
immutable: true
url_param_only: true
required: true
- name: repositoryGroupId
type: String
description: Required. Id of the requesting object
min_version: 'beta'
immutable: true
url_param_only: true
required: true
properties:
- name: repositories
type: Array
description: Required. List of repositories to group
min_version: 'beta'
required: true
item_type:
type: NestedObject
properties:
- name: resource
type: String
description: |-
Required. The DeveloperConnect repository full resource name, relative resource name
or resource URL to be indexed.
min_version: 'beta'
required: true
- name: branchPattern
type: String
description: |-
Required. The Git branch pattern used for indexing in RE2 syntax.
See https://github.com/google/re2/wiki/syntax for syntax.
min_version: 'beta'
required: true
- name: name
type: String
description: Immutable. Identifier. name of resource
min_version: 'beta'
output: true
immutable: true
- name: createTime
type: String
description: Output only. Create time stamp
min_version: 'beta'
output: true
- name: updateTime
type: String
description: Output only. Update time stamp
min_version: 'beta'
output: true
- name: labels
type: KeyValueLabels
description: Optional. Labels as key value pairs
min_version: 'beta'
21 changes: 21 additions & 0 deletions mmv1/products/cloudaicompanion/product.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2024 Google Inc.
# 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.

---
name: Gemini
display_name: Gemini for Google Cloud
scopes:
- https://www.googleapis.com/auth/cloud-platform
versions:
- base_url: https://cloudaicompanion.googleapis.com/v1/
name: 'beta'
121 changes: 121 additions & 0 deletions mmv1/templates/terraform/custom_create/code_repository_index.go.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

obj := make(map[string]interface{})
kmsKeyProp, err := expandGeminiCodeRepositoryIndexKmsKey(d.Get("kms_key"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("kms_key"); !tpgresource.IsEmptyValue(reflect.ValueOf(kmsKeyProp)) && (ok || !reflect.DeepEqual(v, kmsKeyProp)) {
obj["kmsKey"] = kmsKeyProp
}
labelsProp, err := expandGeminiCodeRepositoryIndexEffectiveLabels(d.Get("effective_labels"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("effective_labels"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
obj["labels"] = labelsProp
}

url, err := tpgresource.ReplaceVars(d, config, "{{"{{"}}GeminiBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/codeRepositoryIndexes?codeRepositoryIndexId={{"{{"}}code_repository_index_id{{"}}"}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new CodeRepositoryIndex: %#v", obj)
billingProject := ""

project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for CodeRepositoryIndex: %s", err)
}
billingProject = project

// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}

var res map[string]interface{}
headers := make(http.Header)
for {
res, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "POST",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutCreate),
Headers: headers,
})
if err != nil {
if transport_tpg.IsGoogleApiErrorWithCode(err, 409) {
log.Printf("[DEBUG] Waiting for enqueued operation to finish before creating CodeRepositoryIndex: %#v", obj)
time.Sleep(3 * time.Minute)
} else {
return fmt.Errorf("Error creating CodeRepositoryIndex: %s", err)
}
} else {
break
}
}

// Store the ID now
id, err := tpgresource.ReplaceVars(d, config, "projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/codeRepositoryIndexes/{{"{{"}}code_repository_index_id{{"}}"}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

// Use the resource in the operation response to populate
// identity fields and d.Id() before read
var opRes map[string]interface{}
err = GeminiOperationWaitTimeWithResponse(
config, res, &opRes, project, "Creating CodeRepositoryIndex", userAgent,
d.Timeout(schema.TimeoutCreate))
if err != nil {
// The resource didn't actually create
d.SetId("")

return fmt.Errorf("Error waiting to create CodeRepositoryIndex: %s", err)
}

if err := d.Set("name", flattenGeminiCodeRepositoryIndexName(opRes["name"], d, config)); err != nil {
return err
}

// This may have caused the ID to update - update it if so.
id, err = tpgresource.ReplaceVars(d, config, "projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/codeRepositoryIndexes/{{"{{"}}code_repository_index_id{{"}}"}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

url, err = tpgresource.ReplaceVars(d, config, "{{"{{"}}GeminiBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/codeRepositoryIndexes/{{"{{"}}code_repository_index_id{{"}}"}}")
if err != nil {
return fmt.Errorf("Error constructing url: %s", err)
}
for {
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Headers: headers,
})
if err != nil {
fmt.Errorf("Error getting new CodeRepositoryIndex %q: %s", d.Id(), err)
}
if res["state"] == "CREATING" {
time.Sleep(1 * time.Minute)
} else {
log.Printf("[DEBUG] Waiting for CodeRepositoryIndex to change state from \"CREATING\" finished")
break
}
}

log.Printf("[DEBUG] Finished creating CodeRepositoryIndex %q: %#v", d.Id(), res)

return resourceGeminiCodeRepositoryIndexRead(d, meta)
Loading
Loading