-
-
Notifications
You must be signed in to change notification settings - Fork 5
feat(cli): service to service access #146
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -274,10 +274,24 @@ func (s *SimulationServer) CopyDir(dst, src string) error { | |||||||||||||||
| func (s *SimulationServer) startServices(output io.Writer) (<-chan service.ServiceEvent, error) { | ||||||||||||||||
| serviceIntents := s.appSpec.ServiceIntents | ||||||||||||||||
|
|
||||||||||||||||
| servicePorts := make(map[string]netx.ReservedPort) | ||||||||||||||||
| eventChans := []<-chan service.ServiceEvent{} | ||||||||||||||||
|
|
||||||||||||||||
| for serviceName, serviceIntent := range serviceIntents { | ||||||||||||||||
| // Helper function for lazy port allocation | ||||||||||||||||
| getOrAllocatePort := func(serviceName string) (netx.ReservedPort, error) { | ||||||||||||||||
| if port, exists := servicePorts[serviceName]; exists { | ||||||||||||||||
| return port, nil | ||||||||||||||||
| } | ||||||||||||||||
| port, err := netx.GetNextPort() | ||||||||||||||||
| if err != nil { | ||||||||||||||||
| return 0, err | ||||||||||||||||
| } | ||||||||||||||||
| servicePorts[serviceName] = port | ||||||||||||||||
| return port, nil | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| for serviceName, serviceIntent := range serviceIntents { | ||||||||||||||||
| port, err := getOrAllocatePort(serviceName) | ||||||||||||||||
| if err != nil { | ||||||||||||||||
| return nil, err | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -304,6 +318,21 @@ func (s *SimulationServer) startServices(output io.Writer) (<-chan service.Servi | |||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Inject URLs for services this service can access | ||||||||||||||||
| // Check which services grant access to this service and lazily allocate their ports | ||||||||||||||||
| for targetServiceName, targetServiceIntent := range serviceIntents { | ||||||||||||||||
| if access, ok := targetServiceIntent.GetAccess(); ok { | ||||||||||||||||
| if _, hasAccess := access[serviceName]; hasAccess { | ||||||||||||||||
| targetPort, err := getOrAllocatePort(targetServiceName) | ||||||||||||||||
| if err != nil { | ||||||||||||||||
| return nil, err | ||||||||||||||||
| } | ||||||||||||||||
| envVarName := fmt.Sprintf("%s_URL", strings.ToUpper(targetServiceName)) | ||||||||||||||||
| intentCopy.Env[envVarName] = fmt.Sprintf("http://localhost:%d", targetPort) | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+330
to
+332
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Match production-safe env key naming Simulation still emits Apply this diff: - envVarName := fmt.Sprintf("%s_URL", strings.ToUpper(targetServiceName))
+ safeName := strings.ToUpper(strings.ReplaceAll(targetServiceName, "-", "_"))
+ envVarName := fmt.Sprintf("%s_URL", safeName)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| simulatedService, eventChan, err := service.NewServiceSimulation(serviceName, intentCopy, port, s.apiPort) | ||||||||||||||||
| if err != nil { | ||||||||||||||||
| return nil, err | ||||||||||||||||
|
|
||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -93,7 +93,42 @@ func (td *TerraformDeployment) processServiceIdentities(appSpec *app_spec_schema | |||||||||||||||||||||||
| return serviceInputs, nil | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| func (td *TerraformDeployment) collectServiceAccessors(appSpec *app_spec_schema.Application) map[string]map[string]interface{} { | ||||||||||||||||||||||||
| serviceAccessors := make(map[string]map[string]interface{}) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for targetServiceName, targetServiceIntent := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| if access, ok := targetServiceIntent.GetAccess(); ok { | ||||||||||||||||||||||||
| accessors := map[string]interface{}{} | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for accessorServiceName, actions := range access { | ||||||||||||||||||||||||
| expandedActions := app_spec_schema.ExpandActions(actions, app_spec_schema.Service) | ||||||||||||||||||||||||
| idMap := td.serviceIdentities[accessorServiceName] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| accessors[accessorServiceName] = map[string]interface{}{ | ||||||||||||||||||||||||
| "actions": jsii.Strings(expandedActions...), | ||||||||||||||||||||||||
| "identities": idMap, | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if len(accessors) > 0 { | ||||||||||||||||||||||||
| serviceAccessors[targetServiceName] = accessors | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return serviceAccessors | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| func (td *TerraformDeployment) processServiceResources(appSpec *app_spec_schema.Application, serviceInputs map[string]*SugaServiceVariables, serviceEnvs map[string][]interface{}) error { | ||||||||||||||||||||||||
| serviceAccessors := td.collectServiceAccessors(appSpec) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Track original env values before modification | ||||||||||||||||||||||||
| originalEnvs := make(map[string]interface{}) | ||||||||||||||||||||||||
| for intentName := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| sugaVar := serviceInputs[intentName] | ||||||||||||||||||||||||
| originalEnvs[intentName] = sugaVar.Env | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for intentName, serviceIntent := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| spec, err := td.engine.platform.GetResourceBlueprint(serviceIntent.GetType(), serviceIntent.GetSubType()) | ||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||
|
|
@@ -105,11 +140,10 @@ func (td *TerraformDeployment) processServiceResources(appSpec *app_spec_schema. | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| sugaVar := serviceInputs[intentName] | ||||||||||||||||||||||||
| origEnv := sugaVar.Env | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| mergedEnv := serviceEnvs[intentName] | ||||||||||||||||||||||||
| allEnv := append(mergedEnv, origEnv) | ||||||||||||||||||||||||
| sugaVar.Env = cdktf.Fn_Merge(&allEnv) | ||||||||||||||||||||||||
| if accessors, ok := serviceAccessors[intentName]; ok { | ||||||||||||||||||||||||
| sugaVar.Services = accessors | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| td.createVariablesForIntent(intentName, spec) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -121,6 +155,32 @@ func (td *TerraformDeployment) processServiceResources(appSpec *app_spec_schema. | |||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Add service to service urls | ||||||||||||||||||||||||
| // Build reverse index: for each accessor service, find which targets grant it access | ||||||||||||||||||||||||
| for accessorServiceName := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| for targetServiceName, targetServiceIntent := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| if access, ok := targetServiceIntent.GetAccess(); ok { | ||||||||||||||||||||||||
| if _, hasAccess := access[accessorServiceName]; hasAccess { | ||||||||||||||||||||||||
| if targetResource, ok := td.terraformResources[targetServiceName]; ok { | ||||||||||||||||||||||||
| envVarName := fmt.Sprintf("%s_URL", strings.ToUpper(targetServiceName)) | ||||||||||||||||||||||||
| httpEndpoint := targetResource.Get(jsii.String("suga.http_endpoint")) | ||||||||||||||||||||||||
| serviceEnvs[accessorServiceName] = append(serviceEnvs[accessorServiceName], map[string]interface{}{ | ||||||||||||||||||||||||
| envVarName: httpEndpoint, | ||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||
|
Comment on lines
+165
to
+169
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sanitize service URL env keys Service names like Apply this diff: - envVarName := fmt.Sprintf("%s_URL", strings.ToUpper(targetServiceName))
+ safeName := strings.ToUpper(strings.ReplaceAll(targetServiceName, "-", "_"))
+ envVarName := fmt.Sprintf("%s_URL", safeName)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| // Merge environment variables for all services | ||||||||||||||||||||||||
| for intentName := range appSpec.ServiceIntents { | ||||||||||||||||||||||||
| sugaVar := serviceInputs[intentName] | ||||||||||||||||||||||||
| mergedEnv := serviceEnvs[intentName] | ||||||||||||||||||||||||
| allEnv := append(mergedEnv, originalEnvs[intentName]) | ||||||||||||||||||||||||
| sugaVar.Env = cdktf.Fn_Merge(&allEnv) | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wonder if these names should be prefixed with SUGA