...

Source file src/github.com/datawire/ambassador/v2/cmd/entrypoint/testutil_fake_syntheticauth_test.go

Documentation: github.com/datawire/ambassador/v2/cmd/entrypoint

     1  package entrypoint_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/datawire/ambassador/v2/cmd/entrypoint"
    11  	v3bootstrap "github.com/datawire/ambassador/v2/pkg/api/envoy/config/bootstrap/v3"
    12  	v3cluster "github.com/datawire/ambassador/v2/pkg/api/envoy/config/cluster/v3"
    13  	"github.com/datawire/ambassador/v2/pkg/snapshot/v1"
    14  )
    15  
    16  // This predicate is used to check k8s snapshots for an AuthService matching the provided name and
    17  // namespace.
    18  func HasAuthService(namespace, name string) func(snapshot *snapshot.Snapshot) bool {
    19  	return func(snapshot *snapshot.Snapshot) bool {
    20  		for _, m := range snapshot.Kubernetes.AuthServices {
    21  			if m.Namespace == namespace && m.Name == name {
    22  				return true
    23  			}
    24  		}
    25  		return false
    26  	}
    27  }
    28  
    29  // Tests the synthetic auth generation when a valid AuthService is created.  This AuthService has
    30  // `protocol_version: v3` and should not be replaced by the synthetic AuthService.
    31  func TestSyntheticAuthValid(t *testing.T) {
    32  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
    33  		apiVersion := apiVersion // capture loop variable
    34  		t.Run(apiVersion, func(t *testing.T) {
    35  			t.Setenv("EDGE_STACK", "true")
    36  
    37  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
    38  
    39  			err := f.UpsertYAML(`
    40  ---
    41  apiVersion: getambassador.io/` + apiVersion + `
    42  kind: AuthService
    43  metadata:
    44    name: edge-stack-auth-test
    45    namespace: foo
    46  spec:
    47    auth_service: 127.0.0.1:8500
    48    protocol_version: "v3"
    49    proto: "grpc"
    50  `)
    51  			assert.NoError(t, err)
    52  			f.Flush()
    53  
    54  			// Use the predicate above to check that the snapshot contains the
    55  			// AuthService defined above.  The AuthService has `protocol_version: v3` so
    56  			// it should not be removed/replaced by the synthetic AuthService injected
    57  			// by syntheticauth.go
    58  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
    59  			assert.NoError(t, err)
    60  			assert.NotNil(t, snap)
    61  
    62  			// In edge-stack we should only ever have 1 AuthService.
    63  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
    64  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
    65  
    66  			// Check for an ext_authz cluster name matching the provided AuthService
    67  			// (Http_Filters are harder to check since they always have the same name).
    68  			// The namespace for this extauthz cluster should be foo (since that is the
    69  			// namespace of the valid AuthService above).
    70  			isAuthCluster := func(c *v3cluster.Cluster) bool {
    71  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
    72  			}
    73  
    74  			// Grab the next Envoy config that has an Edge Stack auth cluster on
    75  			// 127.0.0.1:8500
    76  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
    77  				return FindCluster(envoy, isAuthCluster) != nil
    78  			})
    79  			require.NoError(t, err)
    80  
    81  			// Make sure an Envoy Config containing a extauth cluster for the
    82  			// AuthService that was defined.
    83  			assert.NotNil(t, envoyConfig)
    84  		})
    85  	}
    86  }
    87  
    88  // This tests with a provided AuthService that has no protocol_version (which defaults to v2).  It
    89  // should get forcibly overridden to be v3.
    90  func TestSyntheticAuthReplace(t *testing.T) {
    91  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
    92  		apiVersion := apiVersion // capture loop variable
    93  		t.Run(apiVersion, func(t *testing.T) {
    94  			t.Setenv("EDGE_STACK", "true")
    95  
    96  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
    97  
    98  			err := f.UpsertYAML(`
    99  ---
   100  apiVersion: getambassador.io/` + apiVersion + `
   101  kind: AuthService
   102  metadata:
   103    name: edge-stack-auth-test
   104    namespace: foo
   105  spec:
   106    auth_service: 127.0.0.1:8500
   107    proto: "grpc"
   108  `)
   109  			assert.NoError(t, err)
   110  			f.Flush()
   111  
   112  			// The AuthService does not have `protocol_version: v3` so it should be
   113  			// forcibly edited to say `protocol_version: v3` by syntheticauth.go
   114  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   115  			assert.NoError(t, err)
   116  			assert.NotNil(t, snap)
   117  
   118  			// In edge-stack we should only ever have 1 AuthService.
   119  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   120  			// The snapshot should only have the one defined above.
   121  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   122  			// The protocol version should be forcibly set to v3.
   123  			assert.Equal(t, "v3", snap.Kubernetes.AuthServices[0].Spec.ProtocolVersion)
   124  
   125  			// Check for an ext_authz cluster name matching the provided AuthService
   126  			// (Http_Filters are harder to check since they always have the same name).
   127  			// The namespace for this extauthz cluster should be "foo" (since that is
   128  			// the namespace of the AuthService).
   129  			isAuthCluster := func(c *v3cluster.Cluster) bool {
   130  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   131  			}
   132  
   133  			// Grab the next Envoy config that has an Edge Stack auth cluster on
   134  			// 127.0.0.1:8500
   135  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   136  				return FindCluster(envoy, isAuthCluster) != nil
   137  			})
   138  			require.NoError(t, err)
   139  
   140  			// Make sure an Envoy Config containing a extauth cluster for the
   141  			// AuthService that was defined.
   142  			assert.NotNil(t, envoyConfig)
   143  		})
   144  	}
   145  }
   146  
   147  // Tests the synthetic auth generation when an invalid AuthService is created.  This AuthService has
   148  // `protocol_version: v3` and should not be replaced by the synthetic AuthService even though it has
   149  // a bogus value because the bogus field will be dropped when it is loaded and we will be left with
   150  // a valid AuthService.
   151  func TestSyntheticAuthBogusField(t *testing.T) {
   152  	for _, apiVersion := range []string{"v2", "v3alpha1"} {
   153  		apiVersion := apiVersion // capture loop variable
   154  		t.Run(apiVersion, func(t *testing.T) {
   155  			t.Setenv("EDGE_STACK", "true")
   156  
   157  			f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   158  
   159  			err := f.UpsertYAML(`
   160  ---
   161  apiVersion: getambassador.io/` + apiVersion + `
   162  kind: AuthService
   163  metadata:
   164    name: edge-stack-auth-test
   165    namespace: foo
   166  spec:
   167    auth_service: 127.0.0.1:8500
   168    protocol_version: "v3"
   169    proto: "grpc"
   170    bogus_field: "foo"
   171  `)
   172  			assert.NoError(t, err)
   173  			f.Flush()
   174  
   175  			// Use the predicate above to check that the snapshot contains the
   176  			// AuthService defined above.  The AuthService has `protocol_version: v3` so
   177  			// it should not be removed/replaced by the synthetic AuthService injected
   178  			// by syntheticauth.go
   179  			snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   180  			assert.NoError(t, err)
   181  			assert.NotNil(t, snap)
   182  
   183  			// In edge-stack we should only ever have 1 AuthService.
   184  			assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   185  			assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   186  
   187  			// Check for an ext_authz cluster name matching the provided AuthService
   188  			// (Http_Filters are harder to check since they always have the same name).
   189  			// The namespace for this extauthz cluster should be "foo" (since that is
   190  			// the namespace of the valid AuthService above).
   191  			isAuthCluster := func(c *v3cluster.Cluster) bool {
   192  				return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   193  			}
   194  
   195  			// Grab the next Envoy config that has an Edge Stack auth cluster on
   196  			// 127.0.0.1:8500
   197  			envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   198  				return FindCluster(envoy, isAuthCluster) != nil
   199  			})
   200  			require.NoError(t, err)
   201  
   202  			// Make sure an Envoy Config containing a extauth cluster for the
   203  			// AuthService that was defined.
   204  			assert.NotNil(t, envoyConfig)
   205  		})
   206  	}
   207  }
   208  
   209  // Tests the synthetic auth generation when an invalid AuthService (because the protocol_version is
   210  // invalid for the supported enums).  This AuthService should be tossed out an the synthetic
   211  // AuthService should be injected.
   212  func TestSyntheticAuthInvalidProtocolVer(t *testing.T) {
   213  	t.Setenv("EDGE_STACK", "true")
   214  
   215  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   216  
   217  	err := f.UpsertYAML(`
   218  ---
   219  apiVersion: getambassador.io/v2
   220  kind: AuthService
   221  metadata:
   222    name: edge-stack-auth-test
   223    namespace: foo
   224  spec:
   225    auth_service: 127.0.0.1:8500
   226    protocol_version: "vBogus"
   227    proto: "grpc"
   228    bogus_field: "foo"
   229  `)
   230  	assert.NoError(t, err)
   231  	f.Flush()
   232  
   233  	// Use the predicate above to check that the snapshot contains the synthetic AuthService.
   234  	// The AuthService has `protocol_version: v3`, but it has a bogus field so it should not be
   235  	// validated and instead we inject the synthetic AuthService.
   236  	snap, err := f.GetSnapshot(HasAuthService("default", "synthetic_edge_stack_auth"))
   237  	assert.NoError(t, err)
   238  	assert.NotNil(t, snap)
   239  
   240  	// In edge-stack we should only ever have 1 AuthService.
   241  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   242  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   243  	assert.Equal(t, "synthetic_edge_stack_auth", snap.Kubernetes.AuthServices[0].Name)
   244  
   245  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   246  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   247  	// AuthService).
   248  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   249  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_default")
   250  	}
   251  
   252  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   253  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   254  		return FindCluster(envoy, isAuthCluster) != nil
   255  	})
   256  	require.NoError(t, err)
   257  
   258  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   259  	// defined.
   260  	assert.NotNil(t, envoyConfig)
   261  
   262  	t.Setenv("EDGE_STACK", "")
   263  }
   264  
   265  // Tests the synthetic auth generation when an invalid AuthService is created and edited several
   266  // times in succession.  After the config is edited several times, we should see that the final
   267  // result is our provided valid AuthService.  There should not be any duplicate AuthService
   268  // resources, and the synthetic AuthService that gets created when the first invalid AuthService is
   269  // applied should be removed when the final edit makes it a valid AuthService.
   270  func TestSyntheticAuthChurn(t *testing.T) {
   271  	t.Setenv("EDGE_STACK", "true")
   272  
   273  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   274  	f.AutoFlush(true)
   275  
   276  	err := f.UpsertYAML(`
   277  ---
   278  apiVersion: getambassador.io/v3alpha1
   279  kind: AuthService
   280  metadata:
   281    name: edge-stack-auth-test
   282    namespace: foo
   283  spec:
   284    auth_service: 127.0.0.1:8500
   285    proto: "grpc"
   286  `)
   287  	assert.NoError(t, err)
   288  	err = f.UpsertYAML(`
   289  ---
   290  apiVersion: getambassador.io/v3alpha1
   291  kind: AuthService
   292  metadata:
   293    name: edge-stack-auth-test
   294    namespace: foo
   295  spec:
   296    auth_service: 127.0.0.1:8500
   297    protocol_version: "v3"
   298    proto: "grpc"
   299  `)
   300  	assert.NoError(t, err)
   301  	err = f.UpsertYAML(`
   302  ---
   303  apiVersion: getambassador.io/v3alpha1
   304  kind: AuthService
   305  metadata:
   306    name: edge-stack-auth-test
   307    namespace: foo
   308  spec:
   309    auth_service: 127.0.0.1:8500
   310    proto: "grpc"
   311  `)
   312  	assert.NoError(t, err)
   313  	err = f.UpsertYAML(`
   314  ---
   315  apiVersion: getambassador.io/v3alpha1
   316  kind: AuthService
   317  metadata:
   318    name: edge-stack-auth-test
   319    namespace: foo
   320  spec:
   321    auth_service: 127.0.0.1:8500
   322    protocol_version: "v3"
   323    proto: "grpc"
   324  `)
   325  	assert.NoError(t, err)
   326  
   327  	// Use the predicate above to check that the snapshot contains the AuthService defined
   328  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   329  	// by the synthetic AuthService injected by syntheticauth.go
   330  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   331  	assert.NoError(t, err)
   332  	assert.NotNil(t, snap)
   333  
   334  	// In edge-stack we should only ever have 1 AuthService.
   335  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   336  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   337  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   338  
   339  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   340  	// harder to check since they always have the same name).  The namespace for this extauthz
   341  	// cluster should be foo (since that is the namespace of the valid AuthService above)
   342  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   343  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   344  	}
   345  
   346  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   347  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   348  		return FindCluster(envoy, isAuthCluster) != nil
   349  	})
   350  	require.NoError(t, err)
   351  
   352  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was defined
   353  	assert.NotNil(t, envoyConfig)
   354  
   355  	t.Setenv("EDGE_STACK", "")
   356  }
   357  
   358  // Tests the synthetic auth generation by first creating an invalid AuthService and confirming that
   359  // the synthetic AuthService gets injected.  Afterwards, a valid AuthService is applied and we
   360  // expect the synthetic AuthService to be removed in favor of the new valid AuthService.
   361  func TestSyntheticAuthInjectAndRemove(t *testing.T) {
   362  	t.Setenv("EDGE_STACK", "true")
   363  
   364  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   365  	f.AutoFlush(true)
   366  
   367  	// This will cause a synthethic AuthService to be injected.
   368  	err := f.UpsertYAML(`
   369  ---
   370  apiVersion: getambassador.io/v3alpha1
   371  kind: AuthService
   372  metadata:
   373    name: edge-stack-auth-test
   374    namespace: foo
   375  spec:
   376    auth_service: 127.0.0.1:8500
   377    proto: "grpc"
   378    protocol_version: "vBogus"
   379  `)
   380  	assert.NoError(t, err)
   381  
   382  	// Use the predicate above to check that the snapshot contains the synthetic AuthService.
   383  	// The user-provided AuthService is invalid and so it should be ignored and instead we
   384  	// inject the synthetic AuthService.
   385  	snap, err := f.GetSnapshot(HasAuthService("default", "synthetic_edge_stack_auth"))
   386  	assert.NoError(t, err)
   387  	assert.NotNil(t, snap)
   388  
   389  	// We should only have 1 AuthService.
   390  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   391  	// The snapshot should only have the synthetic AuthService and not the one defined above.
   392  	assert.Equal(t, "synthetic_edge_stack_auth", snap.Kubernetes.AuthServices[0].Name)
   393  
   394  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   395  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   396  	// AuthService).
   397  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   398  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_default")
   399  	}
   400  
   401  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   402  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   403  		return FindCluster(envoy, isAuthCluster) != nil
   404  	})
   405  	require.NoError(t, err)
   406  
   407  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   408  	// defined.
   409  	assert.NotNil(t, envoyConfig)
   410  
   411  	// Updating the yaml for that AuthService to include `protocol_version: v3` should make it
   412  	// valid and then remove our synthetic AuthService and allow the now valid AuthService to be
   413  	// used.
   414  	err = f.UpsertYAML(`
   415  ---
   416  apiVersion: getambassador.io/v3alpha1
   417  kind: AuthService
   418  metadata:
   419    name: edge-stack-auth-test
   420    namespace: foo
   421  spec:
   422    auth_service: 127.0.0.1:8500
   423    protocol_version: "v3"
   424    proto: "grpc"
   425  `)
   426  	assert.NoError(t, err)
   427  
   428  	// Use the predicate above to check that the snapshot contains the AuthService defined
   429  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   430  	// by the synthetic AuthService injected by syntheticauth.go
   431  	snap, err = f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   432  	assert.NoError(t, err)
   433  	assert.NotNil(t, snap)
   434  
   435  	// In edge-stack we should only ever have 1 AuthService.
   436  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   437  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   438  
   439  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   440  	// harder to check since they always have the same name).  The namespace for this extauthz
   441  	// cluster should be foo (since that is the namespace of the valid AuthService above).
   442  	isAuthCluster = func(c *v3cluster.Cluster) bool {
   443  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   444  	}
   445  
   446  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   447  	envoyConfig, err = f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   448  		return FindCluster(envoy, isAuthCluster) != nil
   449  	})
   450  	require.NoError(t, err)
   451  
   452  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   453  	// defined.
   454  	assert.NotNil(t, envoyConfig)
   455  
   456  	t.Setenv("EDGE_STACK", "")
   457  
   458  }
   459  
   460  // This AuthService points at 127.0.0.1:8500, but it does not have `protocol_version: v3`.  It also
   461  // has additional fields set.  The correct action is to edit the AuthService to say
   462  // `protocol_version: v3`.
   463  func TestSyntheticAuthCopyFields(t *testing.T) {
   464  	t.Setenv("EDGE_STACK", "true")
   465  
   466  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   467  
   468  	err := f.UpsertYAML(`
   469  ---
   470  apiVersion: getambassador.io/v2
   471  kind: AuthService
   472  metadata:
   473    name: edge-stack-auth-test
   474    namespace: foo
   475  spec:
   476    auth_service: 127.0.0.1:8500
   477    proto: "grpc"
   478    timeout_ms: 12345
   479  
   480  `)
   481  	assert.NoError(t, err)
   482  	f.Flush()
   483  
   484  	// Use the predicate above to check that the snapshot contains the AuthService.
   485  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   486  	assert.NoError(t, err)
   487  	assert.NotNil(t, snap)
   488  
   489  	// In edge-stack we should only ever have 1 AuthService.
   490  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   491  	// It should be that user-provided AuthService...
   492  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   493  	assert.Equal(t, int64(12345), snap.Kubernetes.AuthServices[0].Spec.Timeout.Duration.Milliseconds())
   494  	// ... but with `protocol_version: v3` set.
   495  	assert.Equal(t, "v3", snap.Kubernetes.AuthServices[0].Spec.ProtocolVersion)
   496  
   497  	// Check for an ext_authz cluster name matching the synthetic AuthService.  The namespace
   498  	// for this extauthz cluster should be default (since that is the namespace of the synthetic
   499  	// AuthService).
   500  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   501  		return strings.Contains(c.Name, "cluster_extauth_127_0_0_1_8500_foo")
   502  	}
   503  
   504  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   505  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   506  		return FindCluster(envoy, isAuthCluster) != nil
   507  	})
   508  	require.NoError(t, err)
   509  
   510  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   511  	// defined.
   512  	assert.NotNil(t, envoyConfig)
   513  
   514  	t.Setenv("EDGE_STACK", "")
   515  }
   516  
   517  // This AuthService does not point at 127.0.0.1:8500, we leave it alone rather than adding a
   518  // synthetic one.
   519  func TestSyntheticAuthCustomAuthService(t *testing.T) {
   520  	t.Setenv("EDGE_STACK", "true")
   521  
   522  	f := entrypoint.RunFake(t, entrypoint.FakeConfig{EnvoyConfig: true}, nil)
   523  
   524  	err := f.UpsertYAML(`
   525  ---
   526  apiVersion: getambassador.io/v2
   527  kind: AuthService
   528  metadata:
   529    name: edge-stack-auth-test
   530    namespace: foo
   531  spec:
   532    auth_service: dummy-service
   533    proto: "grpc"
   534  `)
   535  
   536  	assert.NoError(t, err)
   537  	f.Flush()
   538  
   539  	// Use the predicate above to check that the snapshot contains the AuthService defined
   540  	// above.  The AuthService has `protocol_version: v3` so it should not be removed/replaced
   541  	// by the synthetic AuthService injected by syntheticauth.go
   542  	snap, err := f.GetSnapshot(HasAuthService("foo", "edge-stack-auth-test"))
   543  	assert.NoError(t, err)
   544  	assert.NotNil(t, snap)
   545  
   546  	// In edge-stack we should only ever have 1 AuthService.
   547  	assert.Equal(t, 1, len(snap.Kubernetes.AuthServices))
   548  	assert.Equal(t, "edge-stack-auth-test", snap.Kubernetes.AuthServices[0].Name)
   549  
   550  	for _, authService := range snap.Kubernetes.AuthServices {
   551  		assert.Equal(t, "dummy-service", authService.Spec.AuthService)
   552  	}
   553  
   554  	// Check for an ext_authz cluster name matching the provided AuthService (Http_Filters are
   555  	// harder to check since they always have the same name).  the namespace for this extauthz
   556  	// cluster should be foo (since that is the namespace of the valid AuthService above).
   557  	isAuthCluster := func(c *v3cluster.Cluster) bool {
   558  		return strings.Contains(c.Name, "cluster_extauth_dummy_service_foo")
   559  	}
   560  
   561  	// Grab the next Envoy config that has an Edge Stack auth cluster on 127.0.0.1:8500
   562  	envoyConfig, err := f.GetEnvoyConfig(func(envoy *v3bootstrap.Bootstrap) bool {
   563  		return FindCluster(envoy, isAuthCluster) != nil
   564  	})
   565  	require.NoError(t, err)
   566  
   567  	// Make sure an Envoy Config containing a extauth cluster for the AuthService that was
   568  	// defined.
   569  	assert.NotNil(t, envoyConfig)
   570  
   571  	t.Setenv("EDGE_STACK", "")
   572  }
   573  
   574  // When deciding if we need to inject a synthetic AuthService or not, we need to be able to reliably
   575  // determine if that AuthService points at a localhost:8500 or not.
   576  func TestIsLocalhost8500(t *testing.T) {
   577  	t.Parallel()
   578  
   579  	type subtest struct {
   580  		inputAddr string
   581  		expected  bool
   582  	}
   583  
   584  	subtests := []subtest{
   585  		{inputAddr: "127.0.0.1:8500", expected: true},
   586  		{inputAddr: "localhost:8500", expected: true},
   587  		{inputAddr: "127.1.2.3:8500", expected: true},
   588  		// IPv6:
   589  		{inputAddr: "http://[0::1]:8500", expected: true},
   590  		{inputAddr: "http://[0:0:0::1]:8500", expected: true},
   591  		{inputAddr: "http://[::0:0:0:1]:8500", expected: true},
   592  
   593  		{inputAddr: "127.0.0.1:850", expected: false},
   594  		{inputAddr: "127.0.0.1:8080", expected: false},
   595  		{inputAddr: "192.168.2.10:8500", expected: false},
   596  		{inputAddr: "", expected: false},
   597  		// IPv6:
   598  		{inputAddr: "http://[0::1]:8400", expected: false},
   599  		{inputAddr: "http://[0::2]:8500", expected: false},
   600  		{inputAddr: "http://[0::2]:8080", expected: false},
   601  		{inputAddr: "http://[0:0:0::2]:8500", expected: false},
   602  		{inputAddr: "http://[0:0:0::1]:8080", expected: false},
   603  		{inputAddr: "http://[::0:0:0:2]:8500", expected: false},
   604  		{inputAddr: "http://[::0:0:0:2]:8080", expected: false},
   605  	}
   606  
   607  	for _, subtest := range subtests {
   608  		subtest := subtest // capture loop variable
   609  		t.Run(subtest.inputAddr, func(t *testing.T) {
   610  			t.Parallel()
   611  			res := entrypoint.IsLocalhost8500(subtest.inputAddr)
   612  			assert.Equal(t, subtest.expected, res)
   613  		})
   614  	}
   615  }
   616  

View as plain text