Skip to content

Commit

Permalink
Several improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dkistner committed May 20, 2022
1 parent 6c127d7 commit 119edf9
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 41 deletions.
18 changes: 17 additions & 1 deletion hack/api-reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Kubernetes meta/v1.Duration
<p>Lifetime define how long a managed application credentials are valid.
Once the creation time + lifetime of an application credential is expired
it will be renewed once it is next reconciled.
Defaults to 24h.</p>
Defaults to 48h.</p>
</td>
</tr>
<tr>
Expand All @@ -165,6 +165,22 @@ The expiration time will be calculated in the following way:</p>
get deactivated even if the owning user of the application credential
is not available to the openstack-extension anymore and therefore
cannot be removed by the openstack-extension on its own.
Defaults to 720h = 30d.</p>
</td>
</tr>
<tr>
<td>
<code>renewThreshold</code></br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/#duration-v1-meta">
Kubernetes meta/v1.Duration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>RenewThreshold defines a threshold before the openstack expiration time.
Once the threshold is reached the managed application credential need to be renewed.
Defaults to 72h.</p>
</td>
</tr>
Expand Down
8 changes: 6 additions & 2 deletions pkg/apis/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type ApplicationCredentialConfig struct {
// Lifetime define how long a managed application credentials are valid.
// Once the creation time + lifetime of an application credential is expired
// it will be renewed once it is next reconciled.
// Defaults to 24h.
// Defaults to 84h.
Lifetime *metav1.Duration
// OpenstackExpirationPeriod is a duration to calculate the expiration time
// of a managed application credential on the Openstack layer.
Expand All @@ -80,6 +80,10 @@ type ApplicationCredentialConfig struct {
// get deactivated even if the owning user of the application credential
// is not available to the openstack-extension anymore and therefore
// cannot be removed by the openstack-extension on its own.
// Defaults to 72h.
// Defaults to 720h = 30d.
OpenstackExpirationPeriod *metav1.Duration
// RenewThreshold defines a threshold before the openstack expiration time.
// Once the threshold is reached the managed application credential need to be renewed.
// Defaults to 72h.
RenewThreshold *metav1.Duration
}
5 changes: 3 additions & 2 deletions pkg/apis/config/v1alpha1/default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ var _ = Describe("Defaults", func() {
It("should default the application crendential config", func() {
SetDefaults_ApplicationCrendentialConfig(obj)

Expect(*obj.Lifetime).To(Equal(metav1.Duration{Duration: time.Hour * 24}))
Expect(*obj.OpenstackExpirationPeriod).To(Equal(metav1.Duration{Duration: time.Hour * 48}))
Expect(*obj.Lifetime).To(Equal(metav1.Duration{Duration: time.Hour * 48}))
Expect(*obj.OpenstackExpirationPeriod).To(Equal(metav1.Duration{Duration: time.Hour * 24 * 30}))
Expect(*obj.RenewThreshold).To(Equal(metav1.Duration{Duration: time.Hour * 24 * 3}))
})
})

Expand Down
8 changes: 7 additions & 1 deletion pkg/apis/config/v1alpha1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ func SetDefaults_ControllerConfiguration(obj *ControllerConfiguration) {
func SetDefaults_ApplicationCrendentialConfig(obj *ApplicationCredentialConfig) {
if obj.Lifetime == nil {
obj.Lifetime = &metav1.Duration{
Duration: time.Hour * 24,
Duration: time.Hour * 48,
}
}

if obj.OpenstackExpirationPeriod == nil {
obj.OpenstackExpirationPeriod = &metav1.Duration{
Duration: time.Hour * 720,
}
}

if obj.RenewThreshold == nil {
obj.RenewThreshold = &metav1.Duration{
Duration: time.Hour * 72,
}
}
Expand Down
9 changes: 7 additions & 2 deletions pkg/apis/config/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type ApplicationCredentialConfig struct {
// Lifetime define how long a managed application credentials are valid.
// Once the creation time + lifetime of an application credential is expired
// it will be renewed once it is next reconciled.
// Defaults to 24h.
// Defaults to 48h.
// +optional
Lifetime *metav1.Duration `json:"lifetime,omitempty"`
// OpenstackExpirationPeriod is a duration to calculate the expiration time
Expand All @@ -64,9 +64,14 @@ type ApplicationCredentialConfig struct {
// get deactivated even if the owning user of the application credential
// is not available to the openstack-extension anymore and therefore
// cannot be removed by the openstack-extension on its own.
// Defaults to 72h.
// Defaults to 720h = 30d.
// +optional
OpenstackExpirationPeriod *metav1.Duration `json:"openstackExpirationPeriod,omitempty"`
// RenewThreshold defines a threshold before the openstack expiration time.
// Once the threshold is reached the managed application credential need to be renewed.
// Defaults to 72h.
// +optional
RenewThreshold *metav1.Duration `json:"renewThreshold,omitempty"`
}

// ETCD is an etcd configuration.
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/config/v1alpha1/zz_generated.conversion.go

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

5 changes: 5 additions & 0 deletions pkg/apis/config/v1alpha1/zz_generated.deepcopy.go

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

5 changes: 5 additions & 0 deletions pkg/apis/config/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion pkg/internal/managedappcredential/manager_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

// Delete deletes the managed application credentials of an Openstack Shoot cluster.
func (m *Manager) Delete(ctx context.Context, credentials *openstack.Credentials) error {
newParentUser, err := m.newParentFromCredetials(credentials)
newParentUser, err := m.newParentFromCredentials(credentials)
if err != nil {
return err
}
Expand Down
27 changes: 23 additions & 4 deletions pkg/internal/managedappcredential/manager_ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ import (
"github.com/gardener/gardener/pkg/utils"
)

// Ensure will ensure the managed application credential of an Openstack Shoot cluster.
func (m *Manager) Ensure(ctx context.Context, credentials *openstack.Credentials) error {
newParentUser, err := m.newParentFromCredetials(credentials)
newParentUser, err := m.newParentFromCredentials(credentials)
if err != nil {
return err
}
Expand Down Expand Up @@ -141,9 +142,7 @@ func (m *Manager) Ensure(ctx context.Context, credentials *openstack.Credentials
return m.storeApplicationCredential(ctx, newAppCredential, newParentUser)
}

// Check if the in-use application credential has been expired.
if time.Now().UTC().After(appCredential.creationTime.Add(m.config.Lifetime.Duration)) {
fmt.Println("app credential is expired", appCredential.id)
if m.isExpired(appCredential) {
newAppCredential, err := m.createApplicationCredential(ctx, newParentUser)
if err != nil {
return err
Expand All @@ -155,6 +154,26 @@ func (m *Manager) Ensure(ctx context.Context, credentials *openstack.Credentials
return m.storeApplicationCredential(ctx, appCredential, newParentUser)
}

func (m *Manager) isExpired(appCredential *applicationCredential) bool {
var (
now = time.Now().UTC()
creationTime = appCredential.creationTime
lifetime = creationTime.Add(m.config.Lifetime.Duration)
openstackExpirationTime = creationTime.Add(m.config.OpenstackExpirationPeriod.Duration)
renewThreshold = openstackExpirationTime.Add(-m.config.RenewThreshold.Duration)
)

if now.After(renewThreshold) {
return true
}

if now.After(lifetime) {
return true
}

return false
}

func (m *Manager) createApplicationCredential(ctx context.Context, parent *parent) (*applicationCredential, error) {
randomNamePart, err := utils.GenerateRandomString(8)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/internal/managedappcredential/parent.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
corev1 "k8s.io/api/core/v1"
)

func (m *Manager) newParentFromCredetials(credentials *openstack.Credentials) (*parent, error) {
func (m *Manager) newParentFromCredentials(credentials *openstack.Credentials) (*parent, error) {
factory, err := m.openstackClientFactory.NewFactory(credentials)
if err != nil {
return nil, err
Expand All @@ -46,7 +46,7 @@ func (m *Manager) newParentFromCredetials(credentials *openstack.Credentials) (*
}

func (m *Manager) newParentFromSecret(secret *corev1.Secret) (*parent, error) {
return m.newParentFromCredetials(&openstack.Credentials{
return m.newParentFromCredentials(&openstack.Credentials{
DomainName: readSecretKey(secret, openstack.DomainName),
TenantName: readSecretKey(secret, openstack.TenantName),
Password: readSecretKey(secret, applicationCredentialSecretParentSecret),
Expand Down
6 changes: 1 addition & 5 deletions pkg/internal/managedappcredential/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,7 @@ func (m *Manager) updateParentPasswordIfRequired(ctx context.Context, appCredent
patch := client.MergeFrom(appCredential.secret.DeepCopy())
appCredential.secret.Data[applicationCredentialSecretParentSecret] = []byte(newParent.secret)

if err := m.client.Patch(ctx, appCredential.secret, patch); err != nil {
return err
}

return nil
return m.client.Patch(ctx, appCredential.secret, patch)
}

func readSecretKey(secret *corev1.Secret, key string) string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
)

// Get will return an application credential based a given id and on the id of
// GetApplicationCredential will return an application credential based a given id and on the id of
// the parent user/application credential to which the application credential belongs to.
func (c *IdentityClient) GetApplicationCredential(ctx context.Context, parentUserID, applicationCredentialID string) (*applicationcredentials.ApplicationCredential, error) {
return applicationcredentials.Get(c.client, parentUserID, applicationCredentialID).Extract()
Expand All @@ -41,34 +41,18 @@ func (c *IdentityClient) ListApplicationCredentials(ctx context.Context, parentU
// a given parent user/application credential with a randomized name based on a given cluster name.
func (c *IdentityClient) CreateApplicationCredential(ctx context.Context, parentUserID, name, description, expirationTime string) (*applicationcredentials.ApplicationCredential, error) {
return applicationcredentials.Create(c.client, parentUserID, applicationcredentials.CreateOpts{
Name: name,
Description: description,
Unrestricted: false,
ExpiresAt: expirationTime,
Name: name,
Description: description,
ExpiresAt: expirationTime,
}).Extract()
}

// Delete will delete an application credential based a given id and on the id of
// DeleteApplicationCredential will delete an application credential based a given id and on the id of
// the parent user/application credential to which the application credential belongs to.
func (c *IdentityClient) DeleteApplicationCredential(ctx context.Context, parentUserID, applicationCredentialID string) error {
return applicationcredentials.Delete(c.client, parentUserID, applicationCredentialID).ExtractErr()
}

// LookupClientUserID will try to lookup the id of the user that configure the identity client.
func (c *IdentityClient) LookupClientUserID() (string, error) {
result := tokens.Get(c.client, c.client.Token())
if result.Err != nil {
return "", result.Err
}

user, err := result.ExtractUser()
if err != nil {
return "", err
}

return user.ID, nil
}

// GetClientUser return information about the keystone user which is used
// to configure the identiy client. This will contain information like
// the user id, name and the domain the user is associated to.
Expand Down
1 change: 1 addition & 0 deletions pkg/openstack/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ type Networking interface {
GetExternalNetworkNames(ctx context.Context) ([]string, error)
}

// Identity describes the operations of a client interacting with OpenStack's Identity/Keystone service.
type Identity interface {
GetApplicationCredential(ctx context.Context, parentUserID, applicationCredentialID string) (*applicationcredentials.ApplicationCredential, error)
ListApplicationCredentials(ctx context.Context, parentUserID string) ([]applicationcredentials.ApplicationCredential, error)
Expand Down

0 comments on commit 119edf9

Please sign in to comment.