Skip to content

Commit

Permalink
Merge pull request #94 from port-labs/PORT-12682_support_provisioning…
Browse files Browse the repository at this point in the history
…_on_exporter

Port 12682 support new provisioning on k8s-exporter
  • Loading branch information
razsamuel authored Feb 2, 2025
2 parents 8732c1b + 8d5e1c2 commit 4d6fab7
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 51 deletions.
3 changes: 3 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func Init() {
NewString(&ApplicationConfig.PortClientId, "port-client-id", "", "Port client id. Required.")
NewString(&ApplicationConfig.PortClientSecret, "port-client-secret", "", "Port client secret. Required.")
NewBool(&ApplicationConfig.CreateDefaultResources, "create-default-resources", true, "Create default resources on installation. Optional.")
NewCreatePortResourcesOrigin(&ApplicationConfig.CreatePortResourcesOrigin, "create-default-resources-origin", "Port", "Create default resources origin on installation. Optional.")

NewBool(&ApplicationConfig.OverwriteConfigurationOnRestart, "overwrite-configuration-on-restart", false, "Overwrite the configuration in port on restarting the exporter. Optional.")

// Deprecated
Expand All @@ -52,6 +54,7 @@ func NewConfiguration() (*port.Config, error) {
StateKey: ApplicationConfig.StateKey,
EventListenerType: ApplicationConfig.EventListenerType,
CreateDefaultResources: ApplicationConfig.CreateDefaultResources,
CreatePortResourcesOrigin: ApplicationConfig.CreatePortResourcesOrigin,
ResyncInterval: ApplicationConfig.ResyncInterval,
OverwriteConfigurationOnRestart: ApplicationConfig.OverwriteConfigurationOnRestart,
CreateMissingRelatedEntities: ApplicationConfig.CreateMissingRelatedEntities,
Expand Down
1 change: 1 addition & 0 deletions pkg/config/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ApplicationConfiguration struct {
PortClientSecret string
EventListenerType string
CreateDefaultResources bool
CreatePortResourcesOrigin port.CreatePortResourcesOrigin
OverwriteConfigurationOnRestart bool
// These Configurations are used only for setting up the Integration on installation or when using OverwriteConfigurationOnRestart flag.
Resources []port.Resource
Expand Down
12 changes: 12 additions & 0 deletions pkg/config/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package config

import (
"flag"
"fmt"
"github.com/port-labs/port-k8s-exporter/pkg/port"
"strings"

"github.com/port-labs/port-k8s-exporter/pkg/goutils"
Expand Down Expand Up @@ -35,3 +37,13 @@ func NewBool(v *bool, key string, defaultValue bool, description string) {
value := goutils.GetBoolEnvOrDefault(prepareEnvKey(key), defaultValue)
flag.BoolVar(v, key, value, description)
}

func NewCreatePortResourcesOrigin(target *port.CreatePortResourcesOrigin, key, defaultValue, description string) {
var value string
flag.StringVar(&value, key, defaultValue, description)

*target = port.CreatePortResourcesOrigin(value)
if *target != port.CreatePortResourcesOriginPort && *target != port.CreatePortResourcesOriginK8S {
panic(fmt.Sprintf("Invalid value for %s: %s. Must be one of [Port, K8S]", key, value))
}
}
66 changes: 37 additions & 29 deletions pkg/defaults/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ func NewFixture(t *testing.T) *Fixture {
}

func (f *Fixture) CreateIntegration() {
err := integration.CreateIntegration(f.portClient, f.stateKey, "", &port.IntegrationAppConfig{
_, err := integration.CreateIntegration(f.portClient, f.stateKey, "", &port.IntegrationAppConfig{
Resources: []port.Resource{},
})
}, false)

if err != nil {
f.t.Errorf("Error creating Port integration: %s", err.Error())
Expand All @@ -70,9 +70,10 @@ func Test_InitIntegration_InitDefaults(t *testing.T) {
f := NewFixture(t)
defer tearDownFixture(t, f)
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -99,9 +100,10 @@ func Test_InitIntegration_InitDefaults_CreateDefaultResources_False(t *testing.T
f := NewFixture(t)
defer tearDownFixture(t, f)
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: false,
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: false,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -124,9 +126,10 @@ func Test_InitIntegration_BlueprintExists(t *testing.T) {
t.Errorf("Error creating Port blueprint: %s", err.Error())
}
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -150,9 +153,10 @@ func Test_InitIntegration_PageExists(t *testing.T) {
t.Errorf("Error creating Port page: %s", err.Error())
}
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -169,14 +173,15 @@ func Test_InitIntegration_PageExists(t *testing.T) {
func Test_InitIntegration_ExistingIntegration(t *testing.T) {
f := NewFixture(t)
defer tearDownFixture(t, f)
err := integration.CreateIntegration(f.portClient, f.stateKey, "", nil)
_, err := integration.CreateIntegration(f.portClient, f.stateKey, "", nil, false)
if err != nil {
t.Errorf("Error creating Port integration: %s", err.Error())
}
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "POLLING",
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -189,7 +194,7 @@ func Test_InitIntegration_ExistingIntegration(t *testing.T) {
func Test_InitIntegration_LocalResourcesConfiguration(t *testing.T) {
f := NewFixture(t)
defer tearDownFixture(t, f)
err := integration.CreateIntegration(f.portClient, f.stateKey, "", nil)
_, err := integration.CreateIntegration(f.portClient, f.stateKey, "", nil, false)
if err != nil {
t.Errorf("Error creating Port integration: %s", err.Error())
}
Expand All @@ -214,10 +219,11 @@ func Test_InitIntegration_LocalResourcesConfiguration(t *testing.T) {
},
}
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "POLLING",
Resources: expectedResources,
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "POLLING",
Resources: expectedResources,
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand All @@ -231,15 +237,16 @@ func Test_InitIntegration_LocalResourcesConfiguration(t *testing.T) {
func Test_InitIntegration_LocalResourcesConfiguration_ExistingIntegration_EmptyConfiguration(t *testing.T) {
f := NewFixture(t)
defer tearDownFixture(t, f)
err := integration.CreateIntegration(f.portClient, f.stateKey, "POLLING", nil)
_, err := integration.CreateIntegration(f.portClient, f.stateKey, "POLLING", nil, false)
if err != nil {
t.Errorf("Error creating Port integration: %s", err.Error())
}
e := InitIntegration(f.portClient, &port.Config{
StateKey: f.stateKey,
EventListenerType: "KAFKA",
Resources: nil,
CreateDefaultResources: true,
StateKey: f.stateKey,
EventListenerType: "KAFKA",
Resources: nil,
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
})
assert.Nil(t, e)

Expand Down Expand Up @@ -276,7 +283,7 @@ func Test_InitIntegration_LocalResourcesConfiguration_ExistingIntegration_WithCo
},
},
}
err := integration.CreateIntegration(f.portClient, f.stateKey, "POLLING", expectedConfig)
_, err := integration.CreateIntegration(f.portClient, f.stateKey, "POLLING", expectedConfig, false)
if err != nil {
t.Errorf("Error creating Port integration: %s", err.Error())
}
Expand All @@ -287,6 +294,7 @@ func Test_InitIntegration_LocalResourcesConfiguration_ExistingIntegration_WithCo
EventListenerType: "KAFKA",
Resources: expectedConfig.Resources,
CreateDefaultResources: true,
CreatePortResourcesOrigin: port.CreatePortResourcesOriginK8S,
OverwriteConfigurationOnRestart: true,
})
assert.Nil(t, e)
Expand Down
44 changes: 38 additions & 6 deletions pkg/defaults/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/port-labs/port-k8s-exporter/pkg/port"
"github.com/port-labs/port-k8s-exporter/pkg/port/cli"
"github.com/port-labs/port-k8s-exporter/pkg/port/integration"
"github.com/port-labs/port-k8s-exporter/pkg/port/org_details"
"k8s.io/klog/v2"
)

Expand All @@ -16,13 +17,41 @@ func getEventListenerConfig(eventListenerType string) *port.EventListenerSetting
return nil
}

func isPortProvisioningSupported(portClient *cli.PortClient) (bool, error) {
klog.Info("Resources origin is set to be Port, verifying integration is supported")
featureFlags, err := org_details.GetOrganizationFeatureFlags(portClient)
if err != nil {
return false, err
}

for _, flag := range featureFlags {
if flag == port.OrgUseProvisionedDefaultsFeatureFlag {
return true, nil
}
}

klog.Info("Port origin for Integration is not supported, changing resources origin to use K8S")
return false, nil
}

func InitIntegration(portClient *cli.PortClient, applicationConfig *port.Config) error {
klog.Infof("Initializing Port integration")
defaults, err := getDefaults()
if err != nil {
return err
}


// Verify Port origin is supported via feature flags
if applicationConfig.CreatePortResourcesOrigin == port.CreatePortResourcesOriginPort {
shouldProvisionResourcesUsingPort, err := isPortProvisioningSupported(portClient)
if err != nil {
return err
}
if !shouldProvisionResourcesUsingPort {
applicationConfig.CreatePortResourcesOrigin = port.CreatePortResourcesOriginK8S
}
}

existingIntegration, err := integration.GetIntegration(portClient, applicationConfig.StateKey)
defaultIntegrationConfig := &port.IntegrationAppConfig{
Resources: applicationConfig.Resources,
Expand All @@ -34,11 +63,15 @@ func InitIntegration(portClient *cli.PortClient, applicationConfig *port.Config)

if err != nil {
if applicationConfig.CreateDefaultResources {
defaultIntegrationConfig = defaults.AppConfig
if applicationConfig.CreatePortResourcesOrigin != port.CreatePortResourcesOriginPort {
defaultIntegrationConfig = defaults.AppConfig
}
}

klog.Warningf("Could not get integration with state key %s, error: %s", applicationConfig.StateKey, err.Error())
if err := integration.CreateIntegration(portClient, applicationConfig.StateKey, applicationConfig.EventListenerType, defaultIntegrationConfig); err != nil {
shouldCreateResourcesUsingPort := applicationConfig.CreatePortResourcesOrigin == port.CreatePortResourcesOriginPort
_, err := integration.CreateIntegration(portClient, applicationConfig.StateKey, applicationConfig.EventListenerType, defaultIntegrationConfig, shouldCreateResourcesUsingPort)
if err != nil {
return err
}
} else {
Expand All @@ -47,7 +80,7 @@ func InitIntegration(portClient *cli.PortClient, applicationConfig *port.Config)
EventListener: getEventListenerConfig(applicationConfig.EventListenerType),
}

if existingIntegration.Config == nil || applicationConfig.OverwriteConfigurationOnRestart {
if (existingIntegration.Config == nil && !(applicationConfig.CreatePortResourcesOrigin == port.CreatePortResourcesOriginPort)) || applicationConfig.OverwriteConfigurationOnRestart {
integrationPatch.Config = defaultIntegrationConfig
}

Expand All @@ -56,13 +89,12 @@ func InitIntegration(portClient *cli.PortClient, applicationConfig *port.Config)
}
}

if applicationConfig.CreateDefaultResources {
if applicationConfig.CreateDefaultResources && applicationConfig.CreatePortResourcesOrigin != port.CreatePortResourcesOriginPort {
klog.Infof("Creating default resources (blueprints, pages, etc..)")
if err := initializeDefaults(portClient, defaults); err != nil {
klog.Warningf("Error initializing defaults: %s", err.Error())
klog.Warningf("Some default resources may not have been created. The integration will continue running.")
}
}

return nil
}
6 changes: 2 additions & 4 deletions pkg/event_handler/polling/polling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ func (m *MockTicker) GetC() <-chan time.Time {

func NewFixture(t *testing.T, c chan time.Time) *Fixture {
stateKey := guuid.NewString()

newConfig := &config.ApplicationConfiguration{
ConfigFilePath: config.ApplicationConfig.ConfigFilePath,
ResyncInterval: config.ApplicationConfig.ResyncInterval,
Expand All @@ -49,11 +48,10 @@ func NewFixture(t *testing.T, c chan time.Time) *Fixture {
}

portClient := cli.New(newConfig)

_ = integration.DeleteIntegration(portClient, stateKey)
err := integration.CreateIntegration(portClient, stateKey, "", &port.IntegrationAppConfig{
_, err := integration.CreateIntegration(portClient, stateKey, "", &port.IntegrationAppConfig{
Resources: []port.Resource{},
})
}, false)
if err != nil {
t.Errorf("Error creating Port integration: %s", err.Error())
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/port/cli/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ func parseIntegration(i *port.Integration) *port.Integration {
return x
}

func (c *PortClient) CreateIntegration(i *port.Integration) (*port.Integration, error) {
func (c *PortClient) CreateIntegration(i *port.Integration, queryParams map[string]string) (*port.Integration, error) {
pb := &port.ResponseBody{}
resp, err := c.Client.R().
SetQueryParams(queryParams).
SetBody(parseIntegration(i)).
SetResult(&pb).
Post("v1/integration")
Expand Down
14 changes: 14 additions & 0 deletions pkg/port/cli/org_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,17 @@ func (c *PortClient) GetOrgId() (string, error) {
}
return pb.OrgDetails.OrgId, nil
}

func (c *PortClient) GetOrganizationFeatureFlags() ([]string, error) {
pb := &port.ResponseBody{}
resp, err := c.Client.R().
SetResult(&pb).
Get("v1/organization")
if err != nil {
return nil, err
}
if !pb.OK {
return nil, fmt.Errorf("failed to get organization feature flags, got: %s", resp.Body())
}
return pb.OrgDetails.FeatureFlags, nil
}
Loading

0 comments on commit 4d6fab7

Please sign in to comment.