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

feat(AzureRedisInstance): add Azure redis instance to subnet #524

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions api/cloud-control/v1beta1/scope_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,31 @@ type AzureScope struct {

// +kubebuilder:validation:Required
VpcNetwork string `json:"vpcNetwork"`

// +kubebuilder:validation:Required
Network AzureNetwork `json:"azureNetwork"`

// +kubebuilder:validation:Required
TechnicalID string `json:"technicalID"`
}

type AzureNetwork struct {
// +optional
Nodes string `json:"nodes,omitempty"`

// +optional
Pods string `json:"pods,omitempty"`

// +optional
Services string `json:"services,omitempty"`

// +optional
VPC AzureVPC `json:"vpc"`
}

type AzureVPC struct {
Id string `json:"id,omitempty"`
CIDR string `json:"cidr,omitempty"`
}

type AwsScope struct {
Expand Down
32 changes: 32 additions & 0 deletions api/cloud-control/v1beta1/zz_generated.deepcopy.go

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

20 changes: 20 additions & 0 deletions config/crd/bases/cloud-control.kyma-project.io_scopes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,34 @@ spec:
type: object
azure:
properties:
azureNetwork:
properties:
nodes:
type: string
pods:
type: string
services:
type: string
vpc:
properties:
cidr:
type: string
id:
type: string
type: object
type: object
subscriptionId:
type: string
technicalID:
type: string
tenantId:
type: string
vpcNetwork:
type: string
required:
- azureNetwork
- subscriptionId
- technicalID
- tenantId
- vpcNetwork
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,34 @@ spec:
type: object
azure:
properties:
azureNetwork:
properties:
nodes:
type: string
pods:
type: string
services:
type: string
vpc:
properties:
cidr:
type: string
id:
type: string
type: object
type: object
subscriptionId:
type: string
technicalID:
type: string
tenantId:
type: string
vpcNetwork:
type: string
required:
- azureNetwork
- subscriptionId
- technicalID
- tenantId
- vpcNetwork
type: object
Expand Down
2 changes: 1 addition & 1 deletion pkg/kcp/iprange/allocate/allocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func AllocateCidr(maskOnes int, existingRanges []string) (string, error) {
}

current, _ := parseRange(existingRanges[0])
current.nextWithOnes(maskOnes)
current = current.nextWithOnes(maskOnes)
for occupied.overlaps(current) {
current = current.next()
if current == nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/kcp/iprange/allocate/allocate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func TestAllocateCidr(t *testing.T) {
s string
}{
{22, []string{"10.250.0.0/22", "10.96.0.0/13", "10.104.0.0/13"}, "10.250.4.0/22"},
{25, []string{"10.250.0.0/22", "10.96.0.0/13", "10.104.0.0/13"}, "10.250.4.0/25"},
}
for x, item := range list {
t.Run(strconv.Itoa(x), func(t *testing.T) {
Expand Down
9 changes: 9 additions & 0 deletions pkg/kcp/provider/azure/mock/redisCacheClientFake.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5"
armRedis "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redis/armredis"
armResources "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"k8s.io/utils/ptr"
Expand Down Expand Up @@ -148,3 +149,11 @@ func (redisCacheClientFake *redisCacheClientFake) UpdateRedisInstance(ctx contex

return nil
}

func (redisCacheClientFake *redisCacheClientFake) GetSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string) (*armnetwork.SubnetsClientGetResponse, error) {
return &armnetwork.SubnetsClientGetResponse{Subnet: armnetwork.Subnet{Name: ptr.To("fake-subnet")}}, nil
}

func (redisCacheClientFake *redisCacheClientFake) CreateSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName, cidr string) error {
return nil
}
46 changes: 44 additions & 2 deletions pkg/kcp/provider/azure/redisinstance/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5"
armRedis "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redis/armredis"
armResources "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/kyma-project/cloud-manager/pkg/composed"
Expand All @@ -19,6 +20,8 @@ type Client interface {
GetResourceGroup(ctx context.Context, name string) (*armResources.ResourceGroupsClientGetResponse, error)
CreateResourceGroup(ctx context.Context, name string, location string) error
DeleteResourceGroup(ctx context.Context, name string) error
GetSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string) (*armnetwork.SubnetsClientGetResponse, error)
CreateSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName, cidr string) error
}

func NewClientProvider() azureClient.SkrClientProvider[Client] {
Expand All @@ -42,19 +45,27 @@ func NewClientProvider() azureClient.SkrClientProvider[Client] {
return nil, err
}

return newClient(armRedisClientInstance, resourceGroupClientInstance), nil
subnetClientInstance, err := armnetwork.NewSubnetsClient(subscriptionId, cred, nil)

if err != nil {
return nil, err
}

return newClient(armRedisClientInstance, resourceGroupClientInstance, subnetClientInstance), nil
}
}

type redisClient struct {
RedisClient *armRedis.Client
ResourceGroupClient *armResources.ResourceGroupsClient
SubnetClient *armnetwork.SubnetsClient
}

func newClient(armRedisClientInstance *armRedis.Client, resourceGroupClientInstance *armResources.ResourceGroupsClient) Client {
func newClient(armRedisClientInstance *armRedis.Client, resourceGroupClientInstance *armResources.ResourceGroupsClient, subnetClientInstance *armnetwork.SubnetsClient) Client {
return &redisClient{
RedisClient: armRedisClientInstance,
ResourceGroupClient: resourceGroupClientInstance,
SubnetClient: subnetClientInstance,
}
}

Expand Down Expand Up @@ -163,3 +174,34 @@ func (c *redisClient) UpdateRedisInstance(ctx context.Context, resourceGroupName

return nil
}

func (c *redisClient) GetSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string) (*armnetwork.SubnetsClientGetResponse, error) {
logger := composed.LoggerFromCtx(ctx)

subnetClientGetResponse, error := c.SubnetClient.Get(ctx, resourceGroupName, virtualNetworkName, subnetName, nil)

if error != nil {
logger.Error(error, "Failed to get Azure Redis subnet")
return nil, error
}

return &subnetClientGetResponse, nil
}

func (c *redisClient) CreateSubnet(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName, cidr string) error {
logger := composed.LoggerFromCtx(ctx)

subnet := armnetwork.Subnet{
Properties: &armnetwork.SubnetPropertiesFormat{
AddressPrefix: to.Ptr(cidr),
},
}
_, error := c.SubnetClient.BeginCreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, subnetName, subnet, nil)

if error != nil {
logger.Error(error, "Failed to create Azure Redis subnet")
return error
}

return nil
}
1 change: 1 addition & 0 deletions pkg/kcp/provider/azure/redisinstance/createRedis.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func getCreateParams(state *State) armRedis.CreateParameters {
Family: to.Ptr(armRedis.SKUFamilyP),
},
RedisConfiguration: state.ObjAsRedisInstance().Spec.Instance.Azure.RedisConfiguration.GetRedisConfig(),
SubnetID: state.subnet.ID,
}

if state.ObjAsRedisInstance().Spec.Instance.Azure.ShardCount != 0 {
Expand Down
79 changes: 79 additions & 0 deletions pkg/kcp/provider/azure/redisinstance/createSubnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package redisinstance

import (
"context"
"fmt"
"github.com/kyma-project/cloud-manager/api/cloud-control/v1beta1"
"github.com/kyma-project/cloud-manager/pkg/composed"
iprangeallocate "github.com/kyma-project/cloud-manager/pkg/kcp/iprange/allocate"
azureUtil "github.com/kyma-project/cloud-manager/pkg/kcp/provider/azure/util"
"github.com/kyma-project/cloud-manager/pkg/util"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func createSubnet(ctx context.Context, st composed.State) (error, context.Context) {
state := st.(*State)
logger := composed.LoggerFromCtx(ctx)

if state.subnet != nil {
return nil, nil
}

logger.Info("Creating Azure Redis subnet")

resourceGroupName := state.Scope().Spec.Scope.Azure.TechnicalID
virtualNetworkName := state.Scope().Spec.Scope.Azure.VpcNetwork
subnetName := azureUtil.GetSubnetName(state.Scope().Spec.Scope.Azure.TechnicalID)

existingRanges := []string{
state.Scope().Spec.Scope.Azure.Network.Nodes,
state.Scope().Spec.Scope.Azure.Network.Pods,
state.Scope().Spec.Scope.Azure.Network.Services,
}
cidr, error := iprangeallocate.AllocateCidr(25, existingRanges)

if error != nil {
logger.Error(error, "Error creating Azure subnet")
meta.SetStatusCondition(state.ObjAsRedisInstance().Conditions(), metav1.Condition{
Type: v1beta1.ConditionTypeError,
Status: "True",
Reason: v1beta1.ConditionTypeError,
Message: fmt.Sprintf("Failed creating AzureRedis subnet: %s", error),
})
error = state.UpdateObjStatus(ctx)
if error != nil {
return composed.LogErrorAndReturn(error,
"Error updating RedisInstance status due failed azure redis subnet creating",
composed.StopWithRequeueDelay(util.Timing.T10000ms()),
ctx,
)
}

return composed.StopWithRequeueDelay(util.Timing.T60000ms()), nil
}

error = state.client.CreateSubnet(ctx, resourceGroupName, virtualNetworkName, subnetName, cidr)

if error != nil {
logger.Error(error, "Error creating Azure subnet")
meta.SetStatusCondition(state.ObjAsRedisInstance().Conditions(), metav1.Condition{
Type: v1beta1.ConditionTypeError,
Status: "True",
Reason: v1beta1.ConditionTypeError,
Message: fmt.Sprintf("Failed creating AzureRedis subnet: %s", error),
})
error = state.UpdateObjStatus(ctx)
if error != nil {
return composed.LogErrorAndReturn(error,
"Error updating RedisInstance status due failed azure redis subnet creating",
composed.StopWithRequeueDelay(util.Timing.T10000ms()),
ctx,
)
}

return composed.StopWithRequeueDelay(util.Timing.T60000ms()), nil
}

return nil, nil
}
Loading