Skip to content

Commit

Permalink
feat(web): support custom replicas value on instance creation
Browse files Browse the repository at this point in the history
  • Loading branch information
nettoclaudio committed Aug 5, 2022
1 parent db51446 commit a5bdcee
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 98 deletions.
2 changes: 2 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type RpaasConfig struct {
MultiCluster bool `json:"multi-cluster"`
NamespacedInstances bool `json:"namespaced-instances"`
EnableCertManager bool `json:"enable-cert-manager"`
NewInstanceReplicas int `json:"new-instance-replicas"`
}

type ClusterConfig struct {
Expand Down Expand Up @@ -107,6 +108,7 @@ func Init() error {
viper.SetDefault("websocket-max-idle-time", 60*time.Second)
viper.SetDefault("websocket-write-wait", time.Second)
viper.SetDefault("enable-cert-manager", false)
viper.SetDefault("new-instance-replicas", 1)
viper.AutomaticEnv()
err := readConfig()
if err != nil {
Expand Down
157 changes: 61 additions & 96 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,67 +22,45 @@ func Test_Init(t *testing.T) {
tests := []struct {
config string
envs map[string]string
expected RpaasConfig
expected func(c RpaasConfig) RpaasConfig
}{
{},
{
expected: RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: 1 * time.Minute,
WebSocketWriteWait: time.Second,
config: `
new-instance-replicas: 5
`,
expected: func(c RpaasConfig) RpaasConfig {
c.NewInstanceReplicas = 5
return c
},
},
{
config: `
sync-interval: 2m
`,
expected: RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 2 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
expected: func(c RpaasConfig) RpaasConfig {
c.SyncInterval = 2 * time.Minute
return c
},
},
{
config: `
tls-certificate: /var/share/tls/mycert.pem
tls-key: /var/share/tls/key.pem
`,
expected: RpaasConfig{
ServiceName: "rpaasv2",
TLSCertificate: "/var/share/tls/mycert.pem",
TLSKey: "/var/share/tls/key.pem",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
expected: func(c RpaasConfig) RpaasConfig {
c.TLSCertificate = "/var/share/tls/mycert.pem"
c.TLSKey = "/var/share/tls/key.pem"
return c
},
},
{
config: `
api-username: u1
`,
expected: RpaasConfig{
APIUsername: "u1",
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
expected: func(c RpaasConfig) RpaasConfig {
c.APIUsername = "u1"
return c
},
},
{
Expand All @@ -94,17 +72,11 @@ service-name: rpaasv2be
"RPAASV2_API_USERNAME": "u1",
"RPAASV2_API_PASSWORD": "p1",
},
expected: RpaasConfig{
APIUsername: "u1",
APIPassword: "p1",
ServiceName: "rpaasv2be",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
expected: func(c RpaasConfig) RpaasConfig {
c.APIUsername = "u1"
c.APIPassword = "p1"
c.ServiceName = "rpaasv2be"
return c
},
},
{
Expand All @@ -114,15 +86,9 @@ service-name: ignored-service-name
envs: map[string]string{
"RPAASV2_SERVICE_NAME": "my-custom-service-name",
},
expected: RpaasConfig{
ServiceName: "my-custom-service-name",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
expected: func(c RpaasConfig) RpaasConfig {
c.ServiceName = "my-custom-service-name"
return c
},
},
{
Expand All @@ -147,16 +113,8 @@ team-affinity:
values:
- dev
`,
expected: RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
DefaultAffinity: &corev1.Affinity{
expected: func(c RpaasConfig) RpaasConfig {
c.DefaultAffinity = &corev1.Affinity{
NodeAffinity: &corev1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
NodeSelectorTerms: []corev1.NodeSelectorTerm{
Expand All @@ -172,8 +130,8 @@ team-affinity:
},
},
},
},
TeamAffinity: map[string]corev1.Affinity{
}
c.TeamAffinity = map[string]corev1.Affinity{
"team1": {
NodeAffinity: &corev1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
Expand All @@ -191,23 +149,17 @@ team-affinity:
},
},
},
},
}
return c
},
},
{
config: `
loadbalancer-name-label-key: my.cloudprovider.example.com/lb-name
`,
expected: RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: time.Minute,
WebSocketWriteWait: time.Second,
LoadBalancerNameLabelKey: "my.cloudprovider.example.com/lb-name",
expected: func(c RpaasConfig) RpaasConfig {
c.LoadBalancerNameLabelKey = "my.cloudprovider.example.com/lb-name"
return c
},
},
{
Expand All @@ -225,20 +177,19 @@ config-deny-patterns:
- pattern1.*
- pattern2.*
`,
expected: RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: time.Minute,
WebSocketReadBufferSize: 8192,
WebSocketWriteBufferSize: 8192,
WebSocketPingInterval: 500 * time.Millisecond,
WebSocketMaxIdleTime: 5 * time.Second,
WebSocketWriteWait: 5 * time.Second,
WebSocketAllowedOrigins: []string{"rpaasv2.example.com", "rpaasv2.test"},
ConfigDenyPatterns: []regexp.Regexp{
expected: func(c RpaasConfig) RpaasConfig {
c.WebSocketHandshakeTimeout = time.Minute
c.WebSocketReadBufferSize = 8192
c.WebSocketWriteBufferSize = 8192
c.WebSocketPingInterval = 500 * time.Millisecond
c.WebSocketMaxIdleTime = 5 * time.Second
c.WebSocketWriteWait = 5 * time.Second
c.WebSocketAllowedOrigins = []string{"rpaasv2.example.com", "rpaasv2.test"}
c.ConfigDenyPatterns = []regexp.Regexp{
*regexp.MustCompile(`pattern1.*`),
*regexp.MustCompile(`pattern2.*`),
},
}
return c
},
},
}
Expand All @@ -260,7 +211,21 @@ config-deny-patterns:
err = Init()
require.NoError(t, err)
config := Get()
assert.Equal(t, tt.expected, config)
expected := RpaasConfig{
ServiceName: "rpaasv2",
SyncInterval: 5 * time.Minute,
WebSocketHandshakeTimeout: 5 * time.Second,
WebSocketReadBufferSize: 1024,
WebSocketWriteBufferSize: 4096,
WebSocketPingInterval: 2 * time.Second,
WebSocketMaxIdleTime: 1 * time.Minute,
WebSocketWriteWait: time.Second,
NewInstanceReplicas: 1,
}
if tt.expected != nil {
expected = tt.expected(expected)
}
assert.Equal(t, expected, config)
})
}
}
7 changes: 6 additions & 1 deletion internal/pkg/rpaas/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,15 @@ func (m *k8sRpaasManager) CreateInstance(ctx context.Context, args CreateArgs) e
return err
}

replicas := func(n int32) *int32 { return &n }(1)
if r := config.Get().NewInstanceReplicas; r > 0 {
replicas = func(n int32) *int32 { return &n }(int32(r))
}

instance := newRpaasInstance(args.Name)
instance.Namespace = nsName
instance.Spec = v1alpha1.RpaasInstanceSpec{
Replicas: func(n int32) *int32 { return &n }(int32(1)),
Replicas: replicas,
PlanName: plan.Name,
Flavors: args.Flavors(),
Service: &nginxv1alpha1.NginxService{
Expand Down
52 changes: 51 additions & 1 deletion internal/pkg/rpaas/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2565,7 +2565,6 @@ func Test_k8sRpaasManager_CreateInstance(t *testing.T) {
}{
{
name: "without name",
args: CreateArgs{},
expectedError: `name is required`,
},
{
Expand Down Expand Up @@ -2652,6 +2651,56 @@ func Test_k8sRpaasManager_CreateInstance(t *testing.T) {
},
},
},
{
name: "w/ custom number of replicas",
args: CreateArgs{Name: "r1", Team: "t1"},
extraConfig: config.RpaasConfig{NewInstanceReplicas: 3},
expected: v1alpha1.RpaasInstance{
TypeMeta: metav1.TypeMeta{
Kind: "RpaasInstance",
APIVersion: "extensions.tsuru.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "r1",
Namespace: "rpaasv2",
ResourceVersion: "1",
Annotations: map[string]string{
"rpaas.extensions.tsuru.io/description": "",
"rpaas.extensions.tsuru.io/tags": "",
"rpaas.extensions.tsuru.io/team-owner": "t1",
},
Labels: map[string]string{
"rpaas.extensions.tsuru.io/service-name": "rpaasv2",
"rpaas.extensions.tsuru.io/instance-name": "r1",
"rpaas.extensions.tsuru.io/team-owner": "t1",
"rpaas_service": "rpaasv2",
"rpaas_instance": "r1",
},
},
Spec: v1alpha1.RpaasInstanceSpec{
Replicas: func(n int32) *int32 { return &n }(3),
PlanName: "plan1",
Service: &nginxv1alpha1.NginxService{
Labels: map[string]string{
"rpaas.extensions.tsuru.io/service-name": "rpaasv2",
"rpaas.extensions.tsuru.io/instance-name": "r1",
"rpaas.extensions.tsuru.io/team-owner": "t1",
"rpaas_service": "rpaasv2",
"rpaas_instance": "r1",
},
},
PodTemplate: nginxv1alpha1.NginxPodTemplateSpec{
Labels: map[string]string{
"rpaas.extensions.tsuru.io/service-name": "rpaasv2",
"rpaas.extensions.tsuru.io/instance-name": "r1",
"rpaas.extensions.tsuru.io/team-owner": "t1",
"rpaas_service": "rpaasv2",
"rpaas_instance": "r1",
},
},
},
},
},
{
name: "multi-cluster",
args: CreateArgs{Name: "r1", Team: "t1"},
Expand Down Expand Up @@ -3051,6 +3100,7 @@ func Test_k8sRpaasManager_CreateInstance(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
baseConfig := config.RpaasConfig{
NewInstanceReplicas: 1,
ServiceName: "rpaasv2",
LoadBalancerNameLabelKey: "cloudprovider.example/lb-name",
TeamAffinity: map[string]corev1.Affinity{
Expand Down

0 comments on commit a5bdcee

Please sign in to comment.