Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APIGOV-22850 - one api service instance per stage #486

Merged
merged 15 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/agent/eventsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ func NewEventSync() (*EventSync, error) {
// add attribute migration to migrations
attributeMigration := migrate.NewAttributeMigration(agent.apicClient, agent.cfg)
ardMigration := migrate.NewArdMigration(agent.apicClient, agent.cfg)
sbolosan marked this conversation as resolved.
Show resolved Hide resolved
migrations = append(migrations, attributeMigration, ardMigration)
apisiMigration := migrate.NewAPISIMigration(agent.apicClient, agent.cfg)
migrations = append(migrations, attributeMigration, ardMigration, apisiMigration)

if isMpEnabled {
// add marketplace migration to migrations
Expand Down
2 changes: 0 additions & 2 deletions pkg/apic/apiservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ func TestCreateService(t *testing.T) {
apiSvc, err := client.PublishService(&cloneServiceBody)
assert.Nil(t, err)
assert.NotNil(t, apiSvc)
assert.Equal(t, &cloneServiceBody.serviceContext.revisionName, &cloneServiceBody.serviceContext.instanceName)
// this should fail
httpClient.SetResponses([]api.MockResponse{
{
Expand Down Expand Up @@ -309,7 +308,6 @@ func TestUpdateService(t *testing.T) {
apiSvc, err := client.PublishService(&cloneServiceBody)
assert.Nil(t, err)
assert.NotNil(t, apiSvc)
assert.Equal(t, &cloneServiceBody.serviceContext.revisionName, &cloneServiceBody.serviceContext.instanceName)

// tests for updating existing instance with same endpoint
httpClient.SetResponses([]api.MockResponse{
Expand Down
49 changes: 29 additions & 20 deletions pkg/apic/apiserviceinstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package apic
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"

Expand Down Expand Up @@ -145,25 +144,25 @@ func (c *ServiceClient) processInstance(serviceBody *ServiceBody) error {
var instance *mv1a.APIServiceInstance

instanceURL := c.cfg.GetInstancesURL()
instancePrefix := getRevisionPrefix(serviceBody)
instanceName := instancePrefix + "." + strconv.Itoa(serviceBody.serviceContext.revisionCount)
instanceName := getRevisionPrefix(serviceBody)

if serviceBody.serviceContext.revisionAction == addAPI {
httpMethod = http.MethodPost
instance = c.buildAPIServiceInstance(serviceBody, instanceName, endpoints)
}
// creating new instance
httpMethod = http.MethodPost
instance = c.buildAPIServiceInstance(serviceBody, instanceName, endpoints)

if serviceBody.serviceContext.revisionAction == updateAPI {
httpMethod = http.MethodPut
instances, err := c.getRevisionInstances(instanceName, instanceURL)
if serviceBody.serviceContext.serviceAction == updateAPI {
prevInst, err := c.getLastInstance(serviceBody, instanceURL)
if err != nil {
return err
}
if len(instances) == 0 {
return fmt.Errorf("no instance found named '%s' for revision '%s'", instanceName, serviceBody.serviceContext.revisionName)

if prevInst != nil {
instanceURL = instanceURL + "/" + instanceName
jcollins-axway marked this conversation as resolved.
Show resolved Hide resolved

// updating existing instance
httpMethod = http.MethodPut
instance = c.updateAPIServiceInstance(serviceBody, prevInst, endpoints)
}
instanceURL = instanceURL + "/" + instanceName
instance = c.updateAPIServiceInstance(serviceBody, instances[0], endpoints)
}

buffer, err := json.Marshal(instance)
Expand Down Expand Up @@ -233,13 +232,23 @@ func createInstanceEndpoint(endpoints []EndpointDefinition) ([]mv1a.ApiServiceIn
return endPoints, nil
}

func (c *ServiceClient) getRevisionInstances(name, url string) ([]*mv1a.APIServiceInstance, error) {
// Check if instances exist for the current revision.
queryParams := map[string]string{
"query": "name==" + name,
}
func (c *ServiceClient) getLastInstance(serviceBody *ServiceBody, url string) (*mv1a.APIServiceInstance, error) {
// start from latest revision, find first instance
for i := serviceBody.serviceContext.revisionCount; i > 0; i-- {
queryParams := map[string]string{
"query": "metadata.references.name==" + getRevisionPrefix(serviceBody) + "." + strconv.Itoa(i),
}

return c.GetAPIServiceInstances(queryParams, url)
instances, err := c.GetAPIServiceInstances(queryParams, url)
if err != nil {
return nil, err
}

if len(instances) > 0 {
return instances[0], nil
}
}
return nil, nil
}

// GetAPIServiceInstanceByName - Returns the API service instance for specified name
Expand Down
1 change: 1 addition & 0 deletions pkg/apic/definitions/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const (
ReferencesSubResource = "references"
Subscription = "Subscription"
MarketplaceMigration = "marketplace-migration"
InstanceMigration = "instance-migration"
)

// market place provisioning migration
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func TestRootCmdFlags(t *testing.T) {
assertStringSliceCmdFlag(t, rootCmd, "central.ssl.cipherSuites", "centralSslCipherSuites", corecfg.TLSDefaultCipherSuitesStringSlice(), "List of supported cipher suites, comma separated")
assertStringCmdFlag(t, rootCmd, "central.ssl.minVersion", "centralSslMinVersion", corecfg.TLSDefaultMinVersionString(), "Minimum acceptable SSL/TLS protocol version")
assertStringCmdFlag(t, rootCmd, "central.ssl.maxVersion", "centralSslMaxVersion", "0", "Maximum acceptable SSL/TLS protocol version")
assertBooleanCmdFlag(t, rootCmd, "central.migration.cleanInstances", "centralMigrationCleanInstances", false, "Set this to clean all but latest instance, per stage, within an API Service")

// Traceability Agent
rootCmd = NewRootCmd("Test", "TestRootCmd", nil, nil, corecfg.TraceabilityAgent)
Expand Down
12 changes: 12 additions & 0 deletions pkg/config/centralconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ type CentralConfig interface {
SetIsMarketplaceSubsEnabled(enabled bool)
IsMarketplaceSubsEnabled() bool
GetSingleURL() string
GetMigrationSettings() MigrationConfig
}

// CentralConfiguration - Structure to hold the central config
Expand All @@ -143,6 +144,7 @@ type CentralConfiguration struct {
APIServerVersion string `config:"apiServerVersion"`
TagsToPublish string `config:"additionalTags"`
AppendEnvironmentToTitle bool `config:"appendEnvironmentToTitle"`
MigrationSettings MigrationConfig `config:"migration"`
Auth AuthConfig `config:"auth"`
TLS TLSConfig `config:"ssl"`
PollInterval time.Duration `config:"pollInterval"`
Expand Down Expand Up @@ -202,6 +204,7 @@ func NewCentralConfig(agentType AgentType) CentralConfig {
PageSize: 20,
},
},
MigrationSettings: newMigrationConfig(),
}
}

Expand All @@ -212,6 +215,7 @@ func NewTestCentralConfig(agentType AgentType) CentralConfig {
config.URL = "https://central.com"
config.Environment = "environment"
config.Auth = newTestAuthConfig()
config.MigrationSettings = newTestMigrationConfig()
return config
}

Expand Down Expand Up @@ -430,6 +434,11 @@ func (c *CentralConfiguration) GetAuthConfig() AuthConfig {
return c.Auth
}

// GetMigrationSettings - Returns the Migration Config
func (c *CentralConfiguration) GetMigrationSettings() MigrationConfig {
return c.MigrationSettings
}

// GetTLSConfig - Returns the TLS Config
func (c *CentralConfiguration) GetTLSConfig() TLSConfig {
return c.TLS
Expand Down Expand Up @@ -754,6 +763,7 @@ func AddCentralConfigProperties(props properties.Properties, agentType AgentType
props.AddStringProperty(pathAdditionalTags, "", "Additional Tags to Add to discovered APIs when publishing to Amplify Central")
props.AddBoolProperty(pathAppendEnvironmentToTitle, true, "When true API titles and descriptions will be appended with environment name")
AddSubscriptionConfigProperties(props)
AddMigrationConfigProperties(props)
}
}

Expand Down Expand Up @@ -832,9 +842,11 @@ func ParseCentralConfig(props properties.Properties, agentType AgentType) (Centr
// set the notifications
subscriptionConfig := ParseSubscriptionConfig(props)
cfg.SubscriptionConfiguration = subscriptionConfig
cfg.MigrationSettings = ParseMigrationConfig(props)
}
return cfg, nil
}

func supportsTraceability(agentType AgentType) bool {
return agentType == TraceabilityAgent
}
53 changes: 53 additions & 0 deletions pkg/config/migrationconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package config

import "github.com/Axway/agent-sdk/pkg/cmd/properties"

// MigrationConfig - Interface for migration settings config
sbolosan marked this conversation as resolved.
Show resolved Hide resolved
type MigrationConfig interface {
ShouldCleanInstances() bool
validate()
}

// MigrationSettings -
type MigrationSettings struct {
CleanInstances bool
}

func newMigrationConfig() MigrationConfig {
return &MigrationSettings{
CleanInstances: false,
}
}

func newTestMigrationConfig() MigrationConfig {
return &MigrationSettings{
CleanInstances: true,
}
}

func (m *MigrationSettings) validate() {
}

// ShouldCleanInstances - returns the value fo CleanInstances
func (m *MigrationSettings) ShouldCleanInstances() bool {
return m.CleanInstances
}

const (
pathCleanInstances = "central.migration.cleanInstances"
)

// AddMigrationConfigProperties - Adds the command properties needed for Migration Config
func AddMigrationConfigProperties(props properties.Properties) {
props.AddBoolProperty(pathCleanInstances, false, "Set this to clean all but latest instance, per stage, within an API Service")
}

// ParseMigrationConfig - Parses the Migration Config values from the command line
func ParseMigrationConfig(props properties.Properties) MigrationConfig {
migrationConfig := newMigrationConfig()
migrationSettings := migrationConfig.(*MigrationSettings)

migrationSettings.CleanInstances = props.BoolPropertyValue(pathCleanInstances)

return migrationSettings
}
13 changes: 13 additions & 0 deletions pkg/config/migrationconfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMigrationConfig(t *testing.T) {
defConf := newMigrationConfig()

assert.False(t, defConf.ShouldCleanInstances())
}
Loading