Skip to content

Commit

Permalink
feat: added tailscale and fly integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
ArshiaBP committed Jan 14, 2025
1 parent d03667a commit 9cb22ba
Show file tree
Hide file tree
Showing 17 changed files with 567 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package configs

type IntegrationCredentials struct {
Token string `json:"token"`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package configs

const (
DescriberDeploymentName = "og-describer-fly"
DescriberRunCommand = "/og-describer-fly"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package configs

import "github.com/opengovern/og-util/pkg/integration"

const (
IntegrationTypeFlyAccount = integration.Type("fly_account") // example: AWS_ACCOUNT, AZURE_SUBSCRIPTION
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package configs

const (
StreamName = "og_describer_fly"
JobQueueTopic = "og_describer_fly_job_queue"
ConsumerGroup = "describer-fly"
JobQueueTopicManuals = "og_describer_fly_manuals_job_queue"
ConsumerGroupManuals = "describer-fly-manuals"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package configs

var TablesToResourceTypes = map[string]string{
"fly_app": "Fly/App",
"fly_machine": "Fly/Machine",
"fly_volume": "Fly/Volume",
"fly_secret": "Fly/Secret",
}

var ResourceTypesList = []string{
"Fly/App",
"Fly/Machine",
"Fly/Volume",
"Fly/Secret",
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package discovery

import (
"encoding/json"
"errors"
"fmt"
"net/http"
)

// Config represents the JSON input configuration
type Config struct {
Token string `json:"token"`
}

type App struct {
ID string `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
}

type Response struct {
Apps []App `json:"apps"`
}

// Discover retrieves fly user info
func Discover(token string) ([]App, error) {
var response Response

url := "https://api.machines.dev/v1/apps?org_slug=personal"

client := http.DefaultClient

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))

resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request execution failed: %w", err)
}
defer resp.Body.Close()

if err = json.NewDecoder(resp.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}

return response.Apps, nil
}

func FlyIntegrationDiscovery(cfg Config) ([]App, error) {
// Check for the token
if cfg.Token == "" {
return nil, errors.New("token must be configured")
}

return Discover(cfg.Token)
}
104 changes: 104 additions & 0 deletions services/integration/integration-type/fly-account/fly_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package doppler_account

import (
"encoding/json"
"github.com/jackc/pgtype"
flyDescriberLocal "github.com/opengovern/opencomply/services/integration/integration-type/fly-account/configs"
"github.com/opengovern/opencomply/services/integration/integration-type/fly-account/discovery"
"github.com/opengovern/opencomply/services/integration/integration-type/fly-account/healthcheck"
"github.com/opengovern/opencomply/services/integration/integration-type/interfaces"
"github.com/opengovern/opencomply/services/integration/models"
)

type FlyAccountIntegration struct{}

func (i *FlyAccountIntegration) GetConfiguration() interfaces.IntegrationConfiguration {
return interfaces.IntegrationConfiguration{
NatsScheduledJobsTopic: flyDescriberLocal.JobQueueTopic,
NatsManualJobsTopic: flyDescriberLocal.JobQueueTopicManuals,
NatsStreamName: flyDescriberLocal.StreamName,
NatsConsumerGroup: flyDescriberLocal.ConsumerGroup,
NatsConsumerGroupManuals: flyDescriberLocal.ConsumerGroupManuals,

SteampipePluginName: "fly",

UISpecFileName: "fly-account.json",

DescriberDeploymentName: flyDescriberLocal.DescriberDeploymentName,
DescriberRunCommand: flyDescriberLocal.DescriberRunCommand,
}
}

func (i *FlyAccountIntegration) HealthCheck(jsonData []byte, providerId string, labels map[string]string, annotations map[string]string) (bool, error) {
var credentials flyDescriberLocal.IntegrationCredentials
err := json.Unmarshal(jsonData, &credentials)
if err != nil {
return false, err
}

var appName string
if v, ok := labels["AppName"]; ok {
appName = v
}
isHealthy, err := healthcheck.FlyIntegrationHealthcheck(healthcheck.Config{
Token: credentials.Token,
AppName: appName,
})
return isHealthy, err
}

func (i *FlyAccountIntegration) DiscoverIntegrations(jsonData []byte) ([]models.Integration, error) {
var credentials flyDescriberLocal.IntegrationCredentials
err := json.Unmarshal(jsonData, &credentials)
if err != nil {
return nil, err
}
var integrations []models.Integration
apps, err := discovery.FlyIntegrationDiscovery(discovery.Config{
Token: credentials.Token,
})
for _, app := range apps {
labels := map[string]string{
"AppName": app.Name,
"Status": app.Status,
}
labelsJsonData, err := json.Marshal(labels)
if err != nil {
return nil, err
}
integrationLabelsJsonb := pgtype.JSONB{}
err = integrationLabelsJsonb.Set(labelsJsonData)
if err != nil {
return nil, err
}
integrations = append(integrations, models.Integration{
ProviderID: app.ID,
Name: app.Name,
Labels: integrationLabelsJsonb,
})
}
return integrations, nil
}

func (i *FlyAccountIntegration) GetResourceTypesByLabels(labels map[string]string) (map[string]*interfaces.ResourceTypeConfiguration, error) {
resourceTypesMap := make(map[string]*interfaces.ResourceTypeConfiguration)
for _, resourceType := range flyDescriberLocal.ResourceTypesList {
resourceTypesMap[resourceType] = nil
}
return resourceTypesMap, nil
}

func (i *FlyAccountIntegration) GetResourceTypeFromTableName(tableName string) string {
if v, ok := flyDescriberLocal.TablesToResourceTypes[tableName]; ok {
return v
}
return ""
}

func (i *FlyAccountIntegration) GetTablesByLabels(map[string]string) ([]string, error) {
var tables []string
for t, _ := range flyDescriberLocal.TablesToResourceTypes {
tables = append(tables, t)
}
return tables, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package healthcheck

import (
"encoding/json"
"errors"
"fmt"
"net/http"
)

// Config represents the JSON input configuration
type Config struct {
Token string `json:"token"`
AppName string `json:"app_name"`
}

type App struct {
ID string `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
}

// IsHealthy checks if the JWT has read access to all required resources
func IsHealthy(token, appName string) error {
var app App

url := fmt.Sprintf("https://api.machines.dev/v1/apps/%s", appName)

client := http.DefaultClient

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))

resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request execution failed: %w", err)
}
defer resp.Body.Close()

if err = json.NewDecoder(resp.Body).Decode(&app); err != nil {
return fmt.Errorf("failed to decode response: %w", err)
}

return nil
}

func FlyIntegrationHealthcheck(cfg Config) (bool, error) {
// Check for the token
if cfg.Token == "" {
return false, errors.New("token must be configured")
}

if cfg.AppName == "" {
return false, errors.New("app name must be configured")
}

err := IsHealthy(cfg.Token, cfg.AppName)
if err != nil {
return false, err
}

return true, nil
}
10 changes: 10 additions & 0 deletions services/integration/integration-type/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
dopplerConfigs "github.com/opengovern/opencomply/services/integration/integration-type/doppler-account/configs"
"github.com/opengovern/opencomply/services/integration/integration-type/entra-id-directory"
entraidConfigs "github.com/opengovern/opencomply/services/integration/integration-type/entra-id-directory/configs"
fly "github.com/opengovern/opencomply/services/integration/integration-type/fly-account"
flyConfigs "github.com/opengovern/opencomply/services/integration/integration-type/fly-account/configs"
githubaccount "github.com/opengovern/opencomply/services/integration/integration-type/github-account"
githubConfigs "github.com/opengovern/opencomply/services/integration/integration-type/github-account/configs"
google_workspace_account "github.com/opengovern/opencomply/services/integration/integration-type/google-workspace-account"
Expand All @@ -31,6 +33,8 @@ import (
openaiConfigs "github.com/opengovern/opencomply/services/integration/integration-type/openai-integration/configs"
render "github.com/opengovern/opencomply/services/integration/integration-type/render-account"
renderConfigs "github.com/opengovern/opencomply/services/integration/integration-type/render-account/configs"
tailscale "github.com/opengovern/opencomply/services/integration/integration-type/tailscale-account"
tailscaleConfigs "github.com/opengovern/opencomply/services/integration/integration-type/tailscale-account/configs"
)

const (
Expand All @@ -47,6 +51,8 @@ const (
IntegrationTypeOCIRepository = ociConfigs.IntegrationTypeOciRepository
IntegrationTypeRenderAccount = renderConfigs.IntegrationTypeRenderAccount
IntegrationTypeDopplerAccount = dopplerConfigs.IntegrationTypeDopplerAccount
IntegrationTypeTailScaleAccount = tailscaleConfigs.IntegrationTypeTailScaleAccount
IntegrationTypeFlyAccount = flyConfigs.IntegrationTypeFlyAccount
)

var AllIntegrationTypes = []integration.Type{
Expand All @@ -63,6 +69,8 @@ var AllIntegrationTypes = []integration.Type{
IntegrationTypeOCIRepository,
IntegrationTypeRenderAccount,
IntegrationTypeDopplerAccount,
IntegrationTypeTailScaleAccount,
IntegrationTypeFlyAccount,
}

var IntegrationTypes = map[integration.Type]interfaces.IntegrationType{
Expand All @@ -79,6 +87,8 @@ var IntegrationTypes = map[integration.Type]interfaces.IntegrationType{
IntegrationTypeOCIRepository: &oci.Integration{},
IntegrationTypeRenderAccount: &render.RenderAccountIntegration{},
IntegrationTypeDopplerAccount: &doppler.DopplerAccountIntegration{},
IntegrationTypeTailScaleAccount: &tailscale.TailScaleAccountIntegration{},
IntegrationTypeFlyAccount: &fly.FlyAccountIntegration{},
}

func ParseType(str string) integration.Type {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package configs

type IntegrationCredentials struct {
Token string `json:"token"`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package configs

const (
DescriberDeploymentName = "og-describer-tailscale"
DescriberRunCommand = "/og-describer-tailscale"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package configs

import "github.com/opengovern/og-util/pkg/integration"

const (
IntegrationTypeTailScaleAccount = integration.Type("tailscale_account") // example: AWS_ACCOUNT, AZURE_SUBSCRIPTION
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package configs

const (
StreamName = "og_describer_tailscale"
JobQueueTopic = "og_describer_tailscale_job_queue"
ConsumerGroup = "describer-tailscale"
JobQueueTopicManuals = "og_describer_tailscale_manuals_job_queue"
ConsumerGroupManuals = "describer-tailscale-manuals"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package configs

var TablesToResourceTypes = map[string]string{
"tailscale_device": "TailScale/Device",
"tailscale_user": "TailScale/User",
"tailscale_contact": "TailScale/Contact",
"tailscale_device_invite": "TailScale/Device/Invite",
"tailscale_device_posture": "TailScale/Device/Posture",
"tailscale_user_invite": "TailScale/User/Invite",
"tailscale_key": "TailScale/Key",
"tailscale_policy": "TailScale/Policy",
"tailscale_tailnet_setting": "TailScale/TailnetSetting",
"tailscale_webhook": "TailScale/Webhook",
"tailscale_dns": "TailScale/DNS",
}

var ResourceTypesList = []string{
"TailScale/Device",
"TailScale/User",
"TailScale/Contact",
"TailScale/Device/Invite",
"TailScale/Device/Posture",
"TailScale/User/Invite",
"TailScale/Key",
"TailScale/Policy",
"TailScale/TailnetSetting",
"TailScale/Webhook",
"TailScale/DNS",
}
Loading

0 comments on commit 9cb22ba

Please sign in to comment.