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

Generate APIKeys Key from Terraform #1168

12 changes: 4 additions & 8 deletions README.NewResourceFromTerraform.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
## Before You Start

This README entails instructions to implement a new resource CRD through
[Terraform Provider Google](https://github.com/hashicorp/terraform-provider-google).

# Add a New Resource

The instructions will help you add a new resource to Config Connector. A
resource is a K8s representation of a GCP resource.
The instructions will help you add a new resource to Config Connector through
[Terraform Provider Google](https://github.com/hashicorp/terraform-provider-google).
A Config Connector resource is the kubernetes representation of a GCP resource.

# Overview

Expand Down Expand Up @@ -257,7 +253,7 @@ ServiceMappings file. Add the `ResourceConfig` for your resource:
key: projectRef // one of 'projectRef', 'folderRef', 'organizationRef' and 'billingAccountRef'
resourceReferences:
- tfField: project
key: projectRef. // must match the key defined in hierarchicalReferences list
key: projectRef // must match the key defined in hierarchicalReferences list
description: |-
The project that this resource belongs to.
gvk:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cnrm.cloud.google.com/version: 0.0.0-dev
creationTimestamp: null
labels:
cnrm.cloud.google.com/managed-by-kcc: "true"
cnrm.cloud.google.com/stability-level: stable
cnrm.cloud.google.com/system: "true"
cnrm.cloud.google.com/tf2crd: "true"
name: apikeyskeys.apikeys.cnrm.cloud.google.com
spec:
group: apikeys.cnrm.cloud.google.com
names:
categories:
- gcp
kind: APIKeysKey
plural: apikeyskeys
shortNames:
- gcpapikeyskey
- gcpapikeyskeys
singular: apikeyskey
preserveUnknownFields: false
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- description: When 'True', the most recent reconcile of the resource succeeded
jsonPath: .status.conditions[?(@.type=='Ready')].status
name: Ready
type: string
- description: The reason for the value in 'Ready'
jsonPath: .status.conditions[?(@.type=='Ready')].reason
name: Status
type: string
- description: The last transition time for the value in 'Status'
jsonPath: .status.conditions[?(@.type=='Ready')].lastTransitionTime
name: Status Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
properties:
apiVersion:
description: 'apiVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
displayName:
description: Human-readable display name of this API key. Modifiable
by user.
type: string
projectRef:
description: The project that this resource belongs to.
oneOf:
- not:
required:
- external
required:
- name
- not:
anyOf:
- required:
- name
- required:
- namespace
required:
- external
properties:
external:
description: 'Allowed value: The `name` field of a `Project` resource.'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
type: object
resourceID:
description: Immutable. Optional. The name of the resource. Used for
creation and acquisition. When unset, the value of `metadata.name`
is used as the default.
type: string
restrictions:
description: Key restrictions.
properties:
androidKeyRestrictions:
description: The Android apps that are allowed to use the key.
properties:
allowedApplications:
description: A list of Android applications that are allowed
to make API calls with this key.
items:
properties:
packageName:
description: The package name of the application.
type: string
sha1Fingerprint:
description: 'The SHA1 fingerprint of the application.
For example, both sha1 formats are acceptable : DA:39:A3:EE:5E:6B:4B:0D:32:55:BF:EF:95:60:18:90:AF:D8:07:09
or DA39A3EE5E6B4B0D3255BFEF95601890AFD80709. Output
format is the latter.'
type: string
required:
- packageName
- sha1Fingerprint
type: object
type: array
required:
- allowedApplications
type: object
apiTargets:
description: A restriction for a specific service and optionally
one or more specific methods. Requests are allowed if they match
any of these restrictions. If no restrictions are specified,
all targets are allowed.
items:
properties:
methods:
description: 'Optional. List of one or more methods that
can be called. If empty, all methods for the service are
allowed. A wildcard (*) can be used as the last symbol.
Valid examples: `google.cloud.translate.v2.TranslateService.GetSupportedLanguage`
`TranslateText` `Get*` `translate.googleapis.com.Get*`.'
items:
type: string
type: array
service:
description: 'The service for this restriction. It should
be the canonical service name, for example: `translate.googleapis.com`.
You can use `gcloud services list` to get a list of services
that are enabled in the project.'
type: string
required:
- service
type: object
type: array
browserKeyRestrictions:
description: The HTTP referrers (websites) that are allowed to
use the key.
properties:
allowedReferrers:
description: A list of regular expressions for the referrer
URLs that are allowed to make API calls with this key.
items:
type: string
type: array
required:
- allowedReferrers
type: object
iosKeyRestrictions:
description: The iOS apps that are allowed to use the key.
properties:
allowedBundleIds:
description: A list of bundle IDs that are allowed when making
API calls with this key.
items:
type: string
type: array
required:
- allowedBundleIds
type: object
serverKeyRestrictions:
description: The IP addresses of callers that are allowed to use
the key.
properties:
allowedIps:
description: A list of the caller IP addresses that are allowed
to make API calls with this key.
items:
type: string
type: array
required:
- allowedIps
type: object
type: object
required:
- projectRef
type: object
status:
properties:
conditions:
description: Conditions represent the latest available observation
of the resource's current state.
items:
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status
to another.
type: string
message:
description: Human-readable message indicating details about
last transition.
type: string
reason:
description: Unique, one-word, CamelCase reason for the condition's
last transition.
type: string
status:
description: Status is the status of the condition. Can be True,
False, Unknown.
type: string
type:
description: Type is the type of the condition.
type: string
type: object
type: array
keyString:
description: Output only. An encrypted and signed value held by this
key. This field can be accessed only through the `GetKeyString`
method.
type: string
observedGeneration:
description: ObservedGeneration is the generation of the resource
that was most recently observed by the Config Connector controller.
If this is equal to metadata.generation, then that means that the
current reported status reflects the most recent desired state of
the resource.
type: integer
uid:
description: Output only. Unique id in UUID4 format.
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
12 changes: 12 additions & 0 deletions config/installbundle/components/clusterroles/cnrm_admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ rules:
- update
- patch
- delete
- apiGroups:
- apikeys.cnrm.cloud.google.com
resources:
- '*'
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- appengine.cnrm.cloud.google.com
resources:
Expand Down
8 changes: 8 additions & 0 deletions config/installbundle/components/clusterroles/cnrm_viewer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ rules:
- get
- list
- watch
- apiGroups:
- apikeys.cnrm.cloud.google.com
resources:
- '*'
verbs:
- get
- list
- watch
- apiGroups:
- appengine.cnrm.cloud.google.com
resources:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2024 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.

apiVersion: apikeys.cnrm.cloud.google.com/v1alpha1
kind: APIKeysKey
metadata:
name: apikeyskey-sample
spec:
displayName: "Human readable name"
projectRef:
# Replace ${PROJECT_ID?} with your project ID
external: "projects/${PROJECT_ID?}"
resourceID: sample
restrictions:
apiTargets:
- service: "translate.googleapis.com"
methods: [ "GET" ]
45 changes: 45 additions & 0 deletions config/servicemappings/apikeys.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2024 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.

apiVersion: core.cnrm.cloud.google.com/v1alpha1
kind: ServiceMapping
metadata:
name: apikeys.cnrm.cloud.google.com
namespace: cnrm-system
spec:
name: APIKeys
version: v1alpha1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a service level version set to v1alpha1 so there might be some rare feature gaps somewhere.

Meanwhile, we support all the other resources via autogen. So APIKeysKey configured here, I think there'll be two routes to promote a resource from alpha to beta. Feels like our code will get even more complicated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we're going to switch this one to direct actuation pretty fast, it looks like! There are some significant gaps in the terraform implementation.

serviceHostName: "apikeys.googleapis.com"
resources:
- name: google_apikeys_key
kind: APIKeysKey
metadataMapping:
name: name
resourceID:
targetField: name
resourceAvailableInAssetInventory: true
idTemplate: "projects/{{project}}/locations/global/keys/{{name}}"
idTemplateCanBeUsedToMatchResourceName: true
hierarchicalReferences:
- type: project
key: projectRef
resourceReferences:
- tfField: project
key: projectRef
description: |-
The project that this resource belongs to.
gvk:
kind: Project
version: v1beta1
group: resourcemanager.cnrm.cloud.google.com
2 changes: 2 additions & 0 deletions config/tests/samples/create/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ func MaybeSkip(t *testing.T, name string, resources []*unstructured.Unstructured
}

switch gvk.GroupKind() {
case schema.GroupKind{Group: "apikeys.cnrm.cloud.google.com", Kind: "APIKeysKey"}:

case schema.GroupKind{Group: "cloudfunctions.cnrm.cloud.google.com", Kind: "CloudFunctionsFunction"}:

case schema.GroupKind{Group: "containerattached.cnrm.cloud.google.com", Kind: "ContainerAttachedCluster"}:
Expand Down
Loading
Loading