Skip to content

Commit

Permalink
enable private service connect
Browse files Browse the repository at this point in the history
  • Loading branch information
kon-angelo committed Jul 29, 2022
1 parent 409d56c commit a378d33
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ webhooks:
- cloudprofiles
- secretbindings
- shoots
- shoots/binding
failurePolicy: Fail
objectSelector:
{{- if .Values.global.webhookConfig.useObjectSelector }}
Expand Down
9 changes: 9 additions & 0 deletions docs/usage-as-end-user.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ Make sure to [enable the Google Identity and Access Management (IAM) API](https:
- Service Account User
- Compute Admin

If you want to use the [Private Service Connect](https://cloud.google.com/vpc/docs/private-service-connect) services, then you need to additionally grant the [following permissions](https://cloud.google.com/vpc/docs/configure-private-service-connect-apis#roles) :
- Service Directory Editor (roles/servicedirectory.editor)
- DNS Administrator (roles/dns.admin)

Create a [JSON Service Account key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating_service_account_keys) for the Service Account.
Provide it in the `Secret` (base64 encoded for field `serviceaccount.json`), that is being referenced by the `SecretBinding` in the Shoot cluster configuration.

Expand Down Expand Up @@ -62,6 +66,9 @@ networks:
# natIPNames:
# - name: manualnat1
# - name: manualnat2
# privateServiceConnect:
# enabled: true
# endpointIP: 10.252.0.0
# flowLogs:
# aggregationInterval: INTERVAL_5_SEC
# flowSampling: 0.2
Expand Down Expand Up @@ -99,6 +106,8 @@ The `networks.flowLogs` section describes the configuration for the VPC flow log

Apart from the VPC and the subnets the GCP extension will also create a dedicated service account for this shoot, and firewall rules.

The `networks.privateServiceConnect` is an optional parameter describing whether the [Private Service Connect](https://cloud.google.com/vpc/docs/private-service-connect) should be enabled for the network. `networks.privateServiceConnect.endpointIP` is the endpoint where users can access Google services privately from their network. This IP should not overlap with current network subnet CIDRs or other important ranges that should be accesible from the shoot cluster.

## `ControlPlaneConfig`

The control plane configuration mainly contains values for the GCP-specific control plane components.
Expand Down
1 change: 1 addition & 0 deletions example/40-validatingwebhookconfiguration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ webhooks:
- cloudprofiles
- secretbindings
- shoots
- shoots/binding
failurePolicy: Fail
# Please make sure you are running `[email protected]` or later before enabling this object selector.
objectSelector:
Expand Down
51 changes: 51 additions & 0 deletions hack/api-reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,19 @@ FlowLogs
<p>FlowLogs contains the flow log configuration for the subnet.</p>
</td>
</tr>
<tr>
<td>
<code>privateServiceConnect</code></br>
<em>
<a href="#gcp.provider.extensions.gardener.cloud/v1alpha1.PrivateServiceConnect">
PrivateServiceConnect
</a>
</em>
</td>
<td>
<p>PrivateServiceConnect</p>
</td>
</tr>
</tbody>
</table>
<h3 id="gcp.provider.extensions.gardener.cloud/v1alpha1.NetworkStatus">NetworkStatus
Expand Down Expand Up @@ -838,6 +851,44 @@ VPC
</tr>
</tbody>
</table>
<h3 id="gcp.provider.extensions.gardener.cloud/v1alpha1.PrivateServiceConnect">PrivateServiceConnect
</h3>
<p>
(<em>Appears on:</em>
<a href="#gcp.provider.extensions.gardener.cloud/v1alpha1.NetworkConfig">NetworkConfig</a>)
</p>
<p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>enabled</code></br>
<em>
bool
</em>
</td>
<td>
</td>
</tr>
<tr>
<td>
<code>endpointIP</code></br>
<em>
string
</em>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<h3 id="gcp.provider.extensions.gardener.cloud/v1alpha1.ServiceAccount">ServiceAccount
</h3>
<p>
Expand Down
28 changes: 23 additions & 5 deletions pkg/admission/validator/shoot.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (
"fmt"
"reflect"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/utils/pointer"

"github.com/gardener/gardener-extension-provider-gcp/pkg/admission"
apisgcp "github.com/gardener/gardener-extension-provider-gcp/pkg/apis/gcp"
gcpvalidation "github.com/gardener/gardener-extension-provider-gcp/pkg/apis/gcp/validation"
Expand Down Expand Up @@ -89,6 +92,7 @@ var (

type validationContext struct {
shoot *core.Shoot
seed *gardencorev1beta1.Seed
infrastructureConfig *apisgcp.InfrastructureConfig
controlPlaneConfig *apisgcp.ControlPlaneConfig
cloudProfile *gardencorev1beta1.CloudProfile
Expand Down Expand Up @@ -120,12 +124,13 @@ func getAllowedRegionZonesFromCloudProfile(shoot *core.Shoot, cloudProfile *gard

func (s *shoot) validateContext(valContext *validationContext) field.ErrorList {
var (
allErrors = field.ErrorList{}
allowedZones = getAllowedRegionZonesFromCloudProfile(valContext.shoot, valContext.cloudProfile)
allErrors = field.ErrorList{}
allowedZones = getAllowedRegionZonesFromCloudProfile(valContext.shoot, valContext.cloudProfile)
seedServiceCIDR *string
)

allErrors = append(allErrors, gcpvalidation.ValidateNetworking(valContext.shoot.Spec.Networking, networkPath)...)
allErrors = append(allErrors, gcpvalidation.ValidateInfrastructureConfig(valContext.infrastructureConfig, valContext.shoot.Spec.Networking.Nodes, valContext.shoot.Spec.Networking.Pods, valContext.shoot.Spec.Networking.Services, infrastructureConfigPath)...)
allErrors = append(allErrors, gcpvalidation.ValidateInfrastructureConfig(valContext.infrastructureConfig, valContext.shoot.Spec.Networking.Nodes, valContext.shoot.Spec.Networking.Pods, valContext.shoot.Spec.Networking.Services, seedServiceCIDR, infrastructureConfigPath)...)
allErrors = append(allErrors, gcpvalidation.ValidateWorkers(valContext.shoot.Spec.Provider.Workers, workersPath)...)
allErrors = append(allErrors, gcpvalidation.ValidateControlPlaneConfig(valContext.controlPlaneConfig, allowedZones, workersZones(valContext.shoot.Spec.Provider.Workers), valContext.shoot.Spec.Kubernetes.Version, controlPlaneConfigPath)...)

Expand Down Expand Up @@ -169,9 +174,11 @@ func (s *shoot) validateUpdate(ctx context.Context, oldShoot, currentShoot *core
allErrors = field.ErrorList{}
)

if !reflect.DeepEqual(oldInfrastructureConfig, currentInfrastructureConfig) {
allErrors = append(allErrors, gcpvalidation.ValidateInfrastructureConfigUpdate(oldInfrastructureConfig, currentInfrastructureConfig, infrastructureConfigPath)...)
var seedServices *string
if currentValContext.seed != nil {
seedServices = pointer.String(currentValContext.seed.Spec.Networks.Services)
}
allErrors = append(allErrors, gcpvalidation.ValidateInfrastructureConfigUpdate(oldInfrastructureConfig, currentInfrastructureConfig, seedServices, infrastructureConfigPath)...)

if !reflect.DeepEqual(oldControlPlaneConfig, currentControlPlaneConfig) {
allErrors = append(allErrors, gcpvalidation.ValidateControlPlaneConfigUpdate(oldControlPlaneConfig, currentControlPlaneConfig, controlPlaneConfigPath)...)
Expand Down Expand Up @@ -209,13 +216,24 @@ func newValidationContext(ctx context.Context, decoder runtime.Decoder, c client
if cloudProfile.Spec.ProviderConfig == nil {
return nil, fmt.Errorf("providerConfig is not given for cloud profile %q", cloudProfile.Name)
}

cloudProfileConfig, err := admission.DecodeCloudProfileConfig(decoder, cloudProfile.Spec.ProviderConfig)
if err != nil {
return nil, fmt.Errorf("an error occurred while reading the cloud profile %q: %v", cloudProfile.Name, err)
}

var seed *gardencorev1beta1.Seed
if shoot.Spec.SeedName != nil && len(*shoot.Spec.SeedName) > 0 {
seed = &gardencorev1beta1.Seed{}
err = c.Get(ctx, kutil.Key(*shoot.Spec.SeedName), seed)
if err != nil && !errors.IsNotFound(err) {
return nil, fmt.Errorf("an error occured while reading seed information: %v", err)
}
}

return &validationContext{
shoot: shoot,
seed: seed,
infrastructureConfig: infrastructureConfig,
controlPlaneConfig: controlPlaneConfig,
cloudProfile: cloudProfile,
Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/gcp/types_infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ type NetworkConfig struct {
Workers string
// FlowLogs contains the flow log configuration for the subnet.
FlowLogs *FlowLogs
// PrivateServiceConnect configures access to Google services via Private Service Connect.
PrivateServiceConnect *PrivateServiceConnect
}

// PrivateServiceConnect holds the configuration for Private Service Connect endpoints.
type PrivateServiceConnect struct {
Enabled bool
EndpointIP string
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
9 changes: 9 additions & 0 deletions pkg/apis/gcp/v1alpha1/types_infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ type NetworkConfig struct {
// FlowLogs contains the flow log configuration for the subnet.
// +optional
FlowLogs *FlowLogs `json:"flowLogs,omitempty"`
// PrivateServiceConnect configures access to Google services via Private Service Connect.
// +optional
PrivateServiceConnect *PrivateServiceConnect `json:"privateServiceConnect,omitempty"`
}

// PrivateServiceConnect holds the configuration for Private Service Connect endpoints.
type PrivateServiceConnect struct {
Enabled bool `json:"enabled"`
EndpointIP string `json:"endpointIP"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
34 changes: 34 additions & 0 deletions pkg/apis/gcp/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions pkg/apis/gcp/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a378d33

Please sign in to comment.