-
-
Notifications
You must be signed in to change notification settings - Fork 5
feat(cli): service to service access #146
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
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