diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0d51cf83..75490490 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,8 +24,8 @@ jobs: run: make test - name: Run OSS acceptance tests run: | - curl -LO https://releases.hashicorp.com/consul/1.15.2/consul_1.15.2_linux_amd64.zip - sudo unzip consul_1.15.2_linux_amd64.zip consul -d /usr/local/bin + curl -LO https://releases.hashicorp.com/consul/1.16.0/consul_1.16.0_linux_amd64.zip + sudo unzip consul_1.16.0_linux_amd64.zip consul -d /usr/local/bin SKIP_REMOTE_DATACENTER_TESTS=1 make testacc TESTARGS="-count=1" - name: Run go vet run: make vet diff --git a/consul/resource_consul_config_entry_ce_test.go b/consul/resource_consul_config_entry_ce_test.go index e9363f23..6390d265 100644 --- a/consul/resource_consul_config_entry_ce_test.go +++ b/consul/resource_consul_config_entry_ce_test.go @@ -78,21 +78,24 @@ func TestAccConsulConfigEntryCE_basic(t *testing.T) { ), }, { - Config: testAccConsulConfigEntryCE_ServiceConfigL4, + Config: testAccConsulConfigEntryCE_ServiceConfigL4, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "api-service"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), ), }, { - Config: testAccConsulConfigEntryCE_ServiceConfigL7, + Config: testAccConsulConfigEntryCE_ServiceConfigL7, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "fort-knox"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), ), }, { - Config: testAccConsulConfigEntryCE_ServiceConfigL7b, + Config: testAccConsulConfigEntryCE_ServiceConfigL7b, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "api"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), @@ -172,6 +175,48 @@ func TestAccConsulConfigEntryCE_Mesh(t *testing.T) { }) } +func TestAccConsulConfigEntryCE_JWTProvider_Remote(t *testing.T) { + providers, _ := startTestServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipTestOnConsulEnterpriseEdition(t) }, + Providers: providers, + Steps: []resource.TestStep{ + { + Config: TestAccConsulConfigEntryCE_jwtRemote, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "id", "jwt-provider-okta"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "name", "okta"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "kind", "jwt-provider"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "config_json", "{\"ClockSkewSeconds\":30,\"Forwarding\":{\"HeaderName\":\"test-token\"},\"Issuer\":\"test-issuer\",\"JSONWebKeySet\":{\"Remote\":{\"FetchAsynchronously\":true,\"URI\":\"https://127.0.0.1:9091\"}}}"), + ), + }, + }, + }) +} + +func TestAccConsulConfigEntryCE_JWTProvider_Local(t *testing.T) { + providers, _ := startTestServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipTestOnConsulEnterpriseEdition(t) }, + Providers: providers, + Steps: []resource.TestStep{ + { + ExpectNonEmptyPlan: true, + Config: TestAccConsulConfigEntryCE_jwtLocal, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "id", "jwt-provider-auth0"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "name", "auth0"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "kind", "jwt-provider"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "config_json", "{\"ClockSkewSeconds\":30,\"Issuer\":\"auth0-issuer\",\"JSONWebKeySet\":{\"Local\":{\"JWKS\":\"eyJrZXlzIjogW3sKICAiY3J2IjogIlAtMjU2IiwKICAia2V5X29wcyI6IFsKICAgICJ2ZXJpZnkiCiAgXSwKICAia3R5IjogIkVDIiwKICAieCI6ICJXYzl1WnVQYUI3S2gyRk1jOXd0SmpSZThYRDR5VDJBWU5BQWtyWWJWanV3IiwKICAieSI6ICI2OGhSVEppSk5Pd3RyaDRFb1BYZVZuUnVIN2hpU0RKX2xtYmJqZkRmV3EwIiwKICAiYWxnIjogIkVTMjU2IiwKICAidXNlIjogInNpZyIsCiAgImtpZCI6ICJhYzFlOGY5MGVkZGY2MWM0MjljNjFjYTA1YjRmMmUwNyIKfV19\"}}}"), + ), + }, + }, + }) +} + const testAccConsulConfigEntryCE_ServiceDefaults = ` resource "consul_config_entry" "foo" { name = "foo" @@ -395,11 +440,31 @@ resource "consul_config_entry" "terminating_gateway" { ` const testAccConsulConfigEntryCE_ServiceConfigL4 = ` +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = "api-service" kind = "service-intentions" config_json = jsonencode({ + JWT = { + Providers = [ + { name = consul_config_entry.jwt_provider.name } + ] + } Sources = [ { Action = "allow" @@ -431,6 +496,21 @@ resource "consul_config_entry" "sd" { }) } +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = consul_config_entry.sd.name kind = "service-intentions" @@ -446,6 +526,11 @@ resource "consul_config_entry" "service_intentions" { Methods = ["GET", "HEAD"] PathExact = "/healtz" } + JWT = { + Providers = [ + { name = consul_config_entry.jwt_provider.name } + ] + } } ] Precedence = 9 @@ -488,6 +573,21 @@ resource "consul_config_entry" "sd" { }) } +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = consul_config_entry.sd.name kind = "service-intentions" @@ -503,6 +603,11 @@ resource "consul_config_entry" "service_intentions" { Methods = ["GET", "PUT", "POST", "DELETE", "HEAD"] PathPrefix = "/v2" } + JWT = { + Providers = [ + { name = consul_config_entry.jwt_provider.name } + ] + } } ], Precedence = 9 @@ -701,3 +806,38 @@ resource "consul_config_entry" "mesh" { }) } ` +const TestAccConsulConfigEntryCE_jwtRemote = ` +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + Forwarding = { + HeaderName = "test-token" + } + }) +} +` + +const TestAccConsulConfigEntryCE_jwtLocal = ` +resource "consul_config_entry" "jwt_provider" { + name = "auth0" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "auth0-issuer" + JSONWebKeySet = { + Local = { + JWKS = "eyJrZXlzIjogW3sKICAiY3J2IjogIlAtMjU2IiwKICAia2V5X29wcyI6IFsKICAgICJ2ZXJpZnkiCiAgXSwKICAia3R5IjogIkVDIiwKICAieCI6ICJXYzl1WnVQYUI3S2gyRk1jOXd0SmpSZThYRDR5VDJBWU5BQWtyWWJWanV3IiwKICAieSI6ICI2OGhSVEppSk5Pd3RyaDRFb1BYZVZuUnVIN2hpU0RKX2xtYmJqZkRmV3EwIiwKICAiYWxnIjogIkVTMjU2IiwKICAidXNlIjogInNpZyIsCiAgImtpZCI6ICJhYzFlOGY5MGVkZGY2MWM0MjljNjFjYTA1YjRmMmUwNyIKfV19" + } + } + }) +} +` diff --git a/consul/resource_consul_config_entry_ee_test.go b/consul/resource_consul_config_entry_ee_test.go index b74ab1e2..5e97ee3c 100644 --- a/consul/resource_consul_config_entry_ee_test.go +++ b/consul/resource_consul_config_entry_ee_test.go @@ -93,21 +93,24 @@ func TestAccConsulConfigEntryEE_basic(t *testing.T) { ), }, { - Config: testAccConsulConfigEntryEE_ServiceConfigL4, + Config: testAccConsulConfigEntryEE_ServiceConfigL4, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "api-service"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), ), }, { - Config: testAccConsulConfigEntryEE_ServiceConfigL7, + Config: testAccConsulConfigEntryEE_ServiceConfigL7, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "fort-knox"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), ), }, { - Config: testAccConsulConfigEntryEE_ServiceConfigL7b, + Config: testAccConsulConfigEntryEE_ServiceConfigL7b, + ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "name", "api"), resource.TestCheckResourceAttr("consul_config_entry.service_intentions", "kind", "service-intentions"), @@ -195,6 +198,48 @@ func TestAccConsulConfigEntryEE_Mesh(t *testing.T) { }) } +func TestAccConsulConfigEntryEE_JWTProvider_Remote(t *testing.T) { + providers, _ := startTestServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipTestOnConsulCommunityEdition(t) }, + Providers: providers, + Steps: []resource.TestStep{ + { + ExpectNonEmptyPlan: true, + Config: TestAccConsulConfigEntryEE_jwtRemote, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "id", "jwt-provider-okta"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "name", "okta"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "kind", "jwt-provider"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "config_json", "{\"ClockSkewSeconds\":30,\"Forwarding\":{\"HeaderName\":\"test-token\"},\"Issuer\":\"test-issuer\",\"JSONWebKeySet\":{\"Remote\":{\"FetchAsynchronously\":true,\"URI\":\"https://127.0.0.1:9091\"}}}"), + ), + }, + }, + }) +} + +func TestAccConsulConfigEntryEE_JWTProvider_Local(t *testing.T) { + providers, _ := startTestServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { skipTestOnConsulCommunityEdition(t) }, + Providers: providers, + Steps: []resource.TestStep{ + { + Config: TestAccConsulConfigEntryEE_jwtLocal, + ExpectNonEmptyPlan: true, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "id", "jwt-provider-auth0"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "name", "auth0"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "kind", "jwt-provider"), + resource.TestCheckResourceAttr("consul_config_entry.jwt_provider", "config_json", "{\"ClockSkewSeconds\":30,\"Issuer\":\"auth0-issuer\",\"JSONWebKeySet\":{\"Local\":{\"JWKS\":\"eyJrZXlzIjogW3sKICAiY3J2IjogIlAtMjU2IiwKICAia2V5X29wcyI6IFsKICAgICJ2ZXJpZnkiCiAgXSwKICAia3R5IjogIkVDIiwKICAieCI6ICJXYzl1WnVQYUI3S2gyRk1jOXd0SmpSZThYRDR5VDJBWU5BQWtyWWJWanV3IiwKICAieSI6ICI2OGhSVEppSk5Pd3RyaDRFb1BYZVZuUnVIN2hpU0RKX2xtYmJqZkRmV3EwIiwKICAiYWxnIjogIkVTMjU2IiwKICAidXNlIjogInNpZyIsCiAgImtpZCI6ICJhYzFlOGY5MGVkZGY2MWM0MjljNjFjYTA1YjRmMmUwNyIKfV19\"}}}"), + ), + }, + }, + }) +} + const testAccConsulConfigEntryEE_ServiceDefaults = ` resource "consul_config_entry" "foo" { name = "foo" @@ -457,11 +502,31 @@ resource "consul_config_entry" "service_intentions" { ` const testAccConsulConfigEntryEE_ServiceConfigL4 = ` +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = "api-service" kind = "service-intentions" config_json = jsonencode({ + JWT = { + Providers = [ + { name = "okta" } + ] + } Sources = [ { Namespace = "default" @@ -497,6 +562,21 @@ resource "consul_config_entry" "sd" { }) } +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = consul_config_entry.sd.name kind = "service-intentions" @@ -514,6 +594,11 @@ resource "consul_config_entry" "service_intentions" { Methods = ["GET", "HEAD"] PathExact = "/healtz" } + JWT = { + Providers = [ + { name = consul_config_entry.jwt_provider.name } + ] + } } ] Precedence = 9 @@ -558,6 +643,21 @@ resource "consul_config_entry" "sd" { }) } +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + }) +} + resource "consul_config_entry" "service_intentions" { name = consul_config_entry.sd.name kind = "service-intentions" @@ -575,6 +675,11 @@ resource "consul_config_entry" "service_intentions" { Methods = ["GET", "PUT", "POST", "DELETE", "HEAD"] PathPrefix = "/v2" } + JWT = { + Providers = [ + { name = consul_config_entry.jwt_provider.name } + ] + } } ], Precedence = 9 @@ -828,3 +933,39 @@ resource "consul_config_entry" "mesh" { }) } ` + +const TestAccConsulConfigEntryEE_jwtRemote = ` +resource "consul_config_entry" "jwt_provider" { + name = "okta" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + Forwarding = { + HeaderName = "test-token" + } + }) +} +` + +const TestAccConsulConfigEntryEE_jwtLocal = ` +resource "consul_config_entry" "jwt_provider" { + name = "auth0" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "auth0-issuer" + JSONWebKeySet = { + Local = { + JWKS = "eyJrZXlzIjogW3sKICAiY3J2IjogIlAtMjU2IiwKICAia2V5X29wcyI6IFsKICAgICJ2ZXJpZnkiCiAgXSwKICAia3R5IjogIkVDIiwKICAieCI6ICJXYzl1WnVQYUI3S2gyRk1jOXd0SmpSZThYRDR5VDJBWU5BQWtyWWJWanV3IiwKICAieSI6ICI2OGhSVEppSk5Pd3RyaDRFb1BYZVZuUnVIN2hpU0RKX2xtYmJqZkRmV3EwIiwKICAiYWxnIjogIkVTMjU2IiwKICAidXNlIjogInNpZyIsCiAgImtpZCI6ICJhYzFlOGY5MGVkZGY2MWM0MjljNjFjYTA1YjRmMmUwNyIKfV19" + } + } + }) +} +` diff --git a/docs/resources/config_entry.md b/docs/resources/config_entry.md index 642d9674..e89573fa 100644 --- a/docs/resources/config_entry.md +++ b/docs/resources/config_entry.md @@ -171,6 +171,24 @@ resource "consul_config_entry" "sd" { }) } +resource "consul_config_entry" "jwt_provider" { + name = "test-provider" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "test-issuer" + JSONWebKeySet = { + Remote = { + URI = "https://127.0.0.1:9091" + FetchAsynchronously = true + } + } + Forwarding = { + HeaderName = "test-token" + } + }) +} + resource "consul_config_entry" "service_intentions" { name = consul_config_entry.sd.name kind = "service-intentions" @@ -186,6 +204,13 @@ resource "consul_config_entry" "service_intentions" { Methods = ["GET", "HEAD"] PathExact = "/healtz" } + JWT = { + Providers = [ + { + Name = consul_config_entry.jwt_provider.name + } + ] + } } ] Precedence = 9 @@ -250,6 +275,29 @@ resource "consul_config_entry" "mesh" { } ``` +### `jwt-provider` config entry + +```hcl +resource "consul_config_entry" "jwt_provider" { + name = "provider-name" + kind = "jwt-provider" + + config_json = jsonencode({ + Issuer = "https://your.issuer.com" + JSONWebKeySet = { + Remote = { + URI = "https://your-remote.jwks.com" + FetchAsynchronously = true + CacheDuration = "10s" + } + } + Forwarding = { + HeaderName = "test-token" + } + }) +} +``` + ## Argument Reference