Skip to content

Commit

Permalink
create application profile definition builder
Browse files Browse the repository at this point in the history
  • Loading branch information
jcollins-axway committed Jan 28, 2025
1 parent 120c07f commit 5432001
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 2 deletions.
57 changes: 57 additions & 0 deletions pkg/agent/cache/applicationprofiledefinitions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cache

import v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1"

// Access Request Definition cache management

// AddApplicationProfileDefinition - add/update ApplicationProfileDefinition resource in cache
func (c *cacheManager) AddApplicationProfileDefinition(resource *v1.ResourceInstance) {
defer c.setCacheUpdated(true)

c.ardMap.SetWithSecondaryKey(resource.Metadata.ID, resource.Name, resource)
}

// GetApplicationProfileDefinitionKeys - returns keys for ApplicationProfileDefinition cache
func (c *cacheManager) GetApplicationProfileDefinitionKeys() []string {
c.ApplyResourceReadLock()
defer c.ReleaseResourceReadLock()

return c.ardMap.GetKeys()
}

// GetApplicationProfileDefinitionByName - returns resource from ApplicationProfileDefinition cache based on resource name
func (c *cacheManager) GetApplicationProfileDefinitionByName(name string) (*v1.ResourceInstance, error) {
c.ApplyResourceReadLock()
defer c.ReleaseResourceReadLock()

item, err := c.ardMap.GetBySecondaryKey(name)
if item != nil {
if ard, ok := item.(*v1.ResourceInstance); ok {
ard.CreateHashes()
return ard, nil
}
}
return nil, err
}

// GetApplicationProfileDefinitionByID - returns resource from ApplicationProfileDefinition cache based on resource id
func (c *cacheManager) GetApplicationProfileDefinitionByID(id string) (*v1.ResourceInstance, error) {
c.ApplyResourceReadLock()
defer c.ReleaseResourceReadLock()

item, err := c.ardMap.Get(id)
if item != nil {
if ard, ok := item.(*v1.ResourceInstance); ok {
ard.CreateHashes()
return ard, nil
}
}
return nil, err
}

// DeleteApplicationProfileDefinition - deletes the ApplicationProfileDefinition cache based on resource id
func (c *cacheManager) DeleteApplicationProfileDefinition(id string) error {
defer c.setCacheUpdated(true)

return c.ardMap.Delete(id)
}
7 changes: 7 additions & 0 deletions pkg/agent/cache/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ type Manager interface {
GetAccessControlList() *v1.ResourceInstance
DeleteAccessControlList() error

// ApplicationProfileDefinition cache related methods
AddApplicationProfileDefinition(resource *v1.ResourceInstance)
GetApplicationProfileDefinitionKeys() []string
GetApplicationProfileDefinitionByName(name string) (*v1.ResourceInstance, error)
GetApplicationProfileDefinitionByID(id string) (*v1.ResourceInstance, error)
DeleteApplicationProfileDefinition(id string) error

// AccessRequestDefinition cache related methods
AddAccessRequestDefinition(resource *v1.ResourceInstance)
GetAccessRequestDefinitionKeys() []string
Expand Down
29 changes: 29 additions & 0 deletions pkg/agent/cache/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,35 @@ func createRequestDefinition(name, id string) *v1.ResourceInstance {
ri.CreateHashes()
return ri
}
func TestApplicationProfileDefinitionCache(t *testing.T) {
m := NewAgentCacheManager(&config.CentralConfiguration{}, false)
assert.NotNil(t, m)

ard1 := createRequestDefinition("name1", "id1")
ard2 := createRequestDefinition("name2", "id2")

m.AddApplicationProfileDefinition(ard1)
m.AddApplicationProfileDefinition(ard2)

cachedAPD, err := m.GetApplicationProfileDefinitionByName("name1")
assert.Nil(t, err)
assert.Equal(t, ard1, cachedAPD)

cachedAPD, err = m.GetApplicationProfileDefinitionByID("id1")
assert.Nil(t, err)
assert.Equal(t, ard1, cachedAPD)

err = m.DeleteApplicationProfileDefinition("id1")
assert.Nil(t, err)

cachedAPD, err = m.GetApplicationProfileDefinitionByName("name1")
assert.NotNil(t, err)
assert.Nil(t, cachedAPD)

cachedAPD, err = m.GetApplicationProfileDefinitionByID("id1")
assert.NotNil(t, err)
assert.Nil(t, cachedAPD)
}

func TestAccessRequestDefinitionCache(t *testing.T) {
m := NewAgentCacheManager(&config.CentralConfiguration{}, false)
Expand Down
3 changes: 1 addition & 2 deletions pkg/agent/handler/credential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -999,8 +999,7 @@ var crd = &management.CredentialRequestDefinition{
},
},
},
Owner: nil,
References: management.CredentialRequestDefinitionReferences{},
Owner: nil,
Spec: management.CredentialRequestDefinitionSpec{
Schema: nil,
Provision: &management.CredentialRequestDefinitionSpecProvision{
Expand Down
21 changes: 21 additions & 0 deletions pkg/agent/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func createOrUpdateDefinition(data v1.Interface) (*v1.ResourceInstance, error) {
var existingRI *v1.ResourceInstance

switch ri.Kind {
case management.ApplicationProfileDefinitionGVK().Kind:
existingRI, _ = agent.cacheManager.GetApplicationProfileDefinitionByName(ri.Name)
case management.AccessRequestDefinitionGVK().Kind:
existingRI, _ = agent.cacheManager.GetAccessRequestDefinitionByName(ri.Name)
case management.CredentialRequestDefinitionGVK().Kind:
Expand All @@ -61,6 +63,8 @@ func createOrUpdateDefinition(data v1.Interface) (*v1.ResourceInstance, error) {
// if not existing, go ahead and add the request definition
if existingRI == nil {
switch ri.Kind {
case management.ApplicationProfileDefinitionGVK().Kind:
agent.cacheManager.AddApplicationProfileDefinition(ri)
case management.AccessRequestDefinitionGVK().Kind:
agent.cacheManager.AddAccessRequestDefinition(ri)
case management.CredentialRequestDefinitionGVK().Kind:
Expand Down Expand Up @@ -525,6 +529,23 @@ func NewAPIKeyAccessRequestBuilder() provisioning.AccessRequestBuilder {
return NewAccessRequestBuilder().SetName(provisioning.APIKeyARD)
}

// application profile definitions

// createOrUpdateApplicationProfileDefinition -
func createOrUpdateApplicationProfileDefinition(data *management.ApplicationProfileDefinition) (*management.ApplicationProfileDefinition, error) {
ri, err := createOrUpdateDefinition(data)
if ri == nil || err != nil {
return nil, err
}
err = data.FromInstance(ri)
return data, err
}

// NewApplicationProfileBuilder - called by the agents to build and register a new application profile definition
func NewApplicationProfileBuilder() provisioning.ApplicationProfileBuilder {
return provisioning.NewApplicationProfileBuilder(createOrUpdateApplicationProfileDefinition)
}

// provisioner

// RegisterProvisioner - allow the agent to register a provisioner
Expand Down
95 changes: 95 additions & 0 deletions pkg/apic/provisioning/applicationprofiledefinitionbuilder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package provisioning

import (
"fmt"

management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1"
"github.com/Axway/agent-sdk/pkg/apic/definitions"
"github.com/Axway/agent-sdk/pkg/util"
)

// RegisterApplicationProfileDefinition - the function signature used when calling the NewApplicationProfileBuilder function
type RegisterApplicationProfileDefinition func(applicationProfileDefinition *management.ApplicationProfileDefinition) (*management.ApplicationProfileDefinition, error)

type applicationProfileDef struct {
name string
title string
requestSchema map[string]interface{}
registerFunc RegisterApplicationProfileDefinition
err error
}

// ApplicationProfileBuilder - aids in creating a new access request
type ApplicationProfileBuilder interface {
SetName(name string) ApplicationProfileBuilder
SetTitle(title string) ApplicationProfileBuilder
SetRequestSchema(schema SchemaBuilder) ApplicationProfileBuilder
Register() (*management.ApplicationProfileDefinition, error)
}

// NewApplicationProfileBuilder - called by the agent package and sends in the function that registers this access request
func NewApplicationProfileBuilder(registerFunc RegisterApplicationProfileDefinition) ApplicationProfileBuilder {
return &applicationProfileDef{
registerFunc: registerFunc,
}
}

// SetName - set the name of the access request
func (a *applicationProfileDef) SetName(name string) ApplicationProfileBuilder {
a.name = name
return a
}

// SetTitle - set the title of the access request
func (a *applicationProfileDef) SetTitle(title string) ApplicationProfileBuilder {
a.title = title
return a
}

// SetRequestSchema - set the schema to be used for access requests request data
func (a *applicationProfileDef) SetRequestSchema(schema SchemaBuilder) ApplicationProfileBuilder {
if a.err != nil {
return a
}

if schema != nil {
a.requestSchema, a.err = schema.Build()
} else {
a.err = fmt.Errorf("expected a SchemaBuilder argument but received nil")
}

return a
}

// Register - create the access request defintion and send it to Central
func (a *applicationProfileDef) Register() (*management.ApplicationProfileDefinition, error) {
if a.err != nil {
return nil, a.err
}

if a.requestSchema == nil {
a.requestSchema, _ = NewSchemaBuilder().Build()
}

if a.title == "" {
a.title = a.name
}

spec := management.ApplicationProfileDefinitionSpec{
Schema: a.requestSchema,
}

hashInt, _ := util.ComputeHash(spec)

if a.name == "" {
a.name = util.ConvertUnitToString(hashInt)
}

ard := management.NewApplicationProfileDefinition(a.name, "")
ard.Title = a.title
ard.Spec = spec

util.SetAgentDetailsKey(ard, definitions.AttrSpecHash, fmt.Sprintf("%v", hashInt))

return a.registerFunc(ard)
}
77 changes: 77 additions & 0 deletions pkg/apic/provisioning/applicationprofiledefinitionbuilder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package provisioning

import (
"testing"

management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1"
"github.com/stretchr/testify/assert"
)

func TestNewApplicationProfileBuilder(t *testing.T) {
tests := []struct {
name string
noSchema bool
copySchema bool
wantErr bool
}{
{
name: "Success",
},
{
name: "Fail",
wantErr: true,
},
{
name: "Empty",
noSchema: true,
},
{
name: "Copied",
copySchema: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
registerFuncCalled := false
registerFunc := func(applicationProfileDefinition *management.ApplicationProfileDefinition) (*management.ApplicationProfileDefinition, error) {
assert.NotNil(t, applicationProfileDefinition)
if !tt.noSchema {
assert.Len(t, applicationProfileDefinition.Spec.Schema["properties"], 1)
assert.NotNil(t, applicationProfileDefinition.Spec.Schema["properties"].(map[string]interface{})["prop"])
} else {
assert.Len(t, applicationProfileDefinition.Spec.Schema["properties"], 0)
}
registerFuncCalled = true
return nil, nil
}

builder := NewApplicationProfileBuilder(registerFunc).
SetName(tt.name)

if tt.wantErr {
builder = builder.SetRequestSchema(nil)
}

if !tt.noSchema {
builder = builder.
SetRequestSchema(
NewSchemaBuilder().
SetName("schema").
AddProperty(
NewSchemaPropertyBuilder().
SetName("prop").
IsString()))
}

_, err := builder.Register()

if tt.wantErr {
assert.NotNil(t, err)
assert.False(t, registerFuncCalled)
} else {
assert.Nil(t, err)
assert.True(t, registerFuncCalled)
}
})
}
}

0 comments on commit 5432001

Please sign in to comment.