github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/client/taskenv/services.go (about)

     1  package taskenv
     2  
     3  import (
     4  	"github.com/hashicorp/nomad/nomad/structs"
     5  )
     6  
     7  // InterpolateServices returns an interpolated copy of services and checks with
     8  // values from the task's environment.
     9  func InterpolateServices(taskEnv *TaskEnv, services []*structs.Service) []*structs.Service {
    10  	// Guard against not having a valid taskEnv. This can be the case if the
    11  	// PreKilling or Exited hook is run before Poststart.
    12  	if taskEnv == nil || len(services) == 0 {
    13  		return nil
    14  	}
    15  
    16  	interpolated := make([]*structs.Service, len(services))
    17  
    18  	for i, origService := range services {
    19  		// Create a copy as we need to re-interpolate every time the
    20  		// environment changes.
    21  		service := origService.Copy()
    22  
    23  		for _, check := range service.Checks {
    24  			check.Name = taskEnv.ReplaceEnv(check.Name)
    25  			check.Type = taskEnv.ReplaceEnv(check.Type)
    26  			check.Command = taskEnv.ReplaceEnv(check.Command)
    27  			check.Args = taskEnv.ParseAndReplace(check.Args)
    28  			check.Path = taskEnv.ReplaceEnv(check.Path)
    29  			check.Protocol = taskEnv.ReplaceEnv(check.Protocol)
    30  			check.PortLabel = taskEnv.ReplaceEnv(check.PortLabel)
    31  			check.InitialStatus = taskEnv.ReplaceEnv(check.InitialStatus)
    32  			check.Method = taskEnv.ReplaceEnv(check.Method)
    33  			check.GRPCService = taskEnv.ReplaceEnv(check.GRPCService)
    34  			check.Header = interpolateMapStringSliceString(taskEnv, check.Header)
    35  		}
    36  
    37  		service.Name = taskEnv.ReplaceEnv(service.Name)
    38  		service.PortLabel = taskEnv.ReplaceEnv(service.PortLabel)
    39  		service.Tags = taskEnv.ParseAndReplace(service.Tags)
    40  		service.CanaryTags = taskEnv.ParseAndReplace(service.CanaryTags)
    41  		service.Meta = interpolateMapStringString(taskEnv, service.Meta)
    42  		service.CanaryMeta = interpolateMapStringString(taskEnv, service.CanaryMeta)
    43  		interpolateConnect(taskEnv, service.Connect)
    44  
    45  		interpolated[i] = service
    46  	}
    47  
    48  	return interpolated
    49  }
    50  
    51  func interpolateMapStringSliceString(taskEnv *TaskEnv, orig map[string][]string) map[string][]string {
    52  	if len(orig) == 0 {
    53  		return nil
    54  	}
    55  
    56  	m := make(map[string][]string, len(orig))
    57  	for k, vs := range orig {
    58  		m[taskEnv.ReplaceEnv(k)] = taskEnv.ParseAndReplace(vs)
    59  	}
    60  	return m
    61  }
    62  
    63  func interpolateMapStringString(taskEnv *TaskEnv, orig map[string]string) map[string]string {
    64  	if len(orig) == 0 {
    65  		return nil
    66  	}
    67  
    68  	m := make(map[string]string, len(orig))
    69  	for k, v := range orig {
    70  		m[taskEnv.ReplaceEnv(k)] = taskEnv.ReplaceEnv(v)
    71  	}
    72  	return m
    73  }
    74  
    75  func interpolateMapStringInterface(taskEnv *TaskEnv, orig map[string]interface{}) map[string]interface{} {
    76  	if len(orig) == 0 {
    77  		return nil
    78  	}
    79  
    80  	m := make(map[string]interface{}, len(orig))
    81  	for k, v := range orig {
    82  		m[taskEnv.ReplaceEnv(k)] = v
    83  	}
    84  	return m
    85  }
    86  
    87  func interpolateConnect(taskEnv *TaskEnv, connect *structs.ConsulConnect) {
    88  	if connect == nil {
    89  		return
    90  	}
    91  
    92  	interpolateConnectSidecarService(taskEnv, connect.SidecarService)
    93  	interpolateConnectSidecarTask(taskEnv, connect.SidecarTask)
    94  	if connect.Gateway != nil {
    95  		interpolateConnectGatewayProxy(taskEnv, connect.Gateway.Proxy)
    96  		interpolateConnectGatewayIngress(taskEnv, connect.Gateway.Ingress)
    97  	}
    98  }
    99  
   100  func interpolateConnectGatewayProxy(taskEnv *TaskEnv, proxy *structs.ConsulGatewayProxy) {
   101  	if proxy == nil {
   102  		return
   103  	}
   104  
   105  	m := make(map[string]*structs.ConsulGatewayBindAddress, len(proxy.EnvoyGatewayBindAddresses))
   106  	for k, v := range proxy.EnvoyGatewayBindAddresses {
   107  		m[taskEnv.ReplaceEnv(k)] = &structs.ConsulGatewayBindAddress{
   108  			Address: taskEnv.ReplaceEnv(v.Address),
   109  			Port:    v.Port,
   110  		}
   111  	}
   112  
   113  	proxy.EnvoyGatewayBindAddresses = m
   114  	proxy.Config = interpolateMapStringInterface(taskEnv, proxy.Config)
   115  }
   116  
   117  func interpolateConnectGatewayIngress(taskEnv *TaskEnv, ingress *structs.ConsulIngressConfigEntry) {
   118  	if ingress == nil {
   119  		return
   120  	}
   121  
   122  	for _, listener := range ingress.Listeners {
   123  		listener.Protocol = taskEnv.ReplaceEnv(listener.Protocol)
   124  		for _, service := range listener.Services {
   125  			service.Name = taskEnv.ReplaceEnv(service.Name)
   126  			service.Hosts = taskEnv.ParseAndReplace(service.Hosts)
   127  		}
   128  	}
   129  }
   130  
   131  func interpolateConnectSidecarService(taskEnv *TaskEnv, sidecar *structs.ConsulSidecarService) {
   132  	if sidecar == nil {
   133  		return
   134  	}
   135  
   136  	sidecar.Port = taskEnv.ReplaceEnv(sidecar.Port)
   137  	sidecar.Tags = taskEnv.ParseAndReplace(sidecar.Tags)
   138  	if sidecar.Proxy != nil {
   139  		sidecar.Proxy.LocalServiceAddress = taskEnv.ReplaceEnv(sidecar.Proxy.LocalServiceAddress)
   140  		if sidecar.Proxy.Expose != nil {
   141  			for i := 0; i < len(sidecar.Proxy.Expose.Paths); i++ {
   142  				sidecar.Proxy.Expose.Paths[i].Protocol = taskEnv.ReplaceEnv(sidecar.Proxy.Expose.Paths[i].Protocol)
   143  				sidecar.Proxy.Expose.Paths[i].ListenerPort = taskEnv.ReplaceEnv(sidecar.Proxy.Expose.Paths[i].ListenerPort)
   144  				sidecar.Proxy.Expose.Paths[i].Path = taskEnv.ReplaceEnv(sidecar.Proxy.Expose.Paths[i].Path)
   145  			}
   146  		}
   147  		for i := 0; i < len(sidecar.Proxy.Upstreams); i++ {
   148  			sidecar.Proxy.Upstreams[i].Datacenter = taskEnv.ReplaceEnv(sidecar.Proxy.Upstreams[i].Datacenter)
   149  			sidecar.Proxy.Upstreams[i].DestinationName = taskEnv.ReplaceEnv(sidecar.Proxy.Upstreams[i].DestinationName)
   150  			sidecar.Proxy.Upstreams[i].LocalBindAddress = taskEnv.ReplaceEnv(sidecar.Proxy.Upstreams[i].LocalBindAddress)
   151  		}
   152  		sidecar.Proxy.Config = interpolateMapStringInterface(taskEnv, sidecar.Proxy.Config)
   153  	}
   154  }
   155  
   156  func interpolateConnectSidecarTask(taskEnv *TaskEnv, task *structs.SidecarTask) {
   157  	if task == nil {
   158  		return
   159  	}
   160  
   161  	task.Driver = taskEnv.ReplaceEnv(task.Driver)
   162  	task.Config = interpolateMapStringInterface(taskEnv, task.Config)
   163  	task.Env = interpolateMapStringString(taskEnv, task.Env)
   164  	task.KillSignal = taskEnv.ReplaceEnv(task.KillSignal)
   165  	task.Meta = interpolateMapStringString(taskEnv, task.Meta)
   166  	interpolateTaskResources(taskEnv, task.Resources)
   167  	task.User = taskEnv.ReplaceEnv(task.User)
   168  }
   169  
   170  func interpolateTaskResources(taskEnv *TaskEnv, resources *structs.Resources) {
   171  	if resources == nil {
   172  		return
   173  	}
   174  
   175  	for i := 0; i < len(resources.Devices); i++ {
   176  		resources.Devices[i].Name = taskEnv.ReplaceEnv(resources.Devices[i].Name)
   177  		// do not interpolate constraints & affinities
   178  	}
   179  
   180  	for i := 0; i < len(resources.Networks); i++ {
   181  		resources.Networks[i].CIDR = taskEnv.ReplaceEnv(resources.Networks[i].CIDR)
   182  		resources.Networks[i].Device = taskEnv.ReplaceEnv(resources.Networks[i].Device)
   183  		resources.Networks[i].IP = taskEnv.ReplaceEnv(resources.Networks[i].IP)
   184  		resources.Networks[i].Mode = taskEnv.ReplaceEnv(resources.Networks[i].Mode)
   185  
   186  		if resources.Networks[i].DNS != nil {
   187  			resources.Networks[i].DNS.Options = taskEnv.ParseAndReplace(resources.Networks[i].DNS.Options)
   188  			resources.Networks[i].DNS.Searches = taskEnv.ParseAndReplace(resources.Networks[i].DNS.Searches)
   189  			resources.Networks[i].DNS.Servers = taskEnv.ParseAndReplace(resources.Networks[i].DNS.Servers)
   190  		}
   191  
   192  		for p := 0; p < len(resources.Networks[i].DynamicPorts); p++ {
   193  			resources.Networks[i].DynamicPorts[p].HostNetwork = taskEnv.ReplaceEnv(resources.Networks[i].DynamicPorts[p].HostNetwork)
   194  			resources.Networks[i].DynamicPorts[p].Label = taskEnv.ReplaceEnv(resources.Networks[i].DynamicPorts[p].Label)
   195  		}
   196  
   197  		for p := 0; p < len(resources.Networks[i].ReservedPorts); p++ {
   198  			resources.Networks[i].ReservedPorts[p].HostNetwork = taskEnv.ReplaceEnv(resources.Networks[i].ReservedPorts[p].HostNetwork)
   199  			resources.Networks[i].ReservedPorts[p].Label = taskEnv.ReplaceEnv(resources.Networks[i].ReservedPorts[p].Label)
   200  		}
   201  	}
   202  }