Skip to content

Commit

Permalink
bastion configvalidator
Browse files Browse the repository at this point in the history
  • Loading branch information
tedteng committed Aug 24, 2022
1 parent 1442dc6 commit b037d5b
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 42 deletions.
41 changes: 1 addition & 40 deletions pkg/controller/bastion/actuator_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ import (

"github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud"
aliclient "github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud/client"
alicloudapi "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud"
"github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud/helper"

"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/gardener/gardener/extensions/pkg/controller"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
ctrlerror "github.com/gardener/gardener/pkg/controllerutils/reconciler"
"github.com/gardener/gardener/pkg/extensions"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
Expand Down Expand Up @@ -57,7 +54,7 @@ func (a *actuator) Reconcile(ctx context.Context, log logr.Logger, bastion *exte
return err
}

infrastructureStatus, err := getInfrastructureStatus(ctx, a, cluster)
infrastructureStatus, err := getInfrastructureStatus(ctx, a.client, cluster)
if err != nil {
return err
}
Expand Down Expand Up @@ -451,39 +448,3 @@ func egressRuleEqual(a ecs.AuthorizeSecurityGroupEgressRequest, b ecs.Permission

return true
}

func getInfrastructureStatus(ctx context.Context, a *actuator, cluster *extensions.Cluster) (*alicloudapi.InfrastructureStatus, error) {
var infrastructureStatus *alicloudapi.InfrastructureStatus
worker := &extensionsv1alpha1.Worker{}
err := a.client.Get(ctx, client.ObjectKey{Namespace: cluster.ObjectMeta.Name, Name: cluster.Shoot.Name}, worker)
if err != nil {
return nil, err
}

if worker.Spec.InfrastructureProviderStatus == nil {
return nil, errors.New("infrastructure provider status must be not empty for worker")
}

if infrastructureStatus, err = helper.InfrastructureStatusFromRaw(worker.Spec.InfrastructureProviderStatus); err != nil {
return nil, err
}

if infrastructureStatus.VPC.ID == "" {
return nil, errors.New("vpc id must be not empty for infrastructure provider status")
}

if len(infrastructureStatus.VPC.VSwitches) == 0 || infrastructureStatus.VPC.VSwitches[0].ID == "" || infrastructureStatus.VPC.VSwitches[0].Zone == "" {
return nil, errors.New("vswitches id must be not empty for infrastructure provider status")
}

if len(infrastructureStatus.MachineImages) == 0 || infrastructureStatus.MachineImages[0].ID == "" {
return nil, errors.New("machineImages id must be not empty for infrastructure provider status")
}

// The assumption is that the shoot only has one security group
if len(infrastructureStatus.VPC.SecurityGroups) == 0 || infrastructureStatus.VPC.SecurityGroups[0].ID == "" {
return nil, errors.New("shoot securityGroups id must be not empty for infrastructure provider status")
}

return infrastructureStatus, nil
}
3 changes: 3 additions & 0 deletions pkg/controller/bastion/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package bastion

import (
"github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud"
aliclient "github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud/client"

"github.com/gardener/gardener/extensions/pkg/controller/bastion"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/manager"
Expand All @@ -39,6 +41,7 @@ type AddOptions struct {
func AddToManagerWithOptions(mgr manager.Manager, opts AddOptions) error {
return bastion.Add(mgr, bastion.AddArgs{
Actuator: newActuator(),
ConfigValidator: NewConfigValidator(aliclient.NewClientFactory()),
ControllerOptions: opts.Controller,
Predicates: bastion.DefaultPredicates(opts.IgnoreOperationAnnotation),
Type: alicloud.Type,
Expand Down
140 changes: 140 additions & 0 deletions pkg/controller/bastion/configvalidator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package bastion

import (
"context"
"errors"
"fmt"

"github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud"
aliclient "github.com/gardener/gardener-extension-provider-alicloud/pkg/alicloud/client"
alicloudapi "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud"
"github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud/helper"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/gardener/gardener/extensions/pkg/controller/bastion"
"github.com/gardener/gardener/extensions/pkg/controller/common"
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1"
"github.com/gardener/gardener/pkg/extensions"
)

// configValidator implements ConfigValidator for AliCloud bastion resources.
type configValidator struct {
common.ClientContext
aliClientFactory aliclient.ClientFactory
}

// NewConfigValidator creates a new ConfigValidator.
func NewConfigValidator(aliClientFactory aliclient.ClientFactory) bastion.ConfigValidator {
return &configValidator{
aliClientFactory: aliClientFactory,
}
}

// Validate validates the provider config of the given bastion resource with the cloud provider.
func (c *configValidator) Validate(ctx context.Context, bastion *extensionsv1alpha1.Bastion, cluster *extensions.Cluster) field.ErrorList {
allErrs := field.ErrorList{}

// Get value from infrastructure status
infrastructureStatus, err := getInfrastructureStatus(ctx, c.Client(), cluster)
if err != nil {
allErrs = append(allErrs, field.InternalError(nil, err))
return allErrs
}

secretReference := &corev1.SecretReference{
Namespace: cluster.ObjectMeta.Name,
Name: v1beta1constants.SecretNameCloudProvider,
}

credentials, err := alicloud.ReadCredentialsFromSecretRef(ctx, c.Client(), secretReference)
if err != nil {
allErrs = append(allErrs, field.InternalError(nil, err))
return allErrs
}

// Create alicloud ECS client
aliCloudECSClient, err := c.aliClientFactory.NewECSClient(cluster.Shoot.Spec.Region, credentials.AccessKeyID, credentials.AccessKeySecret)
if err != nil {
allErrs = append(allErrs, field.InternalError(nil, err))
return allErrs
}

aliCloudVPCClient, err := c.aliClientFactory.NewVPCClient(cluster.Shoot.Spec.Region, credentials.AccessKeyID, credentials.AccessKeySecret)
if err != nil {
allErrs = append(allErrs, field.InternalError(nil, err))
return allErrs
}

// Validate infrastructureStatus value
allErrs = append(allErrs, c.validateInfrastructureStatus(ctx, aliCloudECSClient, aliCloudVPCClient, infrastructureStatus)...)
return allErrs
}

func getInfrastructureStatus(ctx context.Context, c client.Client, cluster *extensions.Cluster) (*alicloudapi.InfrastructureStatus, error) {
var infrastructureStatus *alicloudapi.InfrastructureStatus
worker := &extensionsv1alpha1.Worker{}
err := c.Get(ctx, client.ObjectKey{Namespace: cluster.ObjectMeta.Name, Name: cluster.Shoot.Name}, worker)
if err != nil {
return nil, err
}

if worker.Spec.InfrastructureProviderStatus == nil {
return nil, errors.New("infrastructure provider status must be not empty for worker")
}

if infrastructureStatus, err = helper.InfrastructureStatusFromRaw(worker.Spec.InfrastructureProviderStatus); err != nil {
return nil, err
}

if infrastructureStatus.VPC.ID == "" {
return nil, errors.New("vpc id must be not empty for infrastructure provider status")
}

if len(infrastructureStatus.VPC.VSwitches) == 0 || infrastructureStatus.VPC.VSwitches[0].ID == "" || infrastructureStatus.VPC.VSwitches[0].Zone == "" {
return nil, errors.New("vswitches id must be not empty for infrastructure provider status")
}

if len(infrastructureStatus.MachineImages) == 0 || infrastructureStatus.MachineImages[0].ID == "" {
return nil, errors.New("machineImages id must be not empty for infrastructure provider status")
}

// The assumption is that the shoot only has one security group
if len(infrastructureStatus.VPC.SecurityGroups) == 0 || infrastructureStatus.VPC.SecurityGroups[0].ID == "" {
return nil, errors.New("shoot securityGroups id must be not empty for infrastructure provider status")
}

return infrastructureStatus, nil
}

func (c *configValidator) validateInfrastructureStatus(ctx context.Context, aliCloudECSClient aliclient.ECS, aliCloudVPCClient aliclient.VPC, infrastructureStatus *alicloudapi.InfrastructureStatus) field.ErrorList {
allErrs := field.ErrorList{}

vpc, err := aliCloudVPCClient.GetVPCWithID(ctx, infrastructureStatus.VPC.ID)
if err != nil || len(vpc) == 0 {
allErrs = append(allErrs, field.NotFound(field.NewPath("vpc"), fmt.Errorf("could not get vpc %s from alicloud provider: %w", infrastructureStatus.VPC.ID, err)))
return allErrs
}

vSwitch, err := aliCloudVPCClient.GetVSwitchesInfoByID(infrastructureStatus.VPC.VSwitches[0].ID)
if err != nil || vSwitch.ZoneID == "" {
allErrs = append(allErrs, field.NotFound(field.NewPath("vswitches"), fmt.Errorf("could not get vswitches %s from alicloud provider: %w", infrastructureStatus.VPC.VSwitches[0].ID, err)))
return allErrs
}

machineImages, err := aliCloudECSClient.CheckIfImageExists(infrastructureStatus.MachineImages[0].ID)
if err != nil || !machineImages {
allErrs = append(allErrs, field.NotFound(field.NewPath("machineImages"), fmt.Errorf("could not get machineImages %s from alicloud provider: %w", infrastructureStatus.MachineImages[0].ID, err)))
return allErrs
}

shootSecurityGroupId, err := aliCloudECSClient.GetSecurityGroupWithID(infrastructureStatus.VPC.SecurityGroups[0].ID)
if err != nil || len(shootSecurityGroupId.SecurityGroups.SecurityGroup) == 0 || shootSecurityGroupId.SecurityGroups.SecurityGroup[0].SecurityGroupId == "" {
allErrs = append(allErrs, field.NotFound(field.NewPath("securityGroup"), fmt.Errorf("could not get shoot security group %s from alicloud provider: %w", infrastructureStatus.VPC.SecurityGroups[0].ID, err)))
return allErrs
}

return allErrs
}
4 changes: 2 additions & 2 deletions pkg/controller/infrastructure/actuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ func (a *actuator) ensureEncryptedImageForShootProviderAccount(
return nil, err
}

if exist, err := shootECSClient.CheckIfImageExists(ctx, imageID); err != nil {
if exist, err := shootECSClient.CheckIfImageExists(imageID); err != nil {
return nil, err
} else if exist {
// Check if image is provided by AliCloud (OwnerAlias is System).
Expand Down Expand Up @@ -502,7 +502,7 @@ func (a *actuator) makeImageVisibleForShoot(ctx context.Context, log logr.Logger
return nil
}

exists, err := shootECSClient.CheckIfImageExists(ctx, imageID)
exists, err := shootECSClient.CheckIfImageExists(imageID)
if err != nil {
return err
}
Expand Down

0 comments on commit b037d5b

Please sign in to comment.