Skip to content

Commit

Permalink
FEAT: [k8scluster] validate k8snodegroup's naming rule
Browse files Browse the repository at this point in the history
In the case of Azure, dashes are not allowed in node pool names.
For more details, refer to https://aka.ms/aks-naming-rules.
  • Loading branch information
Sooyoung Kim committed Nov 25, 2024
1 parent 0544280 commit 57bf03d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 16 deletions.
2 changes: 2 additions & 0 deletions assets/k8sclusterinfo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# requiredSubnetCount: [required number of subnets to create a kubernetes cluster, default value is 1]
# version:
# - region: [region1, region2, common(special keyword: most of regions)]
# nodeGroupNamingRule: [regular expression or no restriction if empty]
#

k8scluster:
Expand Down Expand Up @@ -41,6 +42,7 @@ k8scluster:
nodeGroupsOnCreation: true
nodeImageDesignation: false
requiredSubnetCount: 1
nodeGroupNamingRule: ^[a-z][a-z0-9]*$
version:
- region: [westeurope,westus]
available:
Expand Down
32 changes: 16 additions & 16 deletions src/api/rest/server/resource/k8scluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func RestPostK8sCluster(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sClusterInfo body model.TbK8sClusterInfo true "Details of the K8sCluster object"
// @Success 200 {object} model.TbK8sClusterInfo
// @Failure 404 {object} model.SimpleMsg
Expand All @@ -207,8 +207,8 @@ func RestPutK8sCluster(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sNodeGroupReq body model.TbK8sNodeGroupReq true "Details of the K8sNodeGroup object" default(ng-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sNodeGroupReq body model.TbK8sNodeGroupReq true "Details of the K8sNodeGroup object" default(nodegroup01)
// @Success 200 {object} model.TbK8sClusterInfo
// @Failure 404 {object} model.SimpleMsg
// @Failure 500 {object} model.SimpleMsg
Expand Down Expand Up @@ -245,8 +245,8 @@ func RestPostK8sNodeGroup(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(k8snodegroup-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(k8snodegroup01)
// @Param option query string false "Option for K8sNodeGroup deletion" Enums(force)
// @Success 200 {object} model.SimpleMsg
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -285,8 +285,8 @@ func RestDeleteK8sNodeGroup(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(ng-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(nodegroup01)
// @Param setK8sNodeGroupAutoscalingReq body model.TbSetK8sNodeGroupAutoscalingReq true "Details of the TbSetK8sNodeGroupAutoscalingReq object"
// @Success 200 {object} model.TbSetK8sNodeGroupAutoscalingRes
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -325,8 +325,8 @@ func RestPutSetK8sNodeGroupAutoscaling(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(ng-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sNodeGroupName path string true "K8sNodeGroup Name" default(nodegroup01)
// @Param changeK8sNodeGroupAutoscaleSizeReq body model.TbChangeK8sNodeGroupAutoscaleSizeReq true "Details of the TbChangeK8sNodeGroupAutoscaleSizeReq object"
// @Success 200 {object} model.TbChangeK8sNodeGroupAutoscaleSizeRes
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -365,7 +365,7 @@ func RestPutChangeK8sNodeGroupAutoscaleSize(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Success 200 {object} model.TbK8sClusterInfo
// @Failure 404 {object} model.SimpleMsg
// @Failure 500 {object} model.SimpleMsg
Expand Down Expand Up @@ -448,7 +448,7 @@ func RestGetAllK8sCluster(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param option query string false "Option for K8sCluster deletion" Enums(force)
// @Success 200 {object} model.SimpleMsg
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -516,7 +516,7 @@ func RestDeleteAllK8sCluster(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param upgradeK8sClusterReq body model.TbUpgradeK8sClusterReq true "Details of the TbUpgradeK8sClusterReq object"
// @Success 200 {object} model.SimpleMsg
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -576,7 +576,7 @@ func RestPostK8sClusterDynamicCheckRequest(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterDyanmicReq body model.TbK8sClusterDynamicReq true "Request body to provision K8sCluster dynamically. <br> Must include commonSpec and commonImage info. <br> (ex: {name: k8scluster-01, commonImage: azure+koreacentral+ubuntu22.04, commonSpec: azure+koreacentral+Standard_B2s}]}) <br> You can use /k8sClusterRecommendNode and /k8sClusterDynamicCheckRequest to get it. <br> Check the guide: https://github.com/cloud-barista/cb-tumblebug/discussions/1913"
// @Param k8sClusterDyanmicReq body model.TbK8sClusterDynamicReq true "Request body to provision K8sCluster dynamically. <br> Must include commonSpec and commonImage info. <br> (ex: {name: k8scluster01, commonImage: azure+koreacentral+ubuntu22.04, commonSpec: azure+koreacentral+Standard_B2s}]}) <br> You can use /k8sClusterRecommendNode and /k8sClusterDynamicCheckRequest to get it. <br> Check the guide: https://github.com/cloud-barista/cb-tumblebug/discussions/1913"
// @Param option query string false "Option for K8sCluster creation" Enums(hold)
// @Param x-request-id header string false "Custom request ID"
// @Success 200 {object} model.TbK8sClusterInfo
Expand Down Expand Up @@ -611,8 +611,8 @@ func RestPostK8sClusterDynamic(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sNodeGroupDynamicReq body model.TbK8sNodeGroupDynamicReq true "Request body to provision K8sNodeGroup dynamically. <br> Must include commonSpec and commonImage info. <br> (ex: {name: k8snodegroup-01, commonImage: azure+koreacentral+ubuntu22.04, commonSpec: azure+koreacentral+Standard_B2s}]}) <br> You can use /k8sClusterRecommendNode and /k8sClusterDynamicCheckRequest to get it. <br> Check the guide: https://github.com/cloud-barista/cb-tumblebug/discussions/1913"
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param k8sNodeGroupDynamicReq body model.TbK8sNodeGroupDynamicReq true "Request body to provision K8sNodeGroup dynamically. <br> Must include commonSpec and commonImage info. <br> (ex: {name: k8snodegroup01, commonImage: azure+koreacentral+ubuntu22.04, commonSpec: azure+koreacentral+Standard_B2s}]}) <br> You can use /k8sClusterRecommendNode and /k8sClusterDynamicCheckRequest to get it. <br> Check the guide: https://github.com/cloud-barista/cb-tumblebug/discussions/1913"
// @Param x-request-id header string false "Custom request ID"
// @Success 200 {object} model.TbK8sNodeGroupInfo
// @Failure 404 {object} model.SimpleMsg
Expand Down Expand Up @@ -647,7 +647,7 @@ func RestPostK8sNodeGroupDynamic(c echo.Context) error {
// @Accept json
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster-01)
// @Param k8sClusterId path string true "K8sCluster ID" default(k8scluster01)
// @Param action query string true "Action to K8sCluster" Enums(continue, withdraw)
// @Success 200 {object} model.SimpleMsg
// @Failure 404 {object} model.SimpleMsg
Expand Down
38 changes: 38 additions & 0 deletions src/core/common/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,44 @@ func GetModelK8sRequiredSubnetCount(providerName string) (*model.K8sClusterRequi
}, nil
}

const DefaultNamingRule = "^.*$" // Wildcard Pattern

// GetK8sNodeGroupNamingRule is func to get nodegroup's naming rule
func GetK8sNodeGroupNamingRule(providerName string) (string, error) {
//
// Get nodeGroupNamingRule field in k8sclusterinfo.yaml
//

providerName = strings.ToLower(providerName)

// Get model.K8sClusterDetail for providerName
k8sClusterDetail := getK8sClusterDetail(providerName)
if k8sClusterDetail == nil {
return "", fmt.Errorf("unsupported provider(%s) for kubernetes cluster", providerName)
}

namingRule := k8sClusterDetail.NodeGroupNamingRule
if strings.EqualFold(namingRule, "") {
namingRule = DefaultNamingRule
}

return namingRule, nil
}

/*
// GetModelK8sK8sNodeGroupNamingRule is to convert a K8sNodeGroupNamingRule value to model.K8sClusterK8sNodeGroupNamingRule
func GetModelK8sNodeGroupNamingRule(providerName string) (*model.K8sClusterNodeGroupsOnCreation, error) {
k8sNodeGroupNamingRule, err := GetK8sNodeGroupNamingRule(providerName)
if err != nil {
return nil, err
}
return &model.K8sClusterNodeGroupsOnCreation{
Result: k8sNodeGroupNamingRule,
}, nil
}
*/

func FilterDigitsAndDots(input string) string {
re := regexp.MustCompile(`[^0-9.]`)
return re.ReplaceAllString(input, "")
Expand Down
1 change: 1 addition & 0 deletions src/core/model/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type K8sClusterDetail struct {
NodeGroupsOnCreation bool `mapstructure:"nodeGroupsOnCreation" json:"nodegroups_on_creation"`
NodeImageDesignation bool `mapstructure:"nodeImageDesignation" json:"node_image_designation"`
RequiredSubnetCount int `mapstructure:"requiredSubnetCount" json:"required_subnet_count"`
NodeGroupNamingRule string `mapstructure:"nodeGroupNamingRule" json:"nodegroup_naming_rule"`
Version []K8sClusterVersionDetail `mapstructure:"version" json:"versions"`
NodeImage []K8sClusterNodeImageDetail `mapstructure:"nodeImage" json:"node_images"`
RootDisk []K8sClusterRootDiskDetail `mapstructure:"rootDisk" json:"root_disks"`
Expand Down
19 changes: 19 additions & 0 deletions src/core/resource/k8scluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"encoding/json"
"fmt"
"reflect"
"regexp"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -1399,6 +1400,24 @@ func validateAtCreateK8sCluster(tbK8sClusterReq *model.TbK8sClusterReq) error {
}
}

// Validate K8sNodeGroup's Naming Rule
k8sNgNamingRule, err := common.GetK8sNodeGroupNamingRule(connConfig.ProviderName)
if err != nil {
log.Err(err).Msgf("Failed to Get Nodegroup's Naming Rule")
return err
}

if len(tbK8sClusterReq.K8sNodeGroupList) > 0 {
re := regexp.MustCompile(k8sNgNamingRule)
for _, ng := range tbK8sClusterReq.K8sNodeGroupList {
if re.MatchString(ng.Name) == false {
err := fmt.Errorf("K8sNodeGroup's Name(%s) should be match regular expression(%s)", ng.Name, k8sNgNamingRule)
log.Err(err).Msgf("Provider(%s)", connConfig.ProviderName)
return err
}
}
}

return nil
}

Expand Down

0 comments on commit 57bf03d

Please sign in to comment.