diff --git a/apis/iap/v1alpha1/doc.go b/apis/iap/v1alpha1/doc.go new file mode 100644 index 0000000000..f764970f3c --- /dev/null +++ b/apis/iap/v1alpha1/doc.go @@ -0,0 +1,16 @@ +// 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. + +// +kcc:proto=google.cloud.iap.v1 +package v1alpha1 diff --git a/apis/iap/v1alpha1/groupversion_info.go b/apis/iap/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..f77a0f5259 --- /dev/null +++ b/apis/iap/v1alpha1/groupversion_info.go @@ -0,0 +1,33 @@ +// 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. + +// +kubebuilder:object:generate=true +// +groupName=iap.cnrm.cloud.google.com +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "iap.cnrm.cloud.google.com", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/iap/v1alpha1/iapsettings_identity.go b/apis/iap/v1alpha1/iapsettings_identity.go new file mode 100644 index 0000000000..abc3c53f47 --- /dev/null +++ b/apis/iap/v1alpha1/iapsettings_identity.go @@ -0,0 +1,144 @@ +// 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. + +package v1alpha1 + +import ( + "context" + "fmt" + "strings" + + "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// IAPSettingsIdentity defines the resource reference to IAPSettings. +// The id could have the following format: +// +// organizations/{organization_id} +// folders/{folder_id} +// projects/{projects_id} +// projects/{projects_id}/iap_web +// projects/{projects_id}/iap_web/compute +// projects/{projects_id}/iap_web/compute-{region} +// projects/{projects_id}/iap_web/compute/service/{service_id} +// projects/{projects_id}/iap_web/compute-{region}/service/{service_id} +// projects/{projects_id}/iap_web/appengine-{app_id} +// projects/{projects_id}/iap_web/appengine-{app_id}/service/{service_id} +// projects/{projects_id}/iap_web/appengine-{app_id}/service/{service_id}/version/{version_id} +type IAPSettingsIdentity struct { + id string +} + +func (i *IAPSettingsIdentity) String() string { + return i.id +} + +func (i *IAPSettingsIdentity) ID() string { + return i.id +} + +// New builds a IAPSettingsIdentity from the Config Connector IAPSettings object. +func NewIAPSettingsIdentity(ctx context.Context, reader client.Reader, obj *IAPSettings) (*IAPSettingsIdentity, error) { + // Get desired ID + // Note that we cannot use `metadata.name` as resourceID since the supported resource ID formats are not valid Kubernetes names. + resourceID := common.ValueOf(obj.Spec.ResourceID) + if resourceID == "" { + resourceID = common.ValueOf(obj.Spec.Name) + } + if resourceID == "" { + return nil, fmt.Errorf("cannot resolve resource ID") + } + if err := ValidateIAPSettingsID(resourceID); err != nil { + return nil, err + } + + // Use approved External + externalRef := common.ValueOf(obj.Status.ExternalRef) + if externalRef != "" { + // Validate desired with actual + actualResourceID := externalRef + if err := ValidateIAPSettingsID(actualResourceID); err != nil { + return nil, err + } + if actualResourceID != resourceID { + return nil, fmt.Errorf("cannot reset `spec.name` or `spec.resourceID` to %s, since it has already assigned to %s", + resourceID, actualResourceID) + } + } + return &IAPSettingsIdentity{ + id: resourceID, + }, nil +} + +// ValidateIAPSettingsID validates the IAPSettings resource ID. +func ValidateIAPSettingsID(id string) error { + if id == "" { + return fmt.Errorf("id cannot be empty") + } + + parts := strings.Split(id, "/") + if len(parts) < 2 { + return fmt.Errorf("invalid IAP settings ID format %q: must have at least 2 segments (e.g., 'projects/my-project')", id) + } + + // Validate root resource type + switch parts[0] { + case "organizations", "folders", "projects": + // Valid root types + default: + return fmt.Errorf("invalid root resource type %q: must be one of: organizations, folders, projects", parts[0]) + } + + // For organization and folder paths, only expect 2 parts + if parts[0] == "organizations" || parts[0] == "folders" { + if len(parts) != 2 { + return fmt.Errorf("invalid %s IAP settings path %q: must have exactly 2 segments (e.g., '%s/my-id')", parts[0], id, parts[0]) + } + return nil + } + + // For project paths, validate the structure + if len(parts) > 2 { + if parts[2] != "iap_web" { + return fmt.Errorf("invalid project IAP settings path %q: third segment must be 'iap_web', got %q", id, parts[2]) + } + } + + switch len(parts) { + case 2: // projects/{project_id} + return nil + case 3: // projects/{project_id}/iap_web + return nil + case 4: // projects/{project_id}/iap_web/compute or compute-{region} + if !strings.HasPrefix(parts[3], "compute") && !strings.HasPrefix(parts[3], "appengine-") { + return fmt.Errorf("invalid IAP web resource type %q: must start with 'compute' or 'appengine-'", parts[3]) + } + case 6: // projects/{project_id}/iap_web/(compute|compute-{region}|appengine-{app_id})/service/{service_id} + if parts[4] != "service" { + return fmt.Errorf("invalid service path %q: fifth segment must be 'service', got %q", id, parts[4]) + } + case 8: // projects/{project_id}/iap_web/appengine-{app_id}/service/{service_id}/version/{version_id} + if !strings.HasPrefix(parts[3], "appengine-") { + return fmt.Errorf("invalid path %q: version paths are only valid for App Engine resources (must start with 'appengine-')", id) + } + if parts[4] != "service" || parts[6] != "version" { + return fmt.Errorf("invalid App Engine version path %q: must follow pattern 'appengine-{app_id}/service/{service_id}/version/{version_id}'", id) + } + default: + return fmt.Errorf("invalid number of path segments in IAP settings ID %q: got %d segments, expected 2, 3, 4, 6, or 8", id, len(parts)) + } + + return nil +} diff --git a/apis/iap/v1alpha1/iapsettings_reference.go b/apis/iap/v1alpha1/iapsettings_reference.go new file mode 100644 index 0000000000..19b597eec0 --- /dev/null +++ b/apis/iap/v1alpha1/iapsettings_reference.go @@ -0,0 +1,85 @@ +// 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. + +package v1alpha1 + +import ( + "context" + "fmt" + + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ refsv1beta1.ExternalNormalizer = &IAPSettingsRef{} + +// IAPSettingsRef defines the resource reference to IAPSettings, which "External" field +// holds the GCP identifier for the KRM object. +type IAPSettingsRef struct { + // A reference to an externally managed IAPSettings resource. + External string `json:"external,omitempty"` + + // The name of a IAPSettings resource. + Name string `json:"name,omitempty"` + + // The namespace of a IAPSettings resource. + Namespace string `json:"namespace,omitempty"` +} + +// NormalizedExternal provision the "External" value for other resource that depends on IAPSettings. +// If the "External" is given in the other resource's spec.IAPSettingsRef, the given value will be used. +// Otherwise, the "Name" and "Namespace" will be used to query the actual IAPSettings object from the cluster. +func (r *IAPSettingsRef) NormalizedExternal(ctx context.Context, reader client.Reader, otherNamespace string) (string, error) { + if r.External != "" && r.Name != "" { + return "", fmt.Errorf("cannot specify both name and external on %s reference", IAPSettingsGVK.Kind) + } + // From given External + if r.External != "" { + if err := ValidateIAPSettingsID(r.External); err != nil { + return "", fmt.Errorf("invalid format of IAPSettings external %s: %w", r.External, err) + } + return r.External, nil + } + + // From the Config Connector object + if r.Namespace == "" { + r.Namespace = otherNamespace + } + key := types.NamespacedName{Name: r.Name, Namespace: r.Namespace} + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(IAPSettingsGVK) + if err := reader.Get(ctx, key, u); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(u.GroupVersionKind(), key) + } + return "", fmt.Errorf("reading referenced %s %s: %w", IAPSettingsGVK, key, err) + } + // Get external from status.externalRef. This is the most trustworthy place. + actualExternalRef, _, err := unstructured.NestedString(u.Object, "status", "externalRef") + if err != nil { + return "", fmt.Errorf("reading status.externalRef: %w", err) + } + if actualExternalRef == "" { + return "", k8s.NewReferenceNotReadyError(u.GroupVersionKind(), key) + } + if err := ValidateIAPSettingsID(actualExternalRef); err != nil { + return "", fmt.Errorf("invalid format of IAPSettings status.externalRef %s: %w", actualExternalRef, err) + } + r.External = actualExternalRef + return r.External, nil +} diff --git a/apis/iap/v1alpha1/iapsettings_types.go b/apis/iap/v1alpha1/iapsettings_types.go new file mode 100644 index 0000000000..5a4d3f6ba9 --- /dev/null +++ b/apis/iap/v1alpha1/iapsettings_types.go @@ -0,0 +1,112 @@ +// 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. + +package v1alpha1 + +import ( + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var IAPSettingsGVK = GroupVersion.WithKind("IAPSettings") + +// IAPSettingsSpec defines the desired state of IAPSettings +// +kcc:proto=google.cloud.iap.v1.IapSettings +type IAPSettingsSpec struct { + // The IAPSettings name. + ResourceID *string `json:"resourceID,omitempty"` + + // Required. The resource name of the IAP protected resource. + // The name could have the following format: + // organizations/{organization_id} + // folders/{folder_id} + // projects/{projects_id} + // projects/{projects_id}/iap_web + // projects/{projects_id}/iap_web/compute + // projects/{projects_id}/iap_web/compute-{region} + // projects/{projects_id}/iap_web/compute/service/{service_id} + // projects/{projects_id}/iap_web/compute-{region}/service/{service_id} + // projects/{projects_id}/iap_web/appengine-{app_id} + // projects/{projects_id}/iap_web/appengine-{app_id}/service/{service_id} + // projects/{projects_id}/iap_web/appengine-{app_id}/service/{service_id}/version/{version_id} + // +kcc:proto:field=google.cloud.iap.v1.IapSettings.name + // +required + Name *string `json:"name,omitempty"` + + // Top level wrapper for all access related setting in IAP + // +kcc:proto:field=google.cloud.iap.v1.IapSettings.access_settings + AccessSettings *AccessSettings `json:"accessSettings,omitempty"` + + // Top level wrapper for all application related settings in IAP + // +kcc:proto:field=google.cloud.iap.v1.IapSettings.application_settings + ApplicationSettings *ApplicationSettings `json:"applicationSettings,omitempty"` +} + +// IAPSettingsStatus defines the config connector machine state of IAPSettings +type IAPSettingsStatus struct { + /* Conditions represent the latest available observations of the + object's current state. */ + Conditions []v1alpha1.Condition `json:"conditions,omitempty"` + + // 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. + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // A unique specifier for the IAPSettings resource in GCP. + ExternalRef *string `json:"externalRef,omitempty"` + + // ObservedState is the state of the resource as most recently observed in GCP. + // NOTYET: there is no output only field + // ObservedState *IAPSettingsObservedState `json:"observedState,omitempty"` +} + +// IAPSettingsSpec defines the desired state of IAPSettings +// +kcc:proto=google.cloud.iap.v1.IapSettings +// IAPSettingsObservedState is the state of the IAPSettings resource as most recently observed in GCP. +// NOTYET: there is no output only field +// type IAPSettingsObservedState struct { +// } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// TODO(user): make sure the pluralizaiton below is correct +// +kubebuilder:resource:categories=gcp,shortName=gcpiapsettings;gcpiapsettingss +// +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/system=true" +// +kubebuilder:printcolumn:name="Age",JSONPath=".metadata.creationTimestamp",type="date" +// +kubebuilder:printcolumn:name="Ready",JSONPath=".status.conditions[?(@.type=='Ready')].status",type="string",description="When 'True', the most recent reconcile of the resource succeeded" +// +kubebuilder:printcolumn:name="Status",JSONPath=".status.conditions[?(@.type=='Ready')].reason",type="string",description="The reason for the value in 'Ready'" +// +kubebuilder:printcolumn:name="Status Age",JSONPath=".status.conditions[?(@.type=='Ready')].lastTransitionTime",type="date",description="The last transition time for the value in 'Status'" + +// IAPSettings is the Schema for the IAPSettings API +// +k8s:openapi-gen=true +type IAPSettings struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +required + Spec IAPSettingsSpec `json:"spec,omitempty"` + Status IAPSettingsStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// IAPSettingsList contains a list of IAPSettings +type IAPSettingsList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []IAPSettings `json:"items"` +} + +func init() { + SchemeBuilder.Register(&IAPSettings{}, &IAPSettingsList{}) +} diff --git a/apis/iap/v1alpha1/types.generated.go b/apis/iap/v1alpha1/types.generated.go new file mode 100644 index 0000000000..9e660f068b --- /dev/null +++ b/apis/iap/v1alpha1/types.generated.go @@ -0,0 +1,198 @@ +// Copyright 2025 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. + +package v1alpha1 + +// +kcc:proto=google.cloud.iap.v1.AccessDeniedPageSettings +type AccessDeniedPageSettings struct { + // The URI to be redirected to when access is denied. + // +kcc:proto:field=google.cloud.iap.v1.AccessDeniedPageSettings.access_denied_page_uri + AccessDeniedPageURI *string `json:"accessDeniedPageURI,omitempty"` + + // Whether to generate a troubleshooting URL on access denied events to this + // application. + // +kcc:proto:field=google.cloud.iap.v1.AccessDeniedPageSettings.generate_troubleshooting_uri + GenerateTroubleshootingURI *bool `json:"generateTroubleshootingURI,omitempty"` + + // Whether to generate remediation token on access denied events to this + // application. + // +kcc:proto:field=google.cloud.iap.v1.AccessDeniedPageSettings.remediation_token_generation_enabled + RemediationTokenGenerationEnabled *bool `json:"remediationTokenGenerationEnabled,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.AccessSettings +type AccessSettings struct { + // GCIP claims and endpoint configurations for 3p identity providers. + // +kcc:proto:field=google.cloud.iap.v1.AccessSettings.gcip_settings + GcipSettings *GcipSettings `json:"gcipSettings,omitempty"` + + // Configuration to allow cross-origin requests via IAP. + // +kcc:proto:field=google.cloud.iap.v1.AccessSettings.cors_settings + CorsSettings *CorsSettings `json:"corsSettings,omitempty"` + + // Settings to configure IAP's OAuth behavior. + // +kcc:proto:field=google.cloud.iap.v1.AccessSettings.oauth_settings + OauthSettings *OAuthSettings `json:"oauthSettings,omitempty"` + + // Settings to configure reauthentication policies in IAP. + // +kcc:proto:field=google.cloud.iap.v1.AccessSettings.reauth_settings + ReauthSettings *ReauthSettings `json:"reauthSettings,omitempty"` + + // Settings to configure and enable allowed domains. + // +kcc:proto:field=google.cloud.iap.v1.AccessSettings.allowed_domains_settings + AllowedDomainsSettings *AllowedDomainsSettings `json:"allowedDomainsSettings,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.AllowedDomainsSettings +type AllowedDomainsSettings struct { + // Configuration for customers to opt in for the feature. + // +kcc:proto:field=google.cloud.iap.v1.AllowedDomainsSettings.enable + Enable *bool `json:"enable,omitempty"` + + // List of trusted domains. + // +kcc:proto:field=google.cloud.iap.v1.AllowedDomainsSettings.domains + Domains []string `json:"domains,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.ApplicationSettings +type ApplicationSettings struct { + // Settings to configure IAP's behavior for a service mesh. + // +kcc:proto:field=google.cloud.iap.v1.ApplicationSettings.csm_settings + CsmSettings *CsmSettings `json:"csmSettings,omitempty"` + + // Customization for Access Denied page. + // +kcc:proto:field=google.cloud.iap.v1.ApplicationSettings.access_denied_page_settings + AccessDeniedPageSettings *AccessDeniedPageSettings `json:"accessDeniedPageSettings,omitempty"` + + // The Domain value to set for cookies generated by IAP. This value is not + // validated by the API, but will be ignored at runtime if invalid. + // +kcc:proto:field=google.cloud.iap.v1.ApplicationSettings.cookie_domain + CookieDomain *string `json:"cookieDomain,omitempty"` + + // Settings to configure attribute propagation. + // +kcc:proto:field=google.cloud.iap.v1.ApplicationSettings.attribute_propagation_settings + AttributePropagationSettings *AttributePropagationSettings `json:"attributePropagationSettings,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.AttributePropagationSettings +type AttributePropagationSettings struct { + // Raw string CEL expression. Must return a list of attributes. A maximum of + // 45 attributes can be selected. Expressions can select different attribute + // types from `attributes`: `attributes.saml_attributes`, + // `attributes.iap_attributes`. The following functions are supported: + // + // - filter `.filter(, )`: Returns a subset of + // `` where `` is true for every item. + // + // - in ` in `: Returns true if `` contains ``. + // + // - selectByName `.selectByName()`: Returns the attribute + // in + // `` with the given `` name, otherwise returns empty. + // + // - emitAs `.emitAs()`: Sets the `` name + // field to the given `` for propagation in selected output + // credentials. + // + // - strict `.strict()`: Ignores the `x-goog-iap-attr-` prefix + // for the provided `` when propagating with the `HEADER` output + // credential, such as request headers. + // + // - append `.append()` OR + // `.append()`: Appends the provided `` or + // `` to the end of ``. + // + // Example expression: `attributes.saml_attributes.filter(x, x.name in + // ['test']).append(attributes.iap_attributes.selectByName('exact').emitAs('custom').strict())` + // +kcc:proto:field=google.cloud.iap.v1.AttributePropagationSettings.expression + Expression *string `json:"expression,omitempty"` + + // Which output credentials attributes selected by the CEL expression should + // be propagated in. All attributes will be fully duplicated in each selected + // output credential. + // +kcc:proto:field=google.cloud.iap.v1.AttributePropagationSettings.output_credentials + OutputCredentials []string `json:"outputCredentials,omitempty"` + + // Whether the provided attribute propagation settings should be evaluated on + // user requests. If set to true, attributes returned from the expression will + // be propagated in the set output credentials. + // +kcc:proto:field=google.cloud.iap.v1.AttributePropagationSettings.enable + Enable *bool `json:"enable,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.CorsSettings +type CorsSettings struct { + // Configuration to allow HTTP OPTIONS calls to skip authorization. If + // undefined, IAP will not apply any special logic to OPTIONS requests. + // +kcc:proto:field=google.cloud.iap.v1.CorsSettings.allow_http_options + AllowHTTPOptions *bool `json:"allowHTTPOptions,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.CsmSettings +type CsmSettings struct { + // Audience claim set in the generated RCToken. This value is not validated by + // IAP. + // +kcc:proto:field=google.cloud.iap.v1.CsmSettings.rctoken_aud + RctokenAud *string `json:"rctokenAud,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.GcipSettings +type GcipSettings struct { + // GCIP tenant ids that are linked to the IAP resource. + // tenant_ids could be a string beginning with a number character to indicate + // authenticating with GCIP tenant flow, or in the format of _ + // to indicate authenticating with GCIP agent flow. + // If agent flow is used, tenant_ids should only contain one single element, + // while for tenant flow, tenant_ids can contain multiple elements. + // +kcc:proto:field=google.cloud.iap.v1.GcipSettings.tenant_ids + TenantIds []string `json:"tenantIds,omitempty"` + + // Login page URI associated with the GCIP tenants. + // Typically, all resources within the same project share the same login page, + // though it could be overridden at the sub resource level. + // +kcc:proto:field=google.cloud.iap.v1.GcipSettings.login_page_uri + LoginPageURI *string `json:"loginPageURI,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.OAuthSettings +type OAuthSettings struct { + // Domain hint to send as hd=? parameter in OAuth request flow. Enables + // redirect to primary IDP by skipping Google's login screen. + // https://developers.google.com/identity/protocols/OpenIDConnect#hd-param + // Note: IAP does not verify that the id token's hd claim matches this value + // since access behavior is managed by IAM policies. + // +kcc:proto:field=google.cloud.iap.v1.OAuthSettings.login_hint + LoginHint *string `json:"loginHint,omitempty"` + + // List of OAuth client IDs allowed to programmatically authenticate with IAP. + // +kcc:proto:field=google.cloud.iap.v1.OAuthSettings.programmatic_clients + ProgrammaticClients []string `json:"programmaticClients,omitempty"` +} + +// +kcc:proto=google.cloud.iap.v1.ReauthSettings +type ReauthSettings struct { + // Reauth method requested. + // +kcc:proto:field=google.cloud.iap.v1.ReauthSettings.method + Method *string `json:"method,omitempty"` + + // Reauth session lifetime, how long before a user has to reauthenticate + // again. + // +kcc:proto:field=google.cloud.iap.v1.ReauthSettings.max_age + MaxAge *string `json:"maxAge,omitempty"` + + // How IAP determines the effective policy in cases of hierarchial policies. + // Policies are merged from higher in the hierarchy to lower in the hierarchy. + // +kcc:proto:field=google.cloud.iap.v1.ReauthSettings.policy_type + PolicyType *string `json:"policyType,omitempty"` +} diff --git a/apis/iap/v1alpha1/zz_generated.deepcopy.go b/apis/iap/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..a051c912d7 --- /dev/null +++ b/apis/iap/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,458 @@ +//go:build !ignore_autogenerated + +// Copyright 2020 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. + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + k8sv1alpha1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AccessDeniedPageSettings) DeepCopyInto(out *AccessDeniedPageSettings) { + *out = *in + if in.AccessDeniedPageURI != nil { + in, out := &in.AccessDeniedPageURI, &out.AccessDeniedPageURI + *out = new(string) + **out = **in + } + if in.GenerateTroubleshootingURI != nil { + in, out := &in.GenerateTroubleshootingURI, &out.GenerateTroubleshootingURI + *out = new(bool) + **out = **in + } + if in.RemediationTokenGenerationEnabled != nil { + in, out := &in.RemediationTokenGenerationEnabled, &out.RemediationTokenGenerationEnabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessDeniedPageSettings. +func (in *AccessDeniedPageSettings) DeepCopy() *AccessDeniedPageSettings { + if in == nil { + return nil + } + out := new(AccessDeniedPageSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AccessSettings) DeepCopyInto(out *AccessSettings) { + *out = *in + if in.GcipSettings != nil { + in, out := &in.GcipSettings, &out.GcipSettings + *out = new(GcipSettings) + (*in).DeepCopyInto(*out) + } + if in.CorsSettings != nil { + in, out := &in.CorsSettings, &out.CorsSettings + *out = new(CorsSettings) + (*in).DeepCopyInto(*out) + } + if in.OauthSettings != nil { + in, out := &in.OauthSettings, &out.OauthSettings + *out = new(OAuthSettings) + (*in).DeepCopyInto(*out) + } + if in.ReauthSettings != nil { + in, out := &in.ReauthSettings, &out.ReauthSettings + *out = new(ReauthSettings) + (*in).DeepCopyInto(*out) + } + if in.AllowedDomainsSettings != nil { + in, out := &in.AllowedDomainsSettings, &out.AllowedDomainsSettings + *out = new(AllowedDomainsSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessSettings. +func (in *AccessSettings) DeepCopy() *AccessSettings { + if in == nil { + return nil + } + out := new(AccessSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AllowedDomainsSettings) DeepCopyInto(out *AllowedDomainsSettings) { + *out = *in + if in.Enable != nil { + in, out := &in.Enable, &out.Enable + *out = new(bool) + **out = **in + } + if in.Domains != nil { + in, out := &in.Domains, &out.Domains + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedDomainsSettings. +func (in *AllowedDomainsSettings) DeepCopy() *AllowedDomainsSettings { + if in == nil { + return nil + } + out := new(AllowedDomainsSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplicationSettings) DeepCopyInto(out *ApplicationSettings) { + *out = *in + if in.CsmSettings != nil { + in, out := &in.CsmSettings, &out.CsmSettings + *out = new(CsmSettings) + (*in).DeepCopyInto(*out) + } + if in.AccessDeniedPageSettings != nil { + in, out := &in.AccessDeniedPageSettings, &out.AccessDeniedPageSettings + *out = new(AccessDeniedPageSettings) + (*in).DeepCopyInto(*out) + } + if in.CookieDomain != nil { + in, out := &in.CookieDomain, &out.CookieDomain + *out = new(string) + **out = **in + } + if in.AttributePropagationSettings != nil { + in, out := &in.AttributePropagationSettings, &out.AttributePropagationSettings + *out = new(AttributePropagationSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationSettings. +func (in *ApplicationSettings) DeepCopy() *ApplicationSettings { + if in == nil { + return nil + } + out := new(ApplicationSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AttributePropagationSettings) DeepCopyInto(out *AttributePropagationSettings) { + *out = *in + if in.Expression != nil { + in, out := &in.Expression, &out.Expression + *out = new(string) + **out = **in + } + if in.OutputCredentials != nil { + in, out := &in.OutputCredentials, &out.OutputCredentials + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Enable != nil { + in, out := &in.Enable, &out.Enable + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttributePropagationSettings. +func (in *AttributePropagationSettings) DeepCopy() *AttributePropagationSettings { + if in == nil { + return nil + } + out := new(AttributePropagationSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CorsSettings) DeepCopyInto(out *CorsSettings) { + *out = *in + if in.AllowHTTPOptions != nil { + in, out := &in.AllowHTTPOptions, &out.AllowHTTPOptions + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CorsSettings. +func (in *CorsSettings) DeepCopy() *CorsSettings { + if in == nil { + return nil + } + out := new(CorsSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CsmSettings) DeepCopyInto(out *CsmSettings) { + *out = *in + if in.RctokenAud != nil { + in, out := &in.RctokenAud, &out.RctokenAud + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CsmSettings. +func (in *CsmSettings) DeepCopy() *CsmSettings { + if in == nil { + return nil + } + out := new(CsmSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GcipSettings) DeepCopyInto(out *GcipSettings) { + *out = *in + if in.TenantIds != nil { + in, out := &in.TenantIds, &out.TenantIds + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.LoginPageURI != nil { + in, out := &in.LoginPageURI, &out.LoginPageURI + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GcipSettings. +func (in *GcipSettings) DeepCopy() *GcipSettings { + if in == nil { + return nil + } + out := new(GcipSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettings) DeepCopyInto(out *IAPSettings) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettings. +func (in *IAPSettings) DeepCopy() *IAPSettings { + if in == nil { + return nil + } + out := new(IAPSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IAPSettings) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettingsIdentity) DeepCopyInto(out *IAPSettingsIdentity) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettingsIdentity. +func (in *IAPSettingsIdentity) DeepCopy() *IAPSettingsIdentity { + if in == nil { + return nil + } + out := new(IAPSettingsIdentity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettingsList) DeepCopyInto(out *IAPSettingsList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IAPSettings, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettingsList. +func (in *IAPSettingsList) DeepCopy() *IAPSettingsList { + if in == nil { + return nil + } + out := new(IAPSettingsList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IAPSettingsList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettingsRef) DeepCopyInto(out *IAPSettingsRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettingsRef. +func (in *IAPSettingsRef) DeepCopy() *IAPSettingsRef { + if in == nil { + return nil + } + out := new(IAPSettingsRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettingsSpec) DeepCopyInto(out *IAPSettingsSpec) { + *out = *in + if in.ResourceID != nil { + in, out := &in.ResourceID, &out.ResourceID + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.AccessSettings != nil { + in, out := &in.AccessSettings, &out.AccessSettings + *out = new(AccessSettings) + (*in).DeepCopyInto(*out) + } + if in.ApplicationSettings != nil { + in, out := &in.ApplicationSettings, &out.ApplicationSettings + *out = new(ApplicationSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettingsSpec. +func (in *IAPSettingsSpec) DeepCopy() *IAPSettingsSpec { + if in == nil { + return nil + } + out := new(IAPSettingsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IAPSettingsStatus) DeepCopyInto(out *IAPSettingsStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]k8sv1alpha1.Condition, len(*in)) + copy(*out, *in) + } + if in.ObservedGeneration != nil { + in, out := &in.ObservedGeneration, &out.ObservedGeneration + *out = new(int64) + **out = **in + } + if in.ExternalRef != nil { + in, out := &in.ExternalRef, &out.ExternalRef + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAPSettingsStatus. +func (in *IAPSettingsStatus) DeepCopy() *IAPSettingsStatus { + if in == nil { + return nil + } + out := new(IAPSettingsStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OAuthSettings) DeepCopyInto(out *OAuthSettings) { + *out = *in + if in.LoginHint != nil { + in, out := &in.LoginHint, &out.LoginHint + *out = new(string) + **out = **in + } + if in.ProgrammaticClients != nil { + in, out := &in.ProgrammaticClients, &out.ProgrammaticClients + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthSettings. +func (in *OAuthSettings) DeepCopy() *OAuthSettings { + if in == nil { + return nil + } + out := new(OAuthSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReauthSettings) DeepCopyInto(out *ReauthSettings) { + *out = *in + if in.Method != nil { + in, out := &in.Method, &out.Method + *out = new(string) + **out = **in + } + if in.MaxAge != nil { + in, out := &in.MaxAge, &out.MaxAge + *out = new(string) + **out = **in + } + if in.PolicyType != nil { + in, out := &in.PolicyType, &out.PolicyType + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReauthSettings. +func (in *ReauthSettings) DeepCopy() *ReauthSettings { + if in == nil { + return nil + } + out := new(ReauthSettings) + in.DeepCopyInto(out) + return out +} diff --git a/dev/tasks/generate-crds b/dev/tasks/generate-crds index c3d83dcd6f..267bac4168 100755 --- a/dev/tasks/generate-crds +++ b/dev/tasks/generate-crds @@ -48,7 +48,7 @@ go run ./scripts/crd-tools reflow-descriptions --dir apis/config/crd/ # excluded_resources are resources that are under development for a direct conversion # we don't modify the CRD just yet for those but will in the future #excluded_resources=("securesourcemanagerinstance") -excluded_resources=() +excluded_resources=("iapsettings") cd ${REPO_ROOT} cd apis/config/crd/ diff --git a/dev/tools/controllerbuilder/generate.sh b/dev/tools/controllerbuilder/generate.sh index 566610c7dc..7413cdd435 100755 --- a/dev/tools/controllerbuilder/generate.sh +++ b/dev/tools/controllerbuilder/generate.sh @@ -178,5 +178,15 @@ go run . generate-mapper \ --service google.spanner.admin.instance.v1 \ --api-version "spanner.cnrm.cloud.google.com/v1beta1" +# IAMSettings +go run . generate-types \ + --service google.cloud.iap.v1 \ + --api-version iap.cnrm.cloud.google.com/v1alpha1 \ + --resource IAPSettings:IapSettings + +go run . generate-mapper \ + --service google.cloud.iap.v1 \ + --api-version iap.cnrm.cloud.google.com/v1alpha1 + # Fix up formatting ${REPO_ROOT}/dev/tasks/fix-gofmt diff --git a/dev/tools/controllerbuilder/pkg/codegen/mappergenerator.go b/dev/tools/controllerbuilder/pkg/codegen/mappergenerator.go index 5f3d7b1afc..94c6685862 100644 --- a/dev/tools/controllerbuilder/pkg/codegen/mappergenerator.go +++ b/dev/tools/controllerbuilder/pkg/codegen/mappergenerator.go @@ -728,6 +728,22 @@ func krmFromProtoFunctionName(protoField protoreflect.FieldDescriptor, krmFieldN return "direct.StringDuration_FromProto" case "google.protobuf.Int64Value": return "direct.Int64Value_FromProto" + case "google.protobuf.StringValue": + return "direct.StringValue_FromProto" + case "google.protobuf.BoolValue": + return "direct.BoolValue_FromProto" + case "google.protobuf.FloatValue": + return "direct.FloatValue_FromProto" + case "google.protobuf.DoubleValue": + return "direct.DoubleValue_FromProto" + case "google.protobuf.Int32Value": + return "direct.Int32Value_FromProto" + case "google.protobuf.UInt32Value": + return "direct.UInt32Value_FromProto" + case "google.protobuf.UInt64Value": + return "direct.UInt64Value_FromProto" + case "google.protobuf.BytesValue": + return "direct.BytesValue_FromProto" } klog.Fatalf("unhandled case in krmFromProtoFunctionName for proto field %s", fullname) return "" @@ -744,6 +760,22 @@ func krmToProtoFunctionName(protoField protoreflect.FieldDescriptor, krmFieldNam return "direct.StringDuration_ToProto" case "google.protobuf.Int64Value": return "direct.Int64Value_ToProto" + case "google.protobuf.StringValue": + return "direct.StringValue_ToProto" + case "google.protobuf.BoolValue": + return "direct.BoolValue_ToProto" + case "google.protobuf.FloatValue": + return "direct.FloatValue_ToProto" + case "google.protobuf.DoubleValue": + return "direct.DoubleValue_ToProto" + case "google.protobuf.Int32Value": + return "direct.Int32Value_ToProto" + case "google.protobuf.UInt32Value": + return "direct.UInt32Value_ToProto" + case "google.protobuf.UInt64Value": + return "direct.UInt64Value_ToProto" + case "google.protobuf.BytesValue": + return "direct.BytesValue_ToProto" } klog.Fatalf("unhandled case in krmToProtoFunctionName for proto field %s", fullname) return "" diff --git a/dev/tools/controllerbuilder/pkg/codegen/typegenerator.go b/dev/tools/controllerbuilder/pkg/codegen/typegenerator.go index 4af9552dc6..7cb6bbed8e 100644 --- a/dev/tools/controllerbuilder/pkg/codegen/typegenerator.go +++ b/dev/tools/controllerbuilder/pkg/codegen/typegenerator.go @@ -40,12 +40,13 @@ const ( KCCProtoFieldAnnotation = "+kcc:proto:field" ) -// Some special-case values that are not obvious how to map in KRM +// Some special-case mappings between proto message type and KRM field type. var protoMessagesNotMappedToGoStruct = map[string]string{ "google.protobuf.Timestamp": "string", "google.protobuf.Duration": "string", "google.protobuf.Int64Value": "int64", "google.protobuf.StringValue": "string", + "google.protobuf.BoolValue": "bool", "google.protobuf.Struct": "map[string]string", } @@ -458,7 +459,7 @@ func isAcronym(s string) bool { switch s { case "id": return true - case "html", "url": + case "html", "url", "uri": return true case "http", "https", "ssh": return true diff --git a/go.mod b/go.mod index 3683a82592..8d1450bbad 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( cloud.google.com/go/firestore v1.17.0 cloud.google.com/go/gkemulticloud v1.4.1 cloud.google.com/go/iam v1.2.2 + cloud.google.com/go/iap v1.10.2 cloud.google.com/go/kms v1.20.1 cloud.google.com/go/monitoring v1.21.2 cloud.google.com/go/privilegedaccessmanager v0.2.1 diff --git a/go.sum b/go.sum index 52f974cd51..787174c84a 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ cloud.google.com/go/gkemulticloud v1.4.1 h1:SvVD2nJTGScEDYygIQ5dI14oFYhgtJx8Hazk cloud.google.com/go/gkemulticloud v1.4.1/go.mod h1:KRvPYcx53bztNwNInrezdfNF+wwUom8Y3FuJBwhvFpQ= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= +cloud.google.com/go/iap v1.10.2 h1:rvM+FNIF2wIbwUU8299FhhVGak2f7oOvbW8J/I5oflE= +cloud.google.com/go/iap v1.10.2/go.mod h1:cClgtI09VIfazEK6VMJr6bX8KQfuQ/D3xqX+d0wrUlI= cloud.google.com/go/kms v1.20.1 h1:og29Wv59uf2FVaZlesaiDAqHFzHaoUyHI3HYp9VUHVg= cloud.google.com/go/kms v1.20.1/go.mod h1:LywpNiVCvzYNJWS9JUcGJSVTNSwPwi0vBAotzDqn2nc= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= diff --git a/pkg/controller/direct/iap/iapsettings_mappings.go b/pkg/controller/direct/iap/iapsettings_mappings.go new file mode 100644 index 0000000000..83e6ed4171 --- /dev/null +++ b/pkg/controller/direct/iap/iapsettings_mappings.go @@ -0,0 +1,32 @@ +// 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. + +package iap + +import ( + pb "cloud.google.com/go/iap/apiv1/iappb" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/iap/v1alpha1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func AccessDeniedPageSettings_ToProto(mapCtx *direct.MapContext, in *krm.AccessDeniedPageSettings) *pb.AccessDeniedPageSettings { + if in == nil { + return nil + } + out := &pb.AccessDeniedPageSettings{} + out.AccessDeniedPageUri = direct.StringValue_ToProto(mapCtx, in.AccessDeniedPageURI) + out.GenerateTroubleshootingUri = direct.BoolValue_ToProto(mapCtx, in.GenerateTroubleshootingURI) + out.RemediationTokenGenerationEnabled = direct.BoolValue_ToProto(mapCtx, in.RemediationTokenGenerationEnabled) // this line is manually edited because proto field is incorrectly marked as oneof + return out +} diff --git a/pkg/controller/direct/iap/mapper.generated.go b/pkg/controller/direct/iap/mapper.generated.go new file mode 100644 index 0000000000..39a96faffd --- /dev/null +++ b/pkg/controller/direct/iap/mapper.generated.go @@ -0,0 +1,224 @@ +// Copyright 2025 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. + +package iap + +import ( + pb "cloud.google.com/go/iap/apiv1/iappb" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/iap/v1alpha1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func AccessDeniedPageSettings_FromProto(mapCtx *direct.MapContext, in *pb.AccessDeniedPageSettings) *krm.AccessDeniedPageSettings { + if in == nil { + return nil + } + out := &krm.AccessDeniedPageSettings{} + out.AccessDeniedPageURI = direct.StringValue_FromProto(mapCtx, in.GetAccessDeniedPageUri()) + out.GenerateTroubleshootingURI = direct.BoolValue_FromProto(mapCtx, in.GetGenerateTroubleshootingUri()) + out.RemediationTokenGenerationEnabled = direct.BoolValue_FromProto(mapCtx, in.GetRemediationTokenGenerationEnabled()) + return out +} +func AccessSettings_FromProto(mapCtx *direct.MapContext, in *pb.AccessSettings) *krm.AccessSettings { + if in == nil { + return nil + } + out := &krm.AccessSettings{} + out.GcipSettings = GcipSettings_FromProto(mapCtx, in.GetGcipSettings()) + out.CorsSettings = CorsSettings_FromProto(mapCtx, in.GetCorsSettings()) + out.OauthSettings = OAuthSettings_FromProto(mapCtx, in.GetOauthSettings()) + out.ReauthSettings = ReauthSettings_FromProto(mapCtx, in.GetReauthSettings()) + out.AllowedDomainsSettings = AllowedDomainsSettings_FromProto(mapCtx, in.GetAllowedDomainsSettings()) + return out +} +func AccessSettings_ToProto(mapCtx *direct.MapContext, in *krm.AccessSettings) *pb.AccessSettings { + if in == nil { + return nil + } + out := &pb.AccessSettings{} + out.GcipSettings = GcipSettings_ToProto(mapCtx, in.GcipSettings) + out.CorsSettings = CorsSettings_ToProto(mapCtx, in.CorsSettings) + out.OauthSettings = OAuthSettings_ToProto(mapCtx, in.OauthSettings) + out.ReauthSettings = ReauthSettings_ToProto(mapCtx, in.ReauthSettings) + out.AllowedDomainsSettings = AllowedDomainsSettings_ToProto(mapCtx, in.AllowedDomainsSettings) + return out +} +func AllowedDomainsSettings_FromProto(mapCtx *direct.MapContext, in *pb.AllowedDomainsSettings) *krm.AllowedDomainsSettings { + if in == nil { + return nil + } + out := &krm.AllowedDomainsSettings{} + out.Enable = in.Enable + out.Domains = in.Domains + return out +} +func AllowedDomainsSettings_ToProto(mapCtx *direct.MapContext, in *krm.AllowedDomainsSettings) *pb.AllowedDomainsSettings { + if in == nil { + return nil + } + out := &pb.AllowedDomainsSettings{} + out.Enable = in.Enable + out.Domains = in.Domains + return out +} +func ApplicationSettings_FromProto(mapCtx *direct.MapContext, in *pb.ApplicationSettings) *krm.ApplicationSettings { + if in == nil { + return nil + } + out := &krm.ApplicationSettings{} + out.CsmSettings = CsmSettings_FromProto(mapCtx, in.GetCsmSettings()) + out.AccessDeniedPageSettings = AccessDeniedPageSettings_FromProto(mapCtx, in.GetAccessDeniedPageSettings()) + out.CookieDomain = direct.StringValue_FromProto(mapCtx, in.GetCookieDomain()) + out.AttributePropagationSettings = AttributePropagationSettings_FromProto(mapCtx, in.GetAttributePropagationSettings()) + return out +} +func ApplicationSettings_ToProto(mapCtx *direct.MapContext, in *krm.ApplicationSettings) *pb.ApplicationSettings { + if in == nil { + return nil + } + out := &pb.ApplicationSettings{} + out.CsmSettings = CsmSettings_ToProto(mapCtx, in.CsmSettings) + out.AccessDeniedPageSettings = AccessDeniedPageSettings_ToProto(mapCtx, in.AccessDeniedPageSettings) + out.CookieDomain = direct.StringValue_ToProto(mapCtx, in.CookieDomain) + out.AttributePropagationSettings = AttributePropagationSettings_ToProto(mapCtx, in.AttributePropagationSettings) + return out +} +func AttributePropagationSettings_FromProto(mapCtx *direct.MapContext, in *pb.AttributePropagationSettings) *krm.AttributePropagationSettings { + if in == nil { + return nil + } + out := &krm.AttributePropagationSettings{} + out.Expression = in.Expression + out.OutputCredentials = direct.EnumSlice_FromProto(mapCtx, in.OutputCredentials) + out.Enable = in.Enable + return out +} +func AttributePropagationSettings_ToProto(mapCtx *direct.MapContext, in *krm.AttributePropagationSettings) *pb.AttributePropagationSettings { + if in == nil { + return nil + } + out := &pb.AttributePropagationSettings{} + out.Expression = in.Expression + out.OutputCredentials = direct.EnumSlice_ToProto[pb.AttributePropagationSettings_OutputCredentials](mapCtx, in.OutputCredentials) + out.Enable = in.Enable + return out +} +func CorsSettings_FromProto(mapCtx *direct.MapContext, in *pb.CorsSettings) *krm.CorsSettings { + if in == nil { + return nil + } + out := &krm.CorsSettings{} + out.AllowHTTPOptions = direct.BoolValue_FromProto(mapCtx, in.GetAllowHttpOptions()) + return out +} +func CorsSettings_ToProto(mapCtx *direct.MapContext, in *krm.CorsSettings) *pb.CorsSettings { + if in == nil { + return nil + } + out := &pb.CorsSettings{} + out.AllowHttpOptions = direct.BoolValue_ToProto(mapCtx, in.AllowHTTPOptions) + return out +} +func CsmSettings_FromProto(mapCtx *direct.MapContext, in *pb.CsmSettings) *krm.CsmSettings { + if in == nil { + return nil + } + out := &krm.CsmSettings{} + out.RctokenAud = direct.StringValue_FromProto(mapCtx, in.GetRctokenAud()) + return out +} +func CsmSettings_ToProto(mapCtx *direct.MapContext, in *krm.CsmSettings) *pb.CsmSettings { + if in == nil { + return nil + } + out := &pb.CsmSettings{} + out.RctokenAud = direct.StringValue_ToProto(mapCtx, in.RctokenAud) + return out +} +func GcipSettings_FromProto(mapCtx *direct.MapContext, in *pb.GcipSettings) *krm.GcipSettings { + if in == nil { + return nil + } + out := &krm.GcipSettings{} + out.TenantIds = in.TenantIds + out.LoginPageURI = direct.StringValue_FromProto(mapCtx, in.GetLoginPageUri()) + return out +} +func GcipSettings_ToProto(mapCtx *direct.MapContext, in *krm.GcipSettings) *pb.GcipSettings { + if in == nil { + return nil + } + out := &pb.GcipSettings{} + out.TenantIds = in.TenantIds + out.LoginPageUri = direct.StringValue_ToProto(mapCtx, in.LoginPageURI) + return out +} +func IAPSettingsSpec_FromProto(mapCtx *direct.MapContext, in *pb.IapSettings) *krm.IAPSettingsSpec { + if in == nil { + return nil + } + out := &krm.IAPSettingsSpec{} + out.Name = direct.LazyPtr(in.GetName()) + out.AccessSettings = AccessSettings_FromProto(mapCtx, in.GetAccessSettings()) + out.ApplicationSettings = ApplicationSettings_FromProto(mapCtx, in.GetApplicationSettings()) + return out +} +func IAPSettingsSpec_ToProto(mapCtx *direct.MapContext, in *krm.IAPSettingsSpec) *pb.IapSettings { + if in == nil { + return nil + } + out := &pb.IapSettings{} + out.Name = direct.ValueOf(in.Name) + out.AccessSettings = AccessSettings_ToProto(mapCtx, in.AccessSettings) + out.ApplicationSettings = ApplicationSettings_ToProto(mapCtx, in.ApplicationSettings) + return out +} +func OAuthSettings_FromProto(mapCtx *direct.MapContext, in *pb.OAuthSettings) *krm.OAuthSettings { + if in == nil { + return nil + } + out := &krm.OAuthSettings{} + out.LoginHint = direct.StringValue_FromProto(mapCtx, in.GetLoginHint()) + out.ProgrammaticClients = in.ProgrammaticClients + return out +} +func OAuthSettings_ToProto(mapCtx *direct.MapContext, in *krm.OAuthSettings) *pb.OAuthSettings { + if in == nil { + return nil + } + out := &pb.OAuthSettings{} + out.LoginHint = direct.StringValue_ToProto(mapCtx, in.LoginHint) + out.ProgrammaticClients = in.ProgrammaticClients + return out +} +func ReauthSettings_FromProto(mapCtx *direct.MapContext, in *pb.ReauthSettings) *krm.ReauthSettings { + if in == nil { + return nil + } + out := &krm.ReauthSettings{} + out.Method = direct.Enum_FromProto(mapCtx, in.GetMethod()) + out.MaxAge = direct.StringDuration_FromProto(mapCtx, in.GetMaxAge()) + out.PolicyType = direct.Enum_FromProto(mapCtx, in.GetPolicyType()) + return out +} +func ReauthSettings_ToProto(mapCtx *direct.MapContext, in *krm.ReauthSettings) *pb.ReauthSettings { + if in == nil { + return nil + } + out := &pb.ReauthSettings{} + out.Method = direct.Enum_ToProto[pb.ReauthSettings_Method](mapCtx, in.Method) + out.MaxAge = direct.StringDuration_ToProto(mapCtx, in.MaxAge) + out.PolicyType = direct.Enum_ToProto[pb.ReauthSettings_PolicyType](mapCtx, in.PolicyType) + return out +} diff --git a/pkg/controller/direct/maputils.go b/pkg/controller/direct/maputils.go index 34ba5a03f5..293419ae9e 100644 --- a/pkg/controller/direct/maputils.go +++ b/pkg/controller/direct/maputils.go @@ -211,6 +211,38 @@ func StringDuration_ToProto(mapCtx *MapContext, s *string) *durationpb.Duration return durationpb.New(td) } +func StringValue_FromProto(mapCtx *MapContext, in *wrapperspb.StringValue) *string { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func StringValue_ToProto(mapCtx *MapContext, in *string) *wrapperspb.StringValue { + if in == nil { + return nil + } + out := wrapperspb.String(*in) + return out +} + +func BoolValue_FromProto(mapCtx *MapContext, in *wrapperspb.BoolValue) *bool { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func BoolValue_ToProto(mapCtx *MapContext, in *bool) *wrapperspb.BoolValue { + if in == nil { + return nil + } + out := wrapperspb.Bool(*in) + return out +} + func PtrTo[T any](t T) *T { return &t } @@ -334,3 +366,98 @@ func Int64Value_FromProto(mapCtx *MapContext, ts *wrapperspb.Int64Value) int64 { func Int64Value_ToProto(mapCtx *MapContext, s int64) *wrapperspb.Int64Value { return wrapperspb.Int64(s) } + +func FloatValue_FromProto(mapCtx *MapContext, in *wrapperspb.FloatValue) *float32 { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func FloatValue_ToProto(mapCtx *MapContext, in *float32) *wrapperspb.FloatValue { + if in == nil { + return nil + } + out := wrapperspb.Float(*in) + return out +} + +// Float64 wrapper functions +func DoubleValue_FromProto(mapCtx *MapContext, in *wrapperspb.DoubleValue) *float64 { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func DoubleValue_ToProto(mapCtx *MapContext, in *float64) *wrapperspb.DoubleValue { + if in == nil { + return nil + } + out := wrapperspb.Double(*in) + return out +} + +func Int32Value_FromProto(mapCtx *MapContext, in *wrapperspb.Int32Value) *int32 { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func Int32Value_ToProto(mapCtx *MapContext, in *int32) *wrapperspb.Int32Value { + if in == nil { + return nil + } + out := wrapperspb.Int32(*in) + return out +} + +func UInt32Value_FromProto(mapCtx *MapContext, in *wrapperspb.UInt32Value) *uint32 { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func UInt32Value_ToProto(mapCtx *MapContext, in *uint32) *wrapperspb.UInt32Value { + if in == nil { + return nil + } + out := wrapperspb.UInt32(*in) + return out +} + +func UInt64Value_FromProto(mapCtx *MapContext, in *wrapperspb.UInt64Value) *uint64 { + if in == nil { + return nil + } + out := in.Value + return &out +} + +func UInt64Value_ToProto(mapCtx *MapContext, in *uint64) *wrapperspb.UInt64Value { + if in == nil { + return nil + } + out := wrapperspb.UInt64(*in) + return out +} + +func BytesValue_FromProto(mapCtx *MapContext, in *wrapperspb.BytesValue) []byte { + if in == nil { + return nil + } + return in.Value +} + +func BytesValue_ToProto(mapCtx *MapContext, in []byte) *wrapperspb.BytesValue { + if in == nil { + return nil + } + return wrapperspb.Bytes(in) +}