...

Source file src/github.com/emissary-ingress/emissary/v3/cmd/entrypoint/env.go

Documentation: github.com/emissary-ingress/emissary/v3/cmd/entrypoint

     1  package entrypoint
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/datawire/dlib/dexec"
    13  	"github.com/datawire/dlib/dlog"
    14  )
    15  
    16  func GetAgentService() string {
    17  	// Using an agent service is no longer supported, so return empty.
    18  	// For good measure, we also set AGENT_SERVICE to empty in the entrypoint.
    19  	return ""
    20  }
    21  
    22  func GetAmbassadorID() string {
    23  	id := os.Getenv("AMBASSADOR_ID")
    24  	if id != "" {
    25  		return id
    26  	}
    27  	svc := GetAgentService()
    28  	if svc != "" {
    29  		return fmt.Sprintf("intercept-%s", svc)
    30  	}
    31  	return "default"
    32  }
    33  
    34  func GetAmbassadorNamespace() string {
    35  	return env("AMBASSADOR_NAMESPACE", "default")
    36  }
    37  
    38  func GetAmbassadorFieldSelector() string {
    39  	return env("AMBASSADOR_FIELD_SELECTOR", "")
    40  }
    41  
    42  func GetAmbassadorLabelSelector() string {
    43  	return env("AMBASSADOR_LABEL_SELECTOR", "")
    44  }
    45  
    46  func GetAmbassadorRoot() string {
    47  	return env("ambassador_root", "/ambassador")
    48  }
    49  
    50  func GetHomeDir() string {
    51  	return env("HOME", "/tmp/ambassador")
    52  }
    53  
    54  func GetAmbassadorConfigBaseDir() string {
    55  	return env("AMBASSADOR_CONFIG_BASE_DIR", GetAmbassadorRoot())
    56  }
    57  
    58  func GetEnvoyDir() string {
    59  	return env("ENVOY_DIR", path.Join(GetAmbassadorConfigBaseDir(), "envoy"))
    60  }
    61  
    62  func GetEnvoyConcurrency() string {
    63  	return env("ENVOY_CONCURRENCY", "")
    64  }
    65  
    66  func GetEnvoyBootstrapFile() string {
    67  	return env("ENVOY_BOOTSTRAP_FILE", path.Join(GetAmbassadorConfigBaseDir(), "bootstrap-ads.json"))
    68  }
    69  
    70  func GetEnvoyBaseID() string {
    71  	return env("AMBASSADOR_ENVOY_BASE_ID", "0")
    72  }
    73  
    74  func GetAppDir() string {
    75  	return env("APPDIR", GetAmbassadorRoot())
    76  }
    77  
    78  // GetConfigDir returns the path to the directory we should check for
    79  // filesystem config.
    80  func GetConfigDir(demoMode bool) string {
    81  	// XXX There was no way to override the config dir via the environment in
    82  	// entrypoint.sh.
    83  	configDir := env("AMBASSADOR_CONFIG_DIR", path.Join(GetAmbassadorConfigBaseDir(), "ambassador-config"))
    84  
    85  	if demoMode {
    86  		// There is _intentionally_ no way to override the demo-mode config directory,
    87  		// and it is _intentionally_ based on the root directory rather than on
    88  		// AMBASSADOR_CONFIG_BASE_DIR: it's baked into a specific location during
    89  		// the build process.
    90  		configDir = path.Join(GetAmbassadorRoot(), "ambassador-demo-config")
    91  	}
    92  
    93  	return configDir
    94  }
    95  
    96  // ConfigIsPresent checks to see if any configuration is actually present
    97  // in the given configdir.
    98  func ConfigIsPresent(ctx context.Context, configDir string) bool {
    99  	// Is there anything in this directory?
   100  	foundAny := false
   101  
   102  	_ = filepath.Walk(configDir, func(path string, info os.FileInfo, err error) error {
   103  		// If we're handed an error coming in, something has gone wrong and we _must_
   104  		// return the error to avoid a panic. (The most likely error, admittedly, is
   105  		// simply that the toplevel directory doesn't exist.)
   106  		if err != nil {
   107  			// Log it, but if it isn't an os.ErrNoExist().
   108  			if !os.IsNotExist(err) {
   109  				dlog.Errorf(ctx, "Error scanning config file %s: %s", filepath.Join(configDir, path), err)
   110  			}
   111  
   112  			return err
   113  		}
   114  
   115  		if (info.Mode() & os.ModeType) == 0 {
   116  			// This is a regular file, so we can consider this valid config.
   117  			foundAny = true
   118  
   119  			// Return an error in order to short-circuit the rest of the walk.
   120  			// This is kind of an abuse, honestly, but then we also don't want
   121  			// to spend a long time walking crap if someone sets the environment
   122  			// variable incorrectly -- and if we run into an actual error walking
   123  			// the config dir, see the comment above.
   124  			return errors.New("not really an errore")
   125  		}
   126  
   127  		return nil
   128  	})
   129  
   130  	// Done. We don't care what the walk actually returned, we only care
   131  	// about foundAny.
   132  	return foundAny
   133  }
   134  
   135  func GetSnapshotDir() string {
   136  	return env("snapshot_dir", path.Join(GetAmbassadorConfigBaseDir(), "snapshots"))
   137  }
   138  
   139  func GetEnvoyConfigFile() string {
   140  	return env("envoy_config_file", path.Join(GetEnvoyDir(), "envoy.json"))
   141  }
   142  
   143  func GetAmbassadorDebug() string {
   144  	return env("AMBASSADOR_DEBUG", "")
   145  }
   146  
   147  func isDebug(name string) bool {
   148  	return strings.Contains(GetAmbassadorDebug(), name)
   149  }
   150  
   151  func GetEnvoyFlags() []string {
   152  	result := []string{"-c", GetEnvoyBootstrapFile(), "--base-id", GetEnvoyBaseID()}
   153  	svc := GetAgentService()
   154  	if svc != "" {
   155  		result = append(result, "--drain-time-s", "1")
   156  	} else {
   157  		result = append(result, "--drain-time-s", env("AMBASSADOR_DRAIN_TIME", "600"))
   158  	}
   159  	if isDebug("envoy") {
   160  		result = append(result, "-l", "trace")
   161  	} else {
   162  		result = append(result, "-l", "error")
   163  	}
   164  	concurrency := GetEnvoyConcurrency()
   165  	if concurrency != "" {
   166  		result = append(result, "--concurrency", concurrency)
   167  	}
   168  	return result
   169  }
   170  
   171  func GetDiagdBindAddress() string {
   172  	return env("AMBASSADOR_DIAGD_BIND_ADDREASS", "")
   173  }
   174  
   175  func IsDiagdOnly() bool {
   176  	return envbool("DIAGD_ONLY")
   177  }
   178  
   179  // ForceEndpoints reflects AMBASSADOR_FORCE_ENDPOINTS, to determine whether
   180  // we're forcing endpoint watching or (the default) not.
   181  func ForceEndpoints() bool {
   182  	return envbool("AMBASSADOR_FORCE_ENDPOINTS")
   183  }
   184  
   185  func GetDiagdBindPort() string {
   186  	return env("AMBASSADOR_DIAGD_BIND_PORT", "8004")
   187  }
   188  
   189  func IsEnvoyAvailable() bool {
   190  	_, err := dexec.LookPath("envoy")
   191  	return err == nil
   192  }
   193  
   194  func GetDiagdFlags(ctx context.Context, demoMode bool) []string {
   195  	result := []string{"--notices", path.Join(GetAmbassadorConfigBaseDir(), "notices.json")}
   196  
   197  	if isDebug("diagd") {
   198  		result = append(result, "--debug")
   199  	}
   200  
   201  	diagdBind := GetDiagdBindAddress()
   202  	if diagdBind != "" {
   203  		result = append(result, "--host", diagdBind)
   204  	}
   205  
   206  	// XXX: this was not in entrypoint.sh
   207  	result = append(result, "--port", GetDiagdBindPort())
   208  
   209  	cdir := GetConfigDir(demoMode)
   210  
   211  	if (cdir != "") && ConfigIsPresent(ctx, cdir) {
   212  		result = append(result, "--config-path", cdir)
   213  	}
   214  
   215  	if IsDiagdOnly() {
   216  		result = append(result, "--no-checks", "--no-envoy")
   217  	} else {
   218  		result = append(result, "--kick", fmt.Sprintf("kill -HUP %d", os.Getpid()))
   219  		// XXX: this was not in entrypoint.sh
   220  		if !IsEnvoyAvailable() {
   221  			result = append(result, "--no-envoy")
   222  		}
   223  	}
   224  
   225  	return result
   226  }
   227  
   228  func GetDiagdArgs(ctx context.Context, demoMode bool) []string {
   229  	return append(
   230  		[]string{
   231  			GetSnapshotDir(),
   232  			GetEnvoyBootstrapFile(),
   233  			GetEnvoyConfigFile(),
   234  		},
   235  		GetDiagdFlags(ctx, demoMode)...,
   236  	)
   237  }
   238  
   239  func IsAmbassadorSingleNamespace() bool {
   240  	return envbool("AMBASSADOR_SINGLE_NAMESPACE")
   241  }
   242  
   243  func IsEdgeStack() (bool, error) {
   244  	if envbool("EDGE_STACK") {
   245  		return true, nil
   246  	}
   247  	_, err := os.Stat("/ambassador/.edge_stack")
   248  	if err == nil {
   249  		return true, nil
   250  	} else if os.IsNotExist(err) {
   251  		return false, nil
   252  	} else {
   253  		return false, err
   254  	}
   255  }
   256  
   257  func GetLicenseSecretName() string {
   258  	return env("AMBASSADOR_AES_SECRET_NAME", "ambassador-edge-stack")
   259  }
   260  
   261  func GetLicenseSecretNamespace() string {
   262  	return env("AMBASSADOR_AES_SECRET_NAMESPACE", GetAmbassadorNamespace())
   263  }
   264  
   265  func GetCloudConnectTokenResourceName() string {
   266  	return env("AGENT_CONFIG_RESOURCE_NAME", "ambassador-agent-cloud-token")
   267  }
   268  
   269  func GetCloudConnectTokenResourceNamespace() string {
   270  	return env("AGENT_NAMESPACE", GetAmbassadorNamespace())
   271  }
   272  
   273  func GetEventHost() string {
   274  	return env("DEV_AMBASSADOR_EVENT_HOST", fmt.Sprintf("http://localhost:%s", GetDiagdBindPort()))
   275  }
   276  
   277  func GetEventPath() string {
   278  	return env("DEV_AMBASSADOR_EVENT_PATH", fmt.Sprintf("_internal/v0"))
   279  }
   280  
   281  func GetSidecarHost() string {
   282  	return env("DEV_AMBASSADOR_SIDECAR_HOST", "http://localhost:8500")
   283  }
   284  
   285  func GetSidecarPath() string {
   286  	return env("DEV_AMBASSADOR_SIDECAR_PATH", "_internal/v0")
   287  }
   288  
   289  func GetEventUrl() string {
   290  	return fmt.Sprintf("%s/%s/watt", GetEventHost(), GetEventPath())
   291  }
   292  
   293  func GetSidecarUrl() string {
   294  	return fmt.Sprintf("%s/%s/watt", GetSidecarHost(), GetSidecarPath())
   295  }
   296  
   297  func IsKnativeEnabled() bool {
   298  	return strings.ToLower(env("AMBASSADOR_KNATIVE_SUPPORT", "")) == "true"
   299  }
   300  
   301  // getHealthCheckHost will return address that the health check server will bind to.
   302  // If not provided it will default to all interfaces (`0.0.0.0`).
   303  func getHealthCheckHost() string {
   304  	return env("AMBASSADOR_HEALTHCHECK_BIND_ADDRESS", "0.0.0.0")
   305  }
   306  
   307  // getHealthCheckPort will return the port that the health check server will bind to.
   308  // If not provided it will default to port `8877`
   309  func getHealthCheckPort() string {
   310  	return env("AMBASSADOR_HEALTHCHECK_BIND_PORT", "8877")
   311  }
   312  
   313  // getHealthCheckIPNetworkFamily will return the network IP family that the health checker server
   314  // will listen on. Set the AMBASSADOR_HEALTHCHECK_IP_FAMILIY environment variable to
   315  // "ANY", "IPV4_ONLY" or "IPV6_ONLY".
   316  //
   317  // Here is a list of supported values and how they translate to the supported
   318  // net.Listen networks:
   319  //   - ANY => tcp (default)
   320  //   - IPV4_ONLY => tcp4
   321  //   - IPV6_ONLY => tcp6
   322  func getHealthCheckIPNetworkFamily() string {
   323  	ipFamily := strings.ToUpper(env("AMBASSADOR_HEALTHCHECK_IP_FAMILY", "ANY"))
   324  
   325  	switch ipFamily {
   326  	case "IPV4_ONLY":
   327  		return "tcp4"
   328  	case "IPV6_ONLY":
   329  		return "tcp6"
   330  	}
   331  	return "tcp"
   332  }
   333  

View as plain text