Skip to content

Commit

Permalink
Add max and min expiration time (#1255)
Browse files Browse the repository at this point in the history
* Add max expiration time

* Update deloyment

* Update docs

* Update docs

* Fix formatting

* Update docs
  • Loading branch information
MarekMichali authored Oct 4, 2024
1 parent 78f7595 commit d4ddae9
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 20 deletions.
2 changes: 1 addition & 1 deletion docs/user/05-60-kyma-bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ The Broker returns a kubeconfig file in the response body. The kubeconfig file c
| Name | Default | Description |
|------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **service_account** | `false` | If set to `true`, the Broker returns a kubeconfig with a JWT token used as a user authentication mechanism. The token is generated using Kubernetes TokenRequest attached to a ServiceAccount, ClusterRole, and ClusterRoleBinding, all named `kyma-binding-{{binding_id}}`. Such an approach allows for easily modifying the permissions granted to the kubeconfig. |
| **expiration_seconds** | `600` | Specifies the duration (in seconds) for which the generated kubeconfig is valid. If not provided, the default value of `600` seconds (10 minutes) is used. |
| **expiration_seconds** | `600` | Specifies the duration (in seconds) for which the generated kubeconfig is valid. If not provided, the default value of `600` seconds (10 minutes) is used, which is also the minimum value that can be set. The maximum value that can be set is `7200` seconds (2 hours). |
16 changes: 13 additions & 3 deletions internal/broker/bind_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import (
)

type BindingConfig struct {
Enabled bool `envconfig:"default=false"`
BindablePlans EnablePlans `envconfig:"default=aws"`
ExpirationSeconds int `envconfig:"default=600"`
Enabled bool `envconfig:"default=false"`
BindablePlans EnablePlans `envconfig:"default=aws"`
ExpirationSeconds int `envconfig:"default=600"`
MaxExpirationSeconds int `envconfig:"default=7200"`
MinExpirationSeconds int `envconfig:"default=600"`
}

type BindEndpoint struct {
Expand Down Expand Up @@ -98,6 +100,14 @@ func (b *BindEndpoint) Bind(ctx context.Context, instanceID, bindingID string, d

expirationSeconds := b.config.ExpirationSeconds
if parameters.ExpirationSeconds != 0 {
if parameters.ExpirationSeconds > b.config.MaxExpirationSeconds {
message := fmt.Sprintf("expiration_seconds cannot be greater than %d", b.config.MaxExpirationSeconds)
return domain.Binding{}, apiresponses.NewFailureResponse(fmt.Errorf(message), http.StatusBadRequest, message)
}
if parameters.ExpirationSeconds < b.config.MinExpirationSeconds {
message := fmt.Sprintf("expiration_seconds cannot be less than %d", b.config.MinExpirationSeconds)
return domain.Binding{}, apiresponses.NewFailureResponse(fmt.Errorf(message), http.StatusBadRequest, message)
}
expirationSeconds = parameters.ExpirationSeconds
}

Expand Down
70 changes: 54 additions & 16 deletions internal/broker/bind_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type User struct {
}

const expirationSeconds = 10000
const maxExpirationSeconds = 7200
const minExpirationSeconds = 600

func TestCreateBindingEndpoint(t *testing.T) {
t.Log("test create binding endpoint")
Expand Down Expand Up @@ -153,7 +155,9 @@ func TestCreateBindingEndpoint(t *testing.T) {
BindablePlans: EnablePlans{
fixture.PlanName,
},
ExpirationSeconds: expirationSeconds,
ExpirationSeconds: expirationSeconds,
MaxExpirationSeconds: maxExpirationSeconds,
MinExpirationSeconds: minExpirationSeconds,
}

//// api handler
Expand Down Expand Up @@ -181,13 +185,14 @@ func TestCreateBindingEndpoint(t *testing.T) {
t.Run("should create a new service binding without error", func(t *testing.T) {

// When
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id?accepts_incomplete=true", fmt.Sprintf(`{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true
}
}`, fixture.PlanId), t)
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id?accepts_incomplete=true", fmt.Sprintf(`
{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true
}
}`, fixture.PlanId), t)

binding := verifyResponse(t, response)

Expand Down Expand Up @@ -216,14 +221,15 @@ func TestCreateBindingEndpoint(t *testing.T) {
const customExpirationSeconds = 900

// When
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id2?accepts_incomplete=true", fmt.Sprintf(`{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true,
"expiration_seconds": %v
}
}`, fixture.PlanId, customExpirationSeconds), t)
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id2?accepts_incomplete=true", fmt.Sprintf(`
{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true,
"expiration_seconds": %v
}
}`, fixture.PlanId, customExpirationSeconds), t)

binding := verifyResponse(t, response)

Expand All @@ -234,6 +240,38 @@ func TestCreateBindingEndpoint(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, customExpirationSeconds*time.Second, duration)
})
t.Run("should return error when expiration_seconds is greater than maxExpirationSeconds", func(t *testing.T) {
const customExpirationSeconds = 7201

// When
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id3?accepts_incomplete=true", fmt.Sprintf(`
{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true,
"expiration_seconds": %v
}
}`, fixture.PlanId, customExpirationSeconds), t)
require.Equal(t, http.StatusBadRequest, response.StatusCode)
})

t.Run("should return error when expiration_seconds is less than minExpirationSeconds", func(t *testing.T) {
const customExpirationSeconds = 60

// When
response := CallAPI(httpServer, method, "v2/service_instances/1/service_bindings/binding-id4?accepts_incomplete=true", fmt.Sprintf(`
{
"service_id": "123",
"plan_id": "%s",
"parameters": {
"service_account": true,
"expiration_seconds": %v
}
}`, fixture.PlanId, customExpirationSeconds), t)
require.Equal(t, http.StatusBadRequest, response.StatusCode)
})
}

func createKubeconfigFileForRestConfig(restConfig rest.Config) []byte {
Expand Down
6 changes: 6 additions & 0 deletions resources/keb/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ spec:
value: "{{ .Values.cleaning.dryRun }}"
- name: APP_BROKER_BINDING_ENABLED
value: "{{ .Values.binding.enabled}}"
- name: APP_BROKER_BINDING_BINDABLE_PLANS
value: "{{ .Values.binding.bindablePlans}}"
- name: APP_BROKER_BINDING_EXPIRATION_SECONDS
value: "{{ .Values.binding.expirationSeconds}}"
- name: APP_BROKER_BINDING_MAX_EXPIRATION_SECONDS
value: "{{ .Values.binding.maxExpirationSeconds}}"
- name: APP_BROKER_ONLY_SINGLE_TRIAL_PER_GA
value: "{{ .Values.onlySingleTrialPerGA }}"
- name: APP_BROKER_URL
Expand Down
5 changes: 5 additions & 0 deletions resources/keb/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ broker:

binding:
enabled: false
bindablePlans: "aws"
expirationSeconds: 600
maxExpirationSeconds: 7200
# minExpirationSeconds can't be lower than 600 seconds. Forced by Gardener
minExpirationSeconds: 600

service:
type: ClusterIP
Expand Down

0 comments on commit d4ddae9

Please sign in to comment.