From 61eca6513b4cfecb22439385adb5f809ddb2c3b6 Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Thu, 16 Dec 2021 11:49:22 -0500 Subject: [PATCH 01/78] enabling security scan for CRT --- .github/workflows/build.yml | 4 +++- .release/ci.hcl | 38 ++++++++++++++++++++++++++++++------- .release/security-scan.hcl | 13 +++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 .release/security-scan.hcl diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 754a8fcaab..8a5eeb0354 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,9 @@ name: build on: push: # Sequence of patterns matched against refs/heads - branches: [ main ] + branches: + - enable-security-scan + # [ main ] env: PKG_NAME: consul diff --git a/.release/ci.hcl b/.release/ci.hcl index b248590b83..cb3ba08d5a 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -4,17 +4,13 @@ project "consul" { team = "consul core" slack { # feed-consul-ci - notification_channel = "C9KPKPKRN" + notification_channel = "C01A3A54G0L" } github { organization = "hashicorp" repository = "consul" release_branches = [ - "main", - "release/1.8.x", - "release/1.9.x", - "release/1.10.x", - "release/1.11.x" + "enable-security-scan" ] } } @@ -42,8 +38,36 @@ event "upload-dev" { } } -event "notarize-darwin-amd64" { +event "security-scan-binaries" { depends = ["upload-dev"] + action "security-scan-binaries" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "security-scan-binaries" + config = "security-scan.hcl" + } + + notification { + on = "fail" + } +} + +event "security-scan-containers" { + depends = ["security-scan-binaries"] + action "security-scan-containers" { + organization = "hashicorp" + repository = "crt-workflows-common" + workflow = "security-scan-containers" + config = "security-scan.hcl" + } + + notification { + on = "fail" + } +} + +event "notarize-darwin-amd64" { + depends = ["security-scan-containers"] action "notarize-darwin-amd64" { organization = "hashicorp" repository = "crt-workflows-common" diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl new file mode 100644 index 0000000000..3fd4ef388e --- /dev/null +++ b/.release/security-scan.hcl @@ -0,0 +1,13 @@ +container { + dependencies = true + alpine_secdb = true + secrets = true +} + +binary { + secrets = true + go_modules = true + osv = true + oss_index = true + nvd = true +} From 1e9b621b00efa1d8032a3b1f216b0417d7ce7852 Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 17 Dec 2021 10:20:52 -0500 Subject: [PATCH 02/78] testing out turining go modules false --- .release/security-scan.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 3fd4ef388e..eeb188891c 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -6,7 +6,7 @@ container { binary { secrets = true - go_modules = true + go_modules = false osv = true oss_index = true nvd = true From 4b0d34693211f982d4e3e5f5d48d288167b1944a Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 17 Dec 2021 10:41:04 -0500 Subject: [PATCH 03/78] updating the alpine version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8d5931e91c..1c9e4f6986 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # This Dockerfile creates a production release image for the project using crt release flow. -FROM alpine:3.13 as default +FROM alpine:3 as default ARG VERSION ARG BIN_NAME From 8dcdbd38a569aff5221c67d1545f85caa7f30cc8 Mon Sep 17 00:00:00 2001 From: Jake Herschman Date: Tue, 4 Jan 2022 15:15:46 -0500 Subject: [PATCH 04/78] Updating CTS compatability page Updating compatability chart to refernce all versions of CTS and other HashiCorp products compatability --- website/content/docs/nia/compatibility.mdx | 41 +++++++++------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index be7bd13acc..aebeeb897c 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -7,28 +7,19 @@ description: >- # Compatibility -## Consul - -Below are the supported Consul versions with compatible Consul-Terraform-Sync versions. The latest Consul-Terraform-Sync binary targets supporting the latest patch version of the three most recent Consul minor versions. - -| Consul Version | Compatible Consul-Terraform-Sync Version | -| ---------------------------- | ---------------------------------------- | -| 1.8+ | 0.1+ | - -## Terraform - -Consul-Terraform-Sync is compatible with the following Terraform OSS versions: - -| Consul-Terraform-Sync | Compatible Terraform Version | -| --------------------- | ---------------------------- | -| 0.2+ | 0.13 - 1.0 | -| 0.1 | 0.13 - 0.14 | - -## Terraform Cloud - -Consul-Terraform-Sync integration with Terraform Cloud is supported for the following: - -| Consul-Terraform-Sync Enterprise | Terraform Cloud | Version | -| -------------------------------- | -------------------------- | ------------------ | -| 0.4+ | Terraform Cloud | Latest | -| 0.3+ | Terraform Enterprise | v202010-2 - Latest | +## Consul-Terraform-Sync + +Below are the supported Consul, Terraform, and Vault versions with compatible Consul-Terraform-Sync versions. + +| | **CTS OSS** | **CTS Enterprise** | +| :------------------------------------------------------------: | :--------------------------------------: | :--------------------------------------: | +| **Consul OSS**
`v1.8+` | | | +| **Consul Enterprise**
`v1.8+` | | | +| **HCP Consul**
`v1.8+` | | | +| **Terraform OSS**
`v0.13 - 1.0+` | | | +| **Terraform Enterprise**
`v2020 10-2 - Latest` | | | +| **Terraform Cloud**
`Continuous Updates` | | | +| CTS integrates with Vault to query secrets | +| **Vault OSS**
`v0.7+` | | | +| **Vault Enterprise**
`v0.7+` | | | +| **HCP Vault**
`v0.7+` | | | From fdfc9aff684e70c3b21b3ce645c569c387322f2c Mon Sep 17 00:00:00 2001 From: Jake Herschman Date: Tue, 4 Jan 2022 19:03:48 -0500 Subject: [PATCH 05/78] Updated Formatting on Compatibility Chart --- website/content/docs/nia/compatibility.mdx | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index aebeeb897c..b08c6adc1f 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -11,15 +11,22 @@ description: >- Below are the supported Consul, Terraform, and Vault versions with compatible Consul-Terraform-Sync versions. -| | **CTS OSS** | **CTS Enterprise** | -| :------------------------------------------------------------: | :--------------------------------------: | :--------------------------------------: | -| **Consul OSS**
`v1.8+` | | | -| **Consul Enterprise**
`v1.8+` | | | -| **HCP Consul**
`v1.8+` | | | -| **Terraform OSS**
`v0.13 - 1.0+` | | | -| **Terraform Enterprise**
`v2020 10-2 - Latest` | | | -| **Terraform Cloud**
`Continuous Updates` | | | -| CTS integrates with Vault to query secrets | -| **Vault OSS**
`v0.7+` | | | -| **Vault Enterprise**
`v0.7+` | | | -| **HCP Vault**
`v0.7+` | | | +| | **CTS OSS**
v0.1+ | **CTS Enterprise**
v0.1+ | +| :------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------: | :----------------------------------------------------------------------------: | +| **Consul OSS**
v1.8+ | | | +| **Consul Enterprise**
v1.8+ | | | +| **HCP Consul**
v1.8+ | | | +| | +| **Terraform OSS**
v0.13 - 1.0+ | | | +| **Terraform Enterprise**
v2020 10-2 - Latest | | | +| **Terraform Cloud**
Continuous Updates | | | +| | +| **\*Vault OSS**
v0.7+ | | | +| **\*Vault Enterprise**
v0.7+ | | | +| **\*HCP Vault**
v0.7+ | | | + +

+ + *CTS integrates with Vault to query secrets + +

From d66f4da7f0bf3f0d24fa61f43e4932404f626783 Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Thu, 6 Jan 2022 09:43:35 -0500 Subject: [PATCH 06/78] clean up after testing --- .github/workflows/build.yml | 3 +-- .release/ci.hcl | 8 ++++++-- .release/security-scan.hcl | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8a5eeb0354..46a5896d97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,8 +4,7 @@ on: push: # Sequence of patterns matched against refs/heads branches: - - enable-security-scan - # [ main ] + [ main ] env: PKG_NAME: consul diff --git a/.release/ci.hcl b/.release/ci.hcl index cb3ba08d5a..bf4a2144f3 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -4,13 +4,17 @@ project "consul" { team = "consul core" slack { # feed-consul-ci - notification_channel = "C01A3A54G0L" + notification_channel = "C9KPKPKRN" } github { organization = "hashicorp" repository = "consul" release_branches = [ - "enable-security-scan" + "main", + "release/1.8.x", + "release/1.9.x", + "release/1.10.x", + "release/1.11.x" ] } } diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index eeb188891c..3fd4ef388e 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -6,7 +6,7 @@ container { binary { secrets = true - go_modules = false + go_modules = true osv = true oss_index = true nvd = true From 0b3dfcb195413298b9970267d37d72a201b7987c Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Thu, 6 Jan 2022 09:45:54 -0500 Subject: [PATCH 07/78] fixing build error --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46a5896d97..4349492875 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,8 +3,9 @@ name: build on: push: # Sequence of patterns matched against refs/heads - branches: - [ main ] + branches: [ + "main" + ] env: PKG_NAME: consul From 2ddba9e3a8031216cac2a3b2774d01d8a756ea3b Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Thu, 6 Jan 2022 14:32:35 -0500 Subject: [PATCH 08/78] fix branch event convention --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4349492875..95b505cd30 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,9 +3,9 @@ name: build on: push: # Sequence of patterns matched against refs/heads - branches: [ - "main" - ] + branches: + # Push events on the main branch + - main env: PKG_NAME: consul From 4c3bde7888b5b497dd8c5f4332df09e30ffbf589 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Thu, 6 Jan 2022 13:57:22 -0700 Subject: [PATCH 09/78] initializing SEO updates --- website/content/docs/intro/index.mdx | 2 +- website/content/docs/intro/usecases/index.mdx | 9 ++++ .../intro/usecases/what-is-a-service-mesh.mdx | 46 +++++++++++++++++++ website/data/docs-nav-data.json | 16 ++++++- 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 website/content/docs/intro/usecases/index.mdx create mode 100644 website/content/docs/intro/usecases/what-is-a-service-mesh.mdx diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx index febb4e0956..2db5276d73 100644 --- a/website/content/docs/intro/index.mdx +++ b/website/content/docs/intro/index.mdx @@ -1,6 +1,6 @@ --- layout: docs -page_title: Intro to Consul +page_title: What is Consul? description: >- Welcome to the intro guide to Consul! This guide is the best place to start with Consul. We cover what Consul is, what problems it can solve, how it diff --git a/website/content/docs/intro/usecases/index.mdx b/website/content/docs/intro/usecases/index.mdx new file mode 100644 index 0000000000..2f2b4b324e --- /dev/null +++ b/website/content/docs/intro/usecases/index.mdx @@ -0,0 +1,9 @@ +--- +layout: docs +page_title: usecases +description: >- + Consul Service Mesh can be deployed on AWS ECS (Elastic Container Service). + This section documents the official installation of Consul on ECS. +--- + +lals diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx new file mode 100644 index 0000000000..f9db1b38da --- /dev/null +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -0,0 +1,46 @@ +--- +layout: docs +page_title: What is service mesh?? +description: >- + Welcome to the intro guide to Consul! This guide is the best place to start + with Consul. We cover what Consul is, what problems it can solve, how it + compares to existing software, and how you can get started using it. If you + are familiar with the basics of Consul, the documentation provides a more + detailed reference of available features. +--- + +# What is a Service Mesh? + +Blah Blah Blah Blah ..Go Consul + +## How does Service Mesh work? + +Consul is the best! + +## Service Mesh vs API Gateway + +If you ain't using Consul .... + +## Benefits of Service Mesh + +Consul is a Roman term for head of state!! + +## What Problems Does Service Mesh Solve? + +Consul is a bit tricky to master. + +## How Do You Implement Service Mesh? + +Easy peasy, use Terraform + +## What is Service Mesh Automation? + +When Consul and Terraform get together. + +## What is a Multi Platform Service Mesh? + +AWS + GCP + Azure + Consul = Easy Peasy + +## Next + +Go learn [learn.hashicorp.com](https://learn.hashicorp.com/consul) diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 77a5ef1ffe..dabde29eb0 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -1,11 +1,25 @@ [ { - "title": "Intro to Consul", + "title": "What is Consul?", "routes": [ { "title": "Overview", "path": "intro" }, + { + "title": "Use Cases", + "routes": [ + { + "title": "Overview", + "path": "intro/usecases", + "hidden": true + }, + { + "title": "What is a Service Mesh?", + "path": "intro/usecases/what-is-a-service-mesh" + } + ] + }, { "title": "Consul vs. Other Software", "routes": [ From 467ac0f333a0d3e3cc1823ede1718775868f9360 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 7 Jan 2022 11:28:38 -0700 Subject: [PATCH 10/78] save --- .../intro/usecases/what-is-a-service-mesh.mdx | 69 ++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index f9db1b38da..4bb2ce5b4c 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -9,6 +9,7 @@ description: >- detailed reference of available features. --- + + +# https://react-components-hashicorp.vercel.app + +```shell-session hideClipboard +$ echo 'Hello world' +``` + + + +```javascript +const foo = 'bar' +function hello() { + return Math.random() > 0.5 ? 'Hello' : 'Bonjour' +} +console.log('hello world') +``` + + + + + + + +```hcl +primary_datacenter = "dc1" +acl { + enabled = true + default_policy = "deny" + down_policy = "extend-cache" + tokens { + "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb" + } +} +``` + + + + + +```json +{ + "primary_datacenter": "dc1", + "acl": { + "enabled": true, + "default_policy": "deny", + "down_policy": "extend-cache", + "tokens": { + "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb" + } + } +} +``` + + + + + +-> **Note**: Did you know + +~> **Warning**: Be aware of + +!> **Danger**: DO NOT EXPOSE YOUR BOOTSTRAP ACL TOKEN + + + +!["A swimlane for auth methods"](/img/auth-methods.svg) From 26e5aa772f7ef08066607bd669ec7fb6a9f328a6 Mon Sep 17 00:00:00 2001 From: Jake Herschman <91899352+jherschman@users.noreply.github.com> Date: Mon, 10 Jan 2022 12:13:21 -0500 Subject: [PATCH 11/78] Update website/content/docs/nia/compatibility.mdx Co-authored-by: trujillo-adam <47586768+trujillo-adam@users.noreply.github.com> --- website/content/docs/nia/compatibility.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index b08c6adc1f..31a617a48a 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -9,7 +9,7 @@ description: >- ## Consul-Terraform-Sync -Below are the supported Consul, Terraform, and Vault versions with compatible Consul-Terraform-Sync versions. +The following table describes Consul-Terraform-Sync version compatibility for Consul, Terraform, and Vault. | | **CTS OSS**
v0.1+ | **CTS Enterprise**
v0.1+ | | :------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------: | :----------------------------------------------------------------------------: | From 75f1c4007c1207d6c426f767601e8a5879eea319 Mon Sep 17 00:00:00 2001 From: Jake Herschman Date: Mon, 10 Jan 2022 14:38:27 -0500 Subject: [PATCH 12/78] updated based on feedback & testing searchability --- website/content/docs/nia/compatibility.mdx | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index 31a617a48a..455203fa40 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -1,8 +1,8 @@ --- layout: docs -page_title: Consul-Terraform-Sync Compatibility +page_title: Consul-Terraform-Sync (CTS) Compatibility description: >- - Consul-Terraform-Sync Compatibility + Consul-Terraform-Sync (CTS) Compatibility --- # Compatibility @@ -11,22 +11,22 @@ description: >- The following table describes Consul-Terraform-Sync version compatibility for Consul, Terraform, and Vault. -| | **CTS OSS**
v0.1+ | **CTS Enterprise**
v0.1+ | +| | **CTS OSS**
0.1+ | **CTS Enterprise**
0.3+ | | :------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------: | :----------------------------------------------------------------------------: | -| **Consul OSS**
v1.8+ | | | -| **Consul Enterprise**
v1.8+ | | | -| **HCP Consul**
v1.8+ | | | +| **Consul OSS**
1.8+ | | | +| **Consul Enterprise**
1.8+ | | | +| **HCP Consul**
1.8+ | | | | | -| **Terraform OSS**
v0.13 - 1.0+ | | | -| **Terraform Enterprise**
v2020 10-2 - Latest | | | -| **Terraform Cloud**
Continuous Updates | | | +| **Terraform OSS**
0.13 - 1.0 | | | +| **Terraform Enterprise**
2020 10-2 - Latest | | | +| **Terraform Cloud**
Continuous Updates | |
CTS 0.4+ | | | -| **\*Vault OSS**
v0.7+ | | | -| **\*Vault Enterprise**
v0.7+ | | | -| **\*HCP Vault**
v0.7+ | | | +| **\*Vault OSS**
0.7+ | | | +| **\*Vault Enterprise**
0.7+ | | | +| **\*HCP Vault**
0.7+ | | |

- + *CTS integrates with Vault to query secrets -

+

\ No newline at end of file From 78844e842db1ed2b6952fdd5b4e7e89e1323623b Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 14 Jan 2022 10:09:05 -0700 Subject: [PATCH 13/78] first intro --- .../intro/usecases/what-is-a-service-mesh.mdx | 84 ++----------------- 1 file changed, 9 insertions(+), 75 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 4bb2ce5b4c..f7588c50a4 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -2,17 +2,19 @@ layout: docs page_title: What is service mesh?? description: >- - Welcome to the intro guide to Consul! This guide is the best place to start - with Consul. We cover what Consul is, what problems it can solve, how it - compares to existing software, and how you can get started using it. If you - are familiar with the basics of Consul, the documentation provides a more - detailed reference of available features. + Learn what a serive mesh is, it's benefits, and how it works. --- - - -# https://react-components-hashicorp.vercel.app - -```shell-session hideClipboard -$ echo 'Hello world' -``` - - - -```javascript -const foo = 'bar' -function hello() { - return Math.random() > 0.5 ? 'Hello' : 'Bonjour' -} -console.log('hello world') -``` - - - - - - - -```hcl -primary_datacenter = "dc1" -acl { - enabled = true - default_policy = "deny" - down_policy = "extend-cache" - tokens { - "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb" - } -} -``` - - - - - -```json -{ - "primary_datacenter": "dc1", - "acl": { - "enabled": true, - "default_policy": "deny", - "down_policy": "extend-cache", - "tokens": { - "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb" - } - } -} -``` - - - - - --> **Note**: Did you know - -~> **Warning**: Be aware of - -!> **Danger**: DO NOT EXPOSE YOUR BOOTSTRAP ACL TOKEN - - - -!["A swimlane for auth methods"](/img/auth-methods.svg) From 9c036ae8f3906c5373932db50431aed47913dba5 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 14 Jan 2022 14:46:59 -0700 Subject: [PATCH 14/78] api gw vs mesh section added --- .../intro/usecases/what-is-a-service-mesh.mdx | 45 ++++++++++++++---- website/public/img/what_is_service_mesh_1.png | Bin 0 -> 163903 bytes 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 website/public/img/what_is_service_mesh_1.png diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index f7588c50a4..d0b6a0a911 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -7,26 +7,55 @@ description: >- # What is a Service Mesh? -A service mesh is a dedicated layer that provides secure service-to-service communication for on-prem, cloud, or multi-cloud infrastructure. +A _service mesh_ is a dedicated network layer that provides secure service-to-service communication for on-prem, cloud, or multi-cloud infrastructure. Service meshes are often used with a microservice architectural pattern, but can provide value in any scenario where complex networking is involved. -Service meshes typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. +## Benefits of a Service Mesh + +A _service mesh_ provides benefits for all organziations, ranging from security to improved application resiliency. +Some of the benefits of a _service mesh_ include; + +- service discovery +- application health monitoring +- load balancing +- automatic failover +- traffic management +- encryption +- observability and tracability, +- authentication and authorization, +- network automation + +A common usecase for leveraging a _service mesh_ is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). +In a _zero trust_ model, applications require identity-based access to ensure all communication within the service mesh is authenticated with TLS certificates and encrypted in transit. + +## How does a Service Mesh work? + +A _service meshe_ typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. The data plane handles communication between services. Many _service mesh_ solutions employ a sidecar proxy to handle data plane communications, and thus limit the level of awareness the services need to have about the network environment. -## How does Service Mesh work? +![Overview of a service mesh](/img/what_is_service_mesh_1.png) + +## API Gateway vs Service Mesh -Consul is the best! +An API gateway is a centralized access point for handling incoming client requests and delivering them to services. +The API Gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. +The API Gateway will route the incoming requests to the respective service. API Gateways primary function is to handle requests and return the reply from the service back to the client. -## Service Mesh vs API Gateway +-> **Note:** API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a datacenter or a virutal private network (VPC). -If you ain't using Consul .... +A _service mesh_ specializes in the network management of services and the communication between services. +The mesh is responsible for keeping track of services and their health status, IP address, traffic routing, and ensuring all the traffic between services are authenticated and encrypted. +Unlike API Gateways, a _service mesh_ will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. +API Gateways are frequently deployed alongside a loadbalancer to ensure traffic is directed to healthy and available instances of the service. +The mesh reduces the loadbalancer footprint as routing responsibilities are handled in a decentralized manner. -## Benefits of Service Mesh +API Gateways can be used togehter with a _service mesh_ to bridge external networks (non-mesh) with a _service mesh_. -Consul is a Roman term for head of state!! +-> **Note**: A _service mesh_ is primarly used for handling east-west based traffic. East-west traffic traditionaly remains inside a datacenter or a VPC. +A _service mesh_ can be connected to another _service mesh_ in another datacenter or VPC to form a federated mesh. ## What Problems Does Service Mesh Solve? diff --git a/website/public/img/what_is_service_mesh_1.png b/website/public/img/what_is_service_mesh_1.png new file mode 100644 index 0000000000000000000000000000000000000000..77aa7678ac2ae2ca6802941a1d9d39914ca90213 GIT binary patch literal 163903 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 literal 0 HcmV?d00001 From 447b8c560a0f1bddace87ba8c3ccc45f4e294a6b Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 14 Jan 2022 14:48:54 -0700 Subject: [PATCH 15/78] api gw vs mesh section added --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index d0b6a0a911..28e5c8f375 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -44,8 +44,6 @@ An API gateway is a centralized access point for handling incoming client reques The API Gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. The API Gateway will route the incoming requests to the respective service. API Gateways primary function is to handle requests and return the reply from the service back to the client. --> **Note:** API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a datacenter or a virutal private network (VPC). - A _service mesh_ specializes in the network management of services and the communication between services. The mesh is responsible for keeping track of services and their health status, IP address, traffic routing, and ensuring all the traffic between services are authenticated and encrypted. Unlike API Gateways, a _service mesh_ will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. @@ -54,7 +52,8 @@ The mesh reduces the loadbalancer footprint as routing responsibilities are hand API Gateways can be used togehter with a _service mesh_ to bridge external networks (non-mesh) with a _service mesh_. --> **Note**: A _service mesh_ is primarly used for handling east-west based traffic. East-west traffic traditionaly remains inside a datacenter or a VPC. +-> **Note**: API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a datacenter or a virutal private network (VPC). +A _service mesh_ is primarly used for handling east-west based traffic. East-west traffic traditionaly remains inside a datacenter or a VPC. A _service mesh_ can be connected to another _service mesh_ in another datacenter or VPC to form a federated mesh. ## What Problems Does Service Mesh Solve? From c3b53444b782b0698d96c4360547561e6c12f1cf Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 14 Jan 2022 15:09:33 -0700 Subject: [PATCH 16/78] typo fix --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 28e5c8f375..619bb74649 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -56,11 +56,11 @@ API Gateways can be used togehter with a _service mesh_ to bridge external netwo A _service mesh_ is primarly used for handling east-west based traffic. East-west traffic traditionaly remains inside a datacenter or a VPC. A _service mesh_ can be connected to another _service mesh_ in another datacenter or VPC to form a federated mesh. -## What Problems Does Service Mesh Solve? +## What Problems Does a Service Mesh Solve? Consul is a bit tricky to master. -## How Do You Implement Service Mesh? +## How Do You Implement a Service Mesh? Easy peasy, use Terraform From 8cdff69252266f4604df7dc3b5ffb43316f41126 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Tue, 18 Jan 2022 08:14:40 -0700 Subject: [PATCH 17/78] added content to problems a mesh solves section --- .../intro/usecases/what-is-a-service-mesh.mdx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 619bb74649..efd7e1f1f9 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -58,7 +58,28 @@ A _service mesh_ can be connected to another _service mesh_ in another datacente ## What Problems Does a Service Mesh Solve? -Consul is a bit tricky to master. +Modern infrastructure is transitioning from primarily being static-based to dynamic in nature (ephemeral). +This dynamic infrastructure has a short life cycle, meaning virtual machines (VM) and containers are frequently recycled. +It's difficult for an organization to manage and keep track of application services that live on short-lived resources. A _service mesh_ solves this problem by acting as a central registry of all registered services. +As service instances, either VMs or containers, come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a _service mesh_ solves. + +As a service mesh is aware of the state of a service and its instances, the mesh can implement more intelligent and dynamic network routing. +Many service meshes offer L7 traffic management capabilities. As a result, operators and developers can create powerful rules to direct network traffic as needed, such as load balancing, traffic splitting, dynamic failover, and custom resolvers. +A service mesh's dynamic network behavior allows application owners to improve application resiliency and availability with no application changes. + +Implementing dynamic network behavior is critical as more and more applications are deployed across different cloud providers (multi-cloud) and private datacenters. +Organizations may need to route network traffic to other infrastructure environments. Ensuring this traffic is secure is on top of mind for all organizations. +Service meshes offer the ability to enforce network traffic encryption (mTLS) and authentication between all services. The _service mesh_ can automatically generate an SSL certificate for each service and its instances. +The certificate authenticates with other services inside the mesh and encrypts the TCP/UDP/gRPC connection with SSL. + + + +Fine-grained policies that dictate what services are allowed to communicate with each other is another benefit of a _service mesh_. +Traditionally, services are permitted to communicate with other services through firewall rules. +The traditional firewall (IP-based) model is difficult to enforce with dynamic infrastructure resources with a short lifecycle and frequently recycling IP addresses. +As a result, network administrators have to open up network ranges to permit network traffic between services without differentiating the services generating the network traffic. However, a _service mesh_ allows operators and developers to shift away from an IP-based model and focus more on service to service permissions. +An operator defines a policy that only allows _service A_ to communicate with _service B_. Otherwise, the default action is to deny the traffic. +This shift from an IP address-based security model to a service-focused model reduces the overhead of securing network traffic and allows an organization to take advantage of multi-cloud environments without sacrificing security due to complexity. ## How Do You Implement a Service Mesh? From 97e9b7cf4b3c6d405df826f1a58ac1fef58c1ab8 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Tue, 18 Jan 2022 15:12:26 -0700 Subject: [PATCH 18/78] docs: answered the remaining questions --- .../intro/usecases/what-is-a-service-mesh.mdx | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index efd7e1f1f9..dea0d0df39 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -33,7 +33,9 @@ In a _zero trust_ model, applications require identity-based access to ensure al A _service meshe_ typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. -The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. The data plane handles communication between services. +The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. + +The data plane handles communication between services. Many _service mesh_ solutions employ a sidecar proxy to handle data plane communications, and thus limit the level of awareness the services need to have about the network environment. ![Overview of a service mesh](/img/what_is_service_mesh_1.png) @@ -83,14 +85,31 @@ This shift from an IP address-based security model to a service-focused model re ## How Do You Implement a Service Mesh? -Easy peasy, use Terraform +Service meshes are commonly installed in Kubernetes clusters. There are also platform-agnostic service meshes available for non-Kubernetes-based workloads. +For Kubernetes, most service mesh can be installed by operators through a [Helm chart](https://artifacthub.io/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. +Non-Kubernetes based service meshes can be installed through infrastructure as code (IaC) products such as [Terraform](https://www.terraform.io/), CloudFormation, ARM Templates, Puppet, Chef, etc. ## What is Service Mesh Automation? -When Consul and Terraform get together. +** Waiting to hear back from Marketing what this question means**. ## What is a Multi Platform Service Mesh? -AWS + GCP + Azure + Consul = Easy Peasy +A multi-platform service mesh is capable of supporting various infrastructure environments. This can range from having the service mesh support Kubernetes and non-Kubernetes workloads, to having a service mesh span across various cloud environments (multi-cloud). + +## What is Consul? + +Consul is a multi-networking tool that offers a fully-featured service mesh solution that solves the networking and security challenges of operating microservices and cloud infrastructure. +Consul offers a software-driven approach to routing and segmentation. It also brings additional benefits such as failure handling, retries, and network observability. +Each of these features can be used individually as needed or they can be used together to build a full service mesh and achieve [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) security. In simple terms, Consul is the control plane of the service mesh. + +You can use Consul with virtual machines (VMs), containers, or with container orchestration platforms, such as [Nomad](https://www.nomadproject.io/) and Kubernetes. +Consul is platform agnostic which makes it a great fit for all environments, including legacy platforms. + +Consul is available as a [self-install](/downloads) project or as a fully managed service mesh solution called [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). +HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a _service mesh_ on their own. ## Next + +Get started today with a _service mesh_ by leveraging [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). +Prepare your organization for the future of multi-cloud and embrace a [zero-trust](https://www.hashicorp.com/solutions/zero-trust-security) architecture. From ba432f940fa244ecd42b412833138681d5200914 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Tue, 18 Jan 2022 15:26:37 -0700 Subject: [PATCH 19/78] docs: removed a question pr marketing's gudiance --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index dea0d0df39..3101db54f2 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -74,8 +74,6 @@ Organizations may need to route network traffic to other infrastructure environm Service meshes offer the ability to enforce network traffic encryption (mTLS) and authentication between all services. The _service mesh_ can automatically generate an SSL certificate for each service and its instances. The certificate authenticates with other services inside the mesh and encrypts the TCP/UDP/gRPC connection with SSL. - - Fine-grained policies that dictate what services are allowed to communicate with each other is another benefit of a _service mesh_. Traditionally, services are permitted to communicate with other services through firewall rules. The traditional firewall (IP-based) model is difficult to enforce with dynamic infrastructure resources with a short lifecycle and frequently recycling IP addresses. @@ -89,10 +87,6 @@ Service meshes are commonly installed in Kubernetes clusters. There are also pla For Kubernetes, most service mesh can be installed by operators through a [Helm chart](https://artifacthub.io/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. Non-Kubernetes based service meshes can be installed through infrastructure as code (IaC) products such as [Terraform](https://www.terraform.io/), CloudFormation, ARM Templates, Puppet, Chef, etc. -## What is Service Mesh Automation? - -** Waiting to hear back from Marketing what this question means**. - ## What is a Multi Platform Service Mesh? A multi-platform service mesh is capable of supporting various infrastructure environments. This can range from having the service mesh support Kubernetes and non-Kubernetes workloads, to having a service mesh span across various cloud environments (multi-cloud). From c335043da95ee30c2537ee1e96878293dcb966a8 Mon Sep 17 00:00:00 2001 From: Jake Herschman Date: Wed, 19 Jan 2022 13:20:44 -0800 Subject: [PATCH 20/78] updated chart to reflect accurate cross app compatibility --- website/content/docs/nia/compatibility.mdx | 32 ++++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index 455203fa40..0fdca61db8 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -1,6 +1,6 @@ --- layout: docs -page_title: Consul-Terraform-Sync (CTS) Compatibility +page_title: Consul-Terraform-Sync (CTS) Compatibility description: >- Consul-Terraform-Sync (CTS) Compatibility --- @@ -11,22 +11,18 @@ description: >- The following table describes Consul-Terraform-Sync version compatibility for Consul, Terraform, and Vault. -| | **CTS OSS**
0.1+ | **CTS Enterprise**
0.3+ | -| :------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------: | :----------------------------------------------------------------------------: | -| **Consul OSS**
1.8+ | | | -| **Consul Enterprise**
1.8+ | | | -| **HCP Consul**
1.8+ | | | -| | -| **Terraform OSS**
0.13 - 1.0 | | | -| **Terraform Enterprise**
2020 10-2 - Latest | | | -| **Terraform Cloud**
Continuous Updates | |
CTS 0.4+ | -| | -| **\*Vault OSS**
0.7+ | | | -| **\*Vault Enterprise**
0.7+ | | | -| **\*HCP Vault**
0.7+ | | | +| | **CTS OSS**
0.1+ | **CTS Enterprise**
0.3+ | +| :---------------------------------------------------------------------: | :--------------------------------------------: | :--------------------------------------------------------------------: | +| **Consul OSS**
1.8+ | | | +| **Consul Enterprise**
1.8+ | | | +| | +| **Terraform OSS**
0.13 - 1.1 | | | +| **Terraform Enterprise**
2020 10-2 - Latest | | | +| **Terraform Cloud**
Continuous Updates | |
CTS 0.4+ | +| | +| **\*Vault OSS**
0.7+ | | | +| **\*Vault Enterprise**
0.7+ | | |

- - *CTS integrates with Vault to query secrets - -

\ No newline at end of file + *CTS integrates with Vault to query secrets +

From 241663a046af0ce2b63e45e7b7b80663e55187c0 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sat, 22 Jan 2022 14:07:26 -0500 Subject: [PATCH 21/78] acl: embed ACLResolver in Client and Server In preparation for removing duplicate resolve token methods. --- agent/consul/acl_client.go | 4 ++-- agent/consul/acl_endpoint.go | 22 ++++++++++----------- agent/consul/acl_server.go | 10 +++++----- agent/consul/acl_test.go | 6 +++--- agent/consul/acl_token_exp.go | 2 +- agent/consul/client.go | 6 +++--- agent/consul/intention_endpoint.go | 2 +- agent/consul/internal_endpoint.go | 2 +- agent/consul/leader.go | 2 +- agent/consul/operator_autopilot_endpoint.go | 8 ++++---- agent/consul/operator_raft_endpoint.go | 4 ++-- agent/consul/server.go | 8 ++++---- agent/consul/server_serf.go | 2 +- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/agent/consul/acl_client.go b/agent/consul/acl_client.go index 36f3f19a79..89fcd1b81f 100644 --- a/agent/consul/acl_client.go +++ b/agent/consul/acl_client.go @@ -48,12 +48,12 @@ func (c *Client) ResolveTokenToIdentity(token string) (structs.ACLIdentity, erro // not using ResolveTokenToIdentityAndAuthorizer because in this case we don't // need to resolve the roles, policies and namespace but just want the identity // information such as accessor id. - return c.acls.ResolveTokenToIdentity(token) + return c.ACLResolver.ResolveTokenToIdentity(token) } // TODO: Server has an identical implementation, remove duplication func (c *Client) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { - identity, authz, err := c.acls.ResolveTokenToIdentityAndAuthorizer(token) + identity, authz, err := c.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) if err != nil { return nil, err } diff --git a/agent/consul/acl_endpoint.go b/agent/consul/acl_endpoint.go index 376278c835..13799c3182 100644 --- a/agent/consul/acl_endpoint.go +++ b/agent/consul/acl_endpoint.go @@ -724,7 +724,7 @@ func (a *ACL) tokenSetInternal(args *structs.ACLTokenSetRequest, reply *structs. } // Purge the identity from the cache to prevent using the previous definition of the identity - a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) + a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) // Don't check expiration times here as it doesn't really matter. if _, updatedToken, err := a.srv.fsm.State().ACLTokenGetByAccessor(nil, token.AccessorID, nil); err == nil && updatedToken != nil { @@ -876,7 +876,7 @@ func (a *ACL) TokenDelete(args *structs.ACLTokenDeleteRequest, reply *string) er } // Purge the identity from the cache to prevent using the previous definition of the identity - a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) + a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) if reply != nil { *reply = token.AccessorID @@ -1198,7 +1198,7 @@ func (a *ACL) PolicySet(args *structs.ACLPolicySetRequest, reply *structs.ACLPol } // Remove from the cache to prevent stale cache usage - a.srv.acls.cache.RemovePolicy(policy.ID) + a.srv.ACLResolver.cache.RemovePolicy(policy.ID) if _, policy, err := a.srv.fsm.State().ACLPolicyGetByID(nil, policy.ID, &policy.EnterpriseMeta); err == nil && policy != nil { *reply = *policy @@ -1257,7 +1257,7 @@ func (a *ACL) PolicyDelete(args *structs.ACLPolicyDeleteRequest, reply *string) return fmt.Errorf("Failed to apply policy delete request: %v", err) } - a.srv.acls.cache.RemovePolicy(policy.ID) + a.srv.ACLResolver.cache.RemovePolicy(policy.ID) *reply = policy.Name @@ -1318,12 +1318,12 @@ func (a *ACL) PolicyResolve(args *structs.ACLPolicyBatchGetRequest, reply *struc } // get full list of policies for this token - identity, policies, err := a.srv.acls.resolveTokenToIdentityAndPolicies(args.Token) + identity, policies, err := a.srv.ACLResolver.resolveTokenToIdentityAndPolicies(args.Token) if err != nil { return err } - entIdentity, entPolicies, err := a.srv.acls.resolveEnterpriseIdentityAndPolicies(identity) + entIdentity, entPolicies, err := a.srv.ACLResolver.resolveEnterpriseIdentityAndPolicies(identity) if err != nil { return err } @@ -1609,7 +1609,7 @@ func (a *ACL) RoleSet(args *structs.ACLRoleSetRequest, reply *structs.ACLRole) e } // Remove from the cache to prevent stale cache usage - a.srv.acls.cache.RemoveRole(role.ID) + a.srv.ACLResolver.cache.RemoveRole(role.ID) if _, role, err := a.srv.fsm.State().ACLRoleGetByID(nil, role.ID, &role.EnterpriseMeta); err == nil && role != nil { *reply = *role @@ -1664,7 +1664,7 @@ func (a *ACL) RoleDelete(args *structs.ACLRoleDeleteRequest, reply *string) erro return fmt.Errorf("Failed to apply role delete request: %v", err) } - a.srv.acls.cache.RemoveRole(role.ID) + a.srv.ACLResolver.cache.RemoveRole(role.ID) *reply = role.Name @@ -1719,12 +1719,12 @@ func (a *ACL) RoleResolve(args *structs.ACLRoleBatchGetRequest, reply *structs.A } // get full list of roles for this token - identity, roles, err := a.srv.acls.resolveTokenToIdentityAndRoles(args.Token) + identity, roles, err := a.srv.ACLResolver.resolveTokenToIdentityAndRoles(args.Token) if err != nil { return err } - entIdentity, entRoles, err := a.srv.acls.resolveEnterpriseIdentityAndRoles(identity) + entIdentity, entRoles, err := a.srv.ACLResolver.resolveEnterpriseIdentityAndRoles(identity) if err != nil { return err } @@ -2481,7 +2481,7 @@ func (a *ACL) Logout(args *structs.ACLLogoutRequest, reply *bool) error { } // Purge the identity from the cache to prevent using the previous definition of the identity - a.srv.acls.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) + a.srv.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(token.SecretID)) *reply = true diff --git a/agent/consul/acl_server.go b/agent/consul/acl_server.go index f16b1cc864..28c83ab116 100644 --- a/agent/consul/acl_server.go +++ b/agent/consul/acl_server.go @@ -160,7 +160,7 @@ func (s *Server) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error } func (s *Server) ResolveToken(token string) (acl.Authorizer, error) { - _, authz, err := s.acls.ResolveTokenToIdentityAndAuthorizer(token) + _, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) return authz, err } @@ -168,12 +168,12 @@ func (s *Server) ResolveTokenToIdentity(token string) (structs.ACLIdentity, erro // not using ResolveTokenToIdentityAndAuthorizer because in this case we don't // need to resolve the roles, policies and namespace but just want the identity // information such as accessor id. - return s.acls.ResolveTokenToIdentity(token) + return s.ACLResolver.ResolveTokenToIdentity(token) } // TODO: Client has an identical implementation, remove duplication func (s *Server) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { - identity, authz, err := s.acls.ResolveTokenToIdentityAndAuthorizer(token) + identity, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) if err != nil { return nil, err } @@ -197,9 +197,9 @@ func (s *Server) ResolveTokenAndDefaultMeta(token string, entMeta *structs.Enter } func (s *Server) filterACL(token string, subj interface{}) error { - return filterACL(s.acls, token, subj) + return filterACL(s.ACLResolver, token, subj) } func (s *Server) filterACLWithAuthorizer(authorizer acl.Authorizer, subj interface{}) { - filterACLWithAuthorizer(s.acls.logger, authorizer, subj) + filterACLWithAuthorizer(s.ACLResolver.logger, authorizer, subj) } diff --git a/agent/consul/acl_test.go b/agent/consul/acl_test.go index d45b1e1973..2d4f7dc5ec 100644 --- a/agent/consul/acl_test.go +++ b/agent/consul/acl_test.go @@ -4065,7 +4065,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t require.NoError(t, err) runStep(t, "first resolve", func(t *testing.T) { - _, authz, err := srv.acls.ResolveTokenToIdentityAndAuthorizer(token) + _, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) require.NoError(t, err) require.NotNil(t, authz) require.Equal(t, acl.Allow, authz.KeyRead("foo", nil)) @@ -4084,7 +4084,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t err := msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{}) require.NoError(t, err) - _, authz, err := srv.acls.ResolveTokenToIdentityAndAuthorizer(token) + _, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) require.NoError(t, err) require.NotNil(t, authz) require.Equal(t, acl.Deny, authz.KeyRead("foo", nil)) @@ -4100,7 +4100,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t err := msgpackrpc.CallWithCodec(codec, "ACL.TokenDelete", &req, &resp) require.NoError(t, err) - _, _, err = srv.acls.ResolveTokenToIdentityAndAuthorizer(token) + _, _, err = srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) require.True(t, acl.IsErrNotFound(err), "Error %v is not acl.ErrNotFound", err) }) } diff --git a/agent/consul/acl_token_exp.go b/agent/consul/acl_token_exp.go index a4dfa180fb..370d140ef7 100644 --- a/agent/consul/acl_token_exp.go +++ b/agent/consul/acl_token_exp.go @@ -107,7 +107,7 @@ func (s *Server) reapExpiredACLTokens(local, global bool) (int, error) { // Purge the identities from the cache for _, secretID := range secretIDs { - s.acls.cache.RemoveIdentity(tokenSecretCacheID(secretID)) + s.ACLResolver.cache.RemoveIdentity(tokenSecretCacheID(secretID)) } return len(req.TokenIDs), nil diff --git a/agent/consul/client.go b/agent/consul/client.go index 999f986634..d83a1c3c19 100644 --- a/agent/consul/client.go +++ b/agent/consul/client.go @@ -56,7 +56,7 @@ type Client struct { config *Config // acls is used to resolve tokens to effective policies - acls *ACLResolver + *ACLResolver // Connection pool to consul servers connPool *pool.ConnPool @@ -127,7 +127,7 @@ func NewClient(config *Config, deps Deps) (*Client, error) { Tokens: deps.Tokens, } var err error - if c.acls, err = NewACLResolver(&aclConfig); err != nil { + if c.ACLResolver, err = NewACLResolver(&aclConfig); err != nil { c.Shutdown() return nil, fmt.Errorf("Failed to create ACL resolver: %v", err) } @@ -172,7 +172,7 @@ func (c *Client) Shutdown() error { // Close the connection pool c.connPool.Shutdown() - c.acls.Close() + c.ACLResolver.Close() return nil } diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go index 862637de5a..814d1590a6 100644 --- a/agent/consul/intention_endpoint.go +++ b/agent/consul/intention_endpoint.go @@ -100,7 +100,7 @@ func (s *Intention) Apply(args *structs.IntentionRequest, reply *string) error { } // Get the ACL token for the request for the checks below. - identity, authz, err := s.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := s.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } diff --git a/agent/consul/internal_endpoint.go b/agent/consul/internal_endpoint.go index 14fbc4be41..dea21cfc6f 100644 --- a/agent/consul/internal_endpoint.go +++ b/agent/consul/internal_endpoint.go @@ -433,7 +433,7 @@ func (m *Internal) KeyringOperation( } // Check ACLs - identity, authz, err := m.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := m.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } diff --git a/agent/consul/leader.go b/agent/consul/leader.go index 1b55767b15..d8bf099d0e 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -363,7 +363,7 @@ func (s *Server) initializeACLs(ctx context.Context) error { // Purge the cache, since it could've changed while we were not the // leader. - s.acls.cache.Purge() + s.ACLResolver.cache.Purge() // Purge the auth method validators since they could've changed while we // were not leader. diff --git a/agent/consul/operator_autopilot_endpoint.go b/agent/consul/operator_autopilot_endpoint.go index 9430b30de3..d600df83cb 100644 --- a/agent/consul/operator_autopilot_endpoint.go +++ b/agent/consul/operator_autopilot_endpoint.go @@ -17,7 +17,7 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r } // This action requires operator read access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } @@ -49,7 +49,7 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe } // This action requires operator write access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } @@ -84,7 +84,7 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *structs } // This action requires operator read access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } @@ -151,7 +151,7 @@ func (op *Operator) AutopilotState(args *structs.DCSpecificRequest, reply *autop } // This action requires operator read access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } diff --git a/agent/consul/operator_raft_endpoint.go b/agent/consul/operator_raft_endpoint.go index 4cf38185ad..72ae5b195b 100644 --- a/agent/consul/operator_raft_endpoint.go +++ b/agent/consul/operator_raft_endpoint.go @@ -81,7 +81,7 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest, // This is a super dangerous operation that requires operator write // access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } @@ -134,7 +134,7 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl // This is a super dangerous operation that requires operator write // access. - identity, authz, err := op.srv.acls.ResolveTokenToIdentityAndAuthorizer(args.Token) + identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err } diff --git a/agent/consul/server.go b/agent/consul/server.go index e076af7214..851e1745b0 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -141,7 +141,7 @@ type Server struct { aclConfig *acl.Config // acls is used to resolve tokens to effective policies - acls *ACLResolver + *ACLResolver aclAuthMethodValidators authmethod.Cache @@ -457,7 +457,7 @@ func NewServer(config *Config, flat Deps) (*Server, error) { Tokens: flat.Tokens, } // Initialize the ACL resolver. - if s.acls, err = NewACLResolver(&aclConfig); err != nil { + if s.ACLResolver, err = NewACLResolver(&aclConfig); err != nil { s.Shutdown() return nil, fmt.Errorf("Failed to create ACL resolver: %v", err) } @@ -994,8 +994,8 @@ func (s *Server) Shutdown() error { s.connPool.Shutdown() } - if s.acls != nil { - s.acls.Close() + if s.ACLResolver != nil { + s.ACLResolver.Close() } if s.fsm != nil { diff --git a/agent/consul/server_serf.go b/agent/consul/server_serf.go index 44c3f857a4..ff1b1e4064 100644 --- a/agent/consul/server_serf.go +++ b/agent/consul/server_serf.go @@ -121,7 +121,7 @@ func (s *Server) setupSerfConfig(opts setupSerfOptions) (*serf.Config, error) { // TODO(ACL-Legacy-Compat): remove in phase 2. These are kept for now to // allow for upgrades. - if s.acls.ACLsEnabled() { + if s.ACLResolver.ACLsEnabled() { conf.Tags[metadata.TagACLs] = string(structs.ACLModeEnabled) } else { conf.Tags[metadata.TagACLs] = string(structs.ACLModeDisabled) From 8c9c48e2191829a1fdf203faf892098338ea5e99 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sat, 22 Jan 2022 14:12:08 -0500 Subject: [PATCH 22/78] acl: remove duplicate methods Now that ACLResolver is embedded we don't need ResolveTokenToIdentity on Client and Server. Moving ResolveTokenAndDefaultMeta to ACLResolver removes the duplicate implementation. --- agent/consul/acl.go | 24 ++++++++++++++++++++++++ agent/consul/acl_client.go | 33 --------------------------------- agent/consul/acl_server.go | 30 ------------------------------ 3 files changed, 24 insertions(+), 63 deletions(-) diff --git a/agent/consul/acl.go b/agent/consul/acl.go index b475bf1596..797bd22e4f 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1158,6 +1158,30 @@ func (r *ACLResolver) ACLsEnabled() bool { return true } +func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { + identity, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) + if err != nil { + return nil, err + } + + if entMeta == nil { + entMeta = &structs.EnterpriseMeta{} + } + + // Default the EnterpriseMeta based on the Tokens meta or actual defaults + // in the case of unknown identity + if identity != nil { + entMeta.Merge(identity.EnterpriseMetadata()) + } else { + entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) + } + + // Use the meta to fill in the ACL authorization context + entMeta.FillAuthzContext(authzContext) + + return authz, err +} + // aclFilter is used to filter results from our state store based on ACL rules // configured for the provided token. type aclFilter struct { diff --git a/agent/consul/acl_client.go b/agent/consul/acl_client.go index 89fcd1b81f..0d11906a34 100644 --- a/agent/consul/acl_client.go +++ b/agent/consul/acl_client.go @@ -1,7 +1,6 @@ package consul import ( - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" ) @@ -43,35 +42,3 @@ func (c *Client) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error // clients do no local role resolution at the moment return false, nil, nil } - -func (c *Client) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) { - // not using ResolveTokenToIdentityAndAuthorizer because in this case we don't - // need to resolve the roles, policies and namespace but just want the identity - // information such as accessor id. - return c.ACLResolver.ResolveTokenToIdentity(token) -} - -// TODO: Server has an identical implementation, remove duplication -func (c *Client) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { - identity, authz, err := c.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) - if err != nil { - return nil, err - } - - if entMeta == nil { - entMeta = &structs.EnterpriseMeta{} - } - - // Default the EnterpriseMeta based on the Tokens meta or actual defaults - // in the case of unknown identity - if identity != nil { - entMeta.Merge(identity.EnterpriseMetadata()) - } else { - entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) - } - - // Use the meta to fill in the ACL authorization context - entMeta.FillAuthzContext(authzContext) - - return authz, err -} diff --git a/agent/consul/acl_server.go b/agent/consul/acl_server.go index 28c83ab116..3802145fad 100644 --- a/agent/consul/acl_server.go +++ b/agent/consul/acl_server.go @@ -164,37 +164,7 @@ func (s *Server) ResolveToken(token string) (acl.Authorizer, error) { return authz, err } -func (s *Server) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) { - // not using ResolveTokenToIdentityAndAuthorizer because in this case we don't - // need to resolve the roles, policies and namespace but just want the identity - // information such as accessor id. - return s.ACLResolver.ResolveTokenToIdentity(token) -} - // TODO: Client has an identical implementation, remove duplication -func (s *Server) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { - identity, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) - if err != nil { - return nil, err - } - - if entMeta == nil { - entMeta = &structs.EnterpriseMeta{} - } - - // Default the EnterpriseMeta based on the Tokens meta or actual defaults - // in the case of unknown identity - if identity != nil { - entMeta.Merge(identity.EnterpriseMetadata()) - } else { - entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) - } - - // Use the meta to fill in the ACL authorization context - entMeta.FillAuthzContext(authzContext) - - return authz, err -} func (s *Server) filterACL(token string, subj interface{}) error { return filterACL(s.ACLResolver, token, subj) From a5e8af79c341ebf8fe0989dea1fdb9e74213b885 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sat, 22 Jan 2022 14:33:09 -0500 Subject: [PATCH 23/78] acl: return a resposne from ResolveToken that includes the ACLIdentity So that we can duplicate duplicate methods. --- agent/acl_test.go | 6 +++--- agent/agent.go | 2 +- agent/agent_endpoint_test.go | 4 ++-- agent/consul/acl.go | 19 ++++++++++++++++--- agent/consul/acl_server.go | 3 +-- agent/consul/intention_endpoint.go | 1 + agent/structs/acl.go | 4 ++-- 7 files changed, 26 insertions(+), 13 deletions(-) diff --git a/agent/acl_test.go b/agent/acl_test.go index c085e49a39..7d8039511a 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -102,10 +102,10 @@ func (a *TestACLAgent) ResolveTokenToIdentity(secretID string) (structs.ACLIdent return a.resolveIdentFn(secretID) } -func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { +func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) { identity, authz, err := a.ResolveTokenToIdentityAndAuthorizer(secretID) if err != nil { - return nil, err + return consul.ACLResolveResult{}, err } // Default the EnterpriseMeta based on the Tokens meta or actual defaults @@ -119,7 +119,7 @@ func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *stru // Use the meta to fill in the ACL authorization context entMeta.FillAuthzContext(authzContext) - return authz, err + return consul.ACLResolveResult{Authorizer: authz, ACLIdentity: identity}, err } // All of these are stubs to satisfy the interface diff --git a/agent/agent.go b/agent/agent.go index 41bab89e7f..ba587d3434 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -174,7 +174,7 @@ type delegate interface { // actions based on the permissions granted to the token. // If either entMeta or authzContext are non-nil they will be populated with the // default partition and namespace from the token. - ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) + ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) RPC(method string, args interface{}, reply interface{}) error SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io.Writer, replyFn structs.SnapshotReplyFn) error diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index 8e965db38e..70840f9502 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -1640,8 +1640,8 @@ type fakeResolveTokenDelegate struct { authorizer acl.Authorizer } -func (f fakeResolveTokenDelegate) ResolveTokenAndDefaultMeta(_ string, _ *structs.EnterpriseMeta, _ *acl.AuthorizerContext) (acl.Authorizer, error) { - return f.authorizer, nil +func (f fakeResolveTokenDelegate) ResolveTokenAndDefaultMeta(_ string, _ *structs.EnterpriseMeta, _ *acl.AuthorizerContext) (consul.ACLResolveResult, error) { + return consul.ACLResolveResult{Authorizer: f.authorizer}, nil } func TestAgent_Reload(t *testing.T) { diff --git a/agent/consul/acl.go b/agent/consul/acl.go index 797bd22e4f..d033db1b97 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1115,6 +1115,19 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs return identity, acl.NewChainedAuthorizer(chain), nil } +type ACLResolveResult struct { + acl.Authorizer + // TODO: likely we can reduce this interface + structs.ACLIdentity +} + +func (a ACLResolveResult) AccessorID() string { + if a.ACLIdentity == nil { + return "" + } + return a.ACLIdentity.ID() +} + // TODO: rename to AccessorIDFromToken. This method is only used to retrieve the // ACLIdentity.ID, so we don't need to return a full ACLIdentity. We could // return a much smaller type (instad of just a string) to allow for changes @@ -1158,10 +1171,10 @@ func (r *ACLResolver) ACLsEnabled() bool { return true } -func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { +func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (ACLResolveResult, error) { identity, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) if err != nil { - return nil, err + return ACLResolveResult{}, err } if entMeta == nil { @@ -1179,7 +1192,7 @@ func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs. // Use the meta to fill in the ACL authorization context entMeta.FillAuthzContext(authzContext) - return authz, err + return ACLResolveResult{Authorizer: authz, ACLIdentity: identity}, err } // aclFilter is used to filter results from our state store based on ACL rules diff --git a/agent/consul/acl_server.go b/agent/consul/acl_server.go index 3802145fad..21b4d95032 100644 --- a/agent/consul/acl_server.go +++ b/agent/consul/acl_server.go @@ -159,13 +159,12 @@ func (s *Server) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error return s.InPrimaryDatacenter() || index > 0, role, acl.ErrNotFound } +// TODO: remove func (s *Server) ResolveToken(token string) (acl.Authorizer, error) { _, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) return authz, err } -// TODO: Client has an identical implementation, remove duplication - func (s *Server) filterACL(token string, subj interface{}) error { return filterACL(s.ACLResolver, token, subj) } diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go index 814d1590a6..57d3fc7667 100644 --- a/agent/consul/intention_endpoint.go +++ b/agent/consul/intention_endpoint.go @@ -100,6 +100,7 @@ func (s *Intention) Apply(args *structs.IntentionRequest, reply *string) error { } // Get the ACL token for the request for the checks below. + // TODO: use ResolveTokenAndDefaultMeta identity, authz, err := s.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) if err != nil { return err diff --git a/agent/structs/acl.go b/agent/structs/acl.go index 756cadbb1b..42fa558215 100644 --- a/agent/structs/acl.go +++ b/agent/structs/acl.go @@ -89,8 +89,8 @@ var ACLBootstrapNotAllowedErr = errors.New("ACL bootstrap no longer allowed") var ACLBootstrapInvalidResetIndexErr = errors.New("Invalid ACL bootstrap reset index") type ACLIdentity interface { - // ID returns a string that can be used for logging and telemetry. This should not - // contain any secret data used for authentication + // ID returns the accessor ID, a string that can be used for logging and + // telemetry. It is not the secret ID used for authentication. ID() string SecretToken() string PolicyIDs() []string From edca8d61a365c5c45daaba7bc3f20075e80745d6 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sat, 22 Jan 2022 14:47:59 -0500 Subject: [PATCH 24/78] acl: remove ResolveTokenToIdentity By exposing the AccessorID from the primary ResolveToken method we can remove this duplication. --- agent/acl.go | 7 ++----- agent/acl_test.go | 19 ------------------- agent/agent.go | 3 --- agent/consul/acl.go | 27 --------------------------- agent/consul/acl_test.go | 30 ------------------------------ agent/local/state.go | 10 ++++------ agent/local/state_test.go | 6 ++++-- 7 files changed, 10 insertions(+), 92 deletions(-) diff --git a/agent/acl.go b/agent/acl.go index fa2259cfd3..7b92210ed8 100644 --- a/agent/acl.go +++ b/agent/acl.go @@ -15,7 +15,7 @@ import ( // critical purposes, such as logging. Therefore we interpret all errors as empty-string // so we can safely log it without handling non-critical errors at the usage site. func (a *Agent) aclAccessorID(secretID string) string { - ident, err := a.delegate.ResolveTokenToIdentity(secretID) + ident, err := a.delegate.ResolveTokenAndDefaultMeta(secretID, nil, nil) if acl.IsErrNotFound(err) { return "" } @@ -23,10 +23,7 @@ func (a *Agent) aclAccessorID(secretID string) string { a.logger.Debug("non-critical error resolving acl token accessor for logging", "error", err) return "" } - if ident == nil { - return "" - } - return ident.ID() + return ident.AccessorID() } // vetServiceRegister makes sure the service registration action is allowed by diff --git a/agent/acl_test.go b/agent/acl_test.go index 7d8039511a..b205220f67 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -523,22 +523,3 @@ func TestACL_filterChecksWithAuthorizer(t *testing.T) { _, ok = checks["my-other"] require.False(t, ok) } - -// TODO: remove? -func TestACL_ResolveIdentity(t *testing.T) { - t.Parallel() - a := NewTestACLAgent(t, t.Name(), TestACLConfig(), nil, catalogIdent) - - // this test is meant to ensure we are calling the correct function - // which is ResolveTokenToIdentity on the Agent delegate. Our - // nil authz resolver will cause it to emit an error if used - ident, err := a.delegate.ResolveTokenToIdentity(nodeROSecret) - require.NoError(t, err) - require.NotNil(t, ident) - - // just double checkingto ensure if we had used the wrong function - // that an error would be produced - _, err = a.delegate.ResolveTokenAndDefaultMeta(nodeROSecret, nil, nil) - require.Error(t, err) - -} diff --git a/agent/agent.go b/agent/agent.go index ba587d3434..7e2a7f110a 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -167,9 +167,6 @@ type delegate interface { // RemoveFailedNode is used to remove a failed node from the cluster. RemoveFailedNode(node string, prune bool, entMeta *structs.EnterpriseMeta) error - // TODO: replace this method with consul.ACLResolver - ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) - // ResolveTokenAndDefaultMeta returns an acl.Authorizer which authorizes // actions based on the permissions granted to the token. // If either entMeta or authzContext are non-nil they will be populated with the diff --git a/agent/consul/acl.go b/agent/consul/acl.go index d033db1b97..da89e2dd3d 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1128,33 +1128,6 @@ func (a ACLResolveResult) AccessorID() string { return a.ACLIdentity.ID() } -// TODO: rename to AccessorIDFromToken. This method is only used to retrieve the -// ACLIdentity.ID, so we don't need to return a full ACLIdentity. We could -// return a much smaller type (instad of just a string) to allow for changes -// in the future. -func (r *ACLResolver) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) { - if !r.ACLsEnabled() { - return nil, nil - } - - if acl.RootAuthorizer(token) != nil { - return nil, acl.ErrRootDenied - } - - // handle the anonymous token - if token == "" { - token = anonymousToken - } - - if ident, _, ok := r.resolveLocallyManagedToken(token); ok { - return ident, nil - } - - defer metrics.MeasureSince([]string{"acl", "ResolveTokenToIdentity"}, time.Now()) - - return r.resolveIdentityFromToken(token) -} - func (r *ACLResolver) ACLsEnabled() bool { // Whether we desire ACLs to be enabled according to configuration if !r.config.ACLsEnabled { diff --git a/agent/consul/acl_test.go b/agent/consul/acl_test.go index 2d4f7dc5ec..0e663120a9 100644 --- a/agent/consul/acl_test.go +++ b/agent/consul/acl_test.go @@ -1534,36 +1534,6 @@ func TestACLResolver_Client(t *testing.T) { require.Equal(t, policyResolves, int32(3)) }) - t.Run("Resolve-Identity", func(t *testing.T) { - t.Parallel() - - delegate := &ACLResolverTestDelegate{ - enabled: true, - datacenter: "dc1", - legacy: false, - localTokens: false, - localPolicies: false, - } - - delegate.tokenReadFn = delegate.plainTokenReadFn - delegate.policyResolveFn = delegate.plainPolicyResolveFn - delegate.roleResolveFn = delegate.plainRoleResolveFn - - r := newTestACLResolver(t, delegate, nil) - - ident, err := r.ResolveTokenToIdentity("found-policy-and-role") - require.NoError(t, err) - require.NotNil(t, ident) - require.Equal(t, "5f57c1f6-6a89-4186-9445-531b316e01df", ident.ID()) - require.EqualValues(t, 0, delegate.localTokenResolutions) - require.EqualValues(t, 1, delegate.remoteTokenResolutions) - require.EqualValues(t, 0, delegate.localPolicyResolutions) - require.EqualValues(t, 0, delegate.remotePolicyResolutions) - require.EqualValues(t, 0, delegate.localRoleResolutions) - require.EqualValues(t, 0, delegate.remoteRoleResolutions) - require.EqualValues(t, 0, delegate.remoteLegacyResolutions) - }) - t.Run("Concurrent-Token-Resolve", func(t *testing.T) { t.Parallel() diff --git a/agent/local/state.go b/agent/local/state.go index 5c70b0c8d0..1eb5733bbe 100644 --- a/agent/local/state.go +++ b/agent/local/state.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/go-hclog" "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/api" @@ -150,7 +151,7 @@ func (c *CheckState) CriticalFor() time.Duration { type rpc interface { RPC(method string, args interface{}, reply interface{}) error - ResolveTokenToIdentity(secretID string) (structs.ACLIdentity, error) + ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) } // State is used to represent the node's services, @@ -1538,7 +1539,7 @@ func (l *State) notifyIfAliased(serviceID structs.ServiceID) { // critical purposes, such as logging. Therefore we interpret all errors as empty-string // so we can safely log it without handling non-critical errors at the usage site. func (l *State) aclAccessorID(secretID string) string { - ident, err := l.Delegate.ResolveTokenToIdentity(secretID) + ident, err := l.Delegate.ResolveTokenAndDefaultMeta(secretID, nil, nil) if acl.IsErrNotFound(err) { return "" } @@ -1546,8 +1547,5 @@ func (l *State) aclAccessorID(secretID string) string { l.logger.Debug("non-critical error resolving acl token accessor for logging", "error", err) return "" } - if ident == nil { - return "" - } - return ident.ID() + return ident.AccessorID() } diff --git a/agent/local/state_test.go b/agent/local/state_test.go index 036e156fc1..1be9274e1a 100644 --- a/agent/local/state_test.go +++ b/agent/local/state_test.go @@ -12,8 +12,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent" "github.com/hashicorp/consul/agent/config" + "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/local" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" @@ -2372,6 +2374,6 @@ func (f *fakeRPC) RPC(method string, args interface{}, reply interface{}) error return nil } -func (f *fakeRPC) ResolveTokenToIdentity(_ string) (structs.ACLIdentity, error) { - return nil, nil +func (f *fakeRPC) ResolveTokenAndDefaultMeta(string, *structs.EnterpriseMeta, *acl.AuthorizerContext) (consul.ACLResolveResult, error) { + return consul.ACLResolveResult{}, nil } From e134e43da6f9550df8f11043c35d4a8f2eed7b89 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sat, 22 Jan 2022 15:05:42 -0500 Subject: [PATCH 25/78] acl: remove calls to ResolveIdentityFromToken We already have an ACLResolveResult, so we can get the accessor ID from it. --- agent/consul/intention_endpoint.go | 31 ++++++------------------------ agent/consul/internal_endpoint.go | 22 ++------------------- 2 files changed, 8 insertions(+), 45 deletions(-) diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go index 57d3fc7667..2031641caa 100644 --- a/agent/consul/intention_endpoint.go +++ b/agent/consul/intention_endpoint.go @@ -433,7 +433,8 @@ func (s *Intention) Get(args *structs.IntentionQueryRequest, reply *structs.Inde // Get the ACL token for the request for the checks below. var entMeta structs.EnterpriseMeta - if _, err := s.srv.ResolveTokenAndDefaultMeta(args.Token, &entMeta, nil); err != nil { + authz, err := s.srv.ResolveTokenAndDefaultMeta(args.Token, &entMeta, nil) + if err != nil { return err } @@ -480,13 +481,11 @@ func (s *Intention) Get(args *structs.IntentionQueryRequest, reply *structs.Inde reply.Intentions = structs.Intentions{ixn} // Filter - if err := s.srv.filterACL(args.Token, reply); err != nil { - return err - } + s.srv.filterACLWithAuthorizer(authz, reply) // If ACLs prevented any responses, error if len(reply.Intentions) == 0 { - accessorID := s.aclAccessorID(args.Token) + accessorID := authz.AccessorID() // todo(kit) Migrate intention access denial logging over to audit logging when we implement it s.logger.Warn("Request to get intention denied due to ACLs", "intention", args.IntentionID, "accessorID", accessorID) return acl.ErrPermissionDenied @@ -619,7 +618,7 @@ func (s *Intention) Match(args *structs.IntentionQueryRequest, reply *structs.In for _, entry := range args.Match.Entries { entry.FillAuthzContext(&authzContext) if prefix := entry.Name; prefix != "" && authz.IntentionRead(prefix, &authzContext) != acl.Allow { - accessorID := s.aclAccessorID(args.Token) + accessorID := authz.AccessorID() // todo(kit) Migrate intention access denial logging over to audit logging when we implement it s.logger.Warn("Operation on intention prefix denied due to ACLs", "prefix", prefix, "accessorID", accessorID) return acl.ErrPermissionDenied @@ -709,7 +708,7 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In var authzContext acl.AuthorizerContext query.FillAuthzContext(&authzContext) if authz.ServiceRead(prefix, &authzContext) != acl.Allow { - accessorID := s.aclAccessorID(args.Token) + accessorID := authz.AccessorID() // todo(kit) Migrate intention access denial logging over to audit logging when we implement it s.logger.Warn("test on intention denied due to ACLs", "prefix", prefix, "accessorID", accessorID) return acl.ErrPermissionDenied @@ -761,24 +760,6 @@ func (s *Intention) Check(args *structs.IntentionQueryRequest, reply *structs.In return nil } -// aclAccessorID is used to convert an ACLToken's secretID to its accessorID for non- -// critical purposes, such as logging. Therefore we interpret all errors as empty-string -// so we can safely log it without handling non-critical errors at the usage site. -func (s *Intention) aclAccessorID(secretID string) string { - _, ident, err := s.srv.ResolveIdentityFromToken(secretID) - if acl.IsErrNotFound(err) { - return "" - } - if err != nil { - s.logger.Debug("non-critical error resolving acl token accessor for logging", "error", err) - return "" - } - if ident == nil { - return "" - } - return ident.ID() -} - func (s *Intention) validateEnterpriseIntention(ixn *structs.Intention) error { if err := s.srv.validateEnterpriseIntentionPartition(ixn.SourcePartition); err != nil { return fmt.Errorf("Invalid source partition %q: %v", ixn.SourcePartition, err) diff --git a/agent/consul/internal_endpoint.go b/agent/consul/internal_endpoint.go index dea21cfc6f..5213349e79 100644 --- a/agent/consul/internal_endpoint.go +++ b/agent/consul/internal_endpoint.go @@ -401,13 +401,13 @@ func (m *Internal) EventFire(args *structs.EventFireRequest, } // Check ACLs - authz, err := m.srv.ResolveToken(args.Token) + authz, err := m.srv.ResolveTokenAndDefaultMeta(args.Token, nil, nil) if err != nil { return err } if authz.EventWrite(args.Name, nil) != acl.Allow { - accessorID := m.aclAccessorID(args.Token) + accessorID := authz.AccessorID() m.logger.Warn("user event blocked by ACLs", "event", args.Name, "accessorID", accessorID) return acl.ErrPermissionDenied } @@ -545,21 +545,3 @@ func (m *Internal) executeKeyringOpMgr( return serfResp, err } - -// aclAccessorID is used to convert an ACLToken's secretID to its accessorID for non- -// critical purposes, such as logging. Therefore we interpret all errors as empty-string -// so we can safely log it without handling non-critical errors at the usage site. -func (m *Internal) aclAccessorID(secretID string) string { - _, ident, err := m.srv.ResolveIdentityFromToken(secretID) - if acl.IsErrNotFound(err) { - return "" - } - if err != nil { - m.logger.Debug("non-critical error resolving acl token accessor for logging", "error", err) - return "" - } - if ident == nil { - return "" - } - return ident.ID() -} From 3a74ca53747ee00fbdccf7f838521566a3472fbb Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Mon, 24 Jan 2022 11:18:37 -0700 Subject: [PATCH 26/78] pushing up local changes --- ...orm_sync_intro-consul_ui-services_status.png | Bin 0 -> 62374 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 website/public/img/consul_terraform_sync_intro-consul_ui-services_status.png diff --git a/website/public/img/consul_terraform_sync_intro-consul_ui-services_status.png b/website/public/img/consul_terraform_sync_intro-consul_ui-services_status.png new file mode 100644 index 0000000000000000000000000000000000000000..8880c56e89db4ba1a31120fb64134c389286e21c GIT binary patch literal 62374 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

lJ!o?aK@w78`->n9{Eg7dp3p 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 LYBGgVrosOUnUM*@ literal 0 HcmV?d00001 From 7baba1d05a862fa553637295debd235d54bb67ad Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Mon, 24 Jan 2022 11:20:12 -0700 Subject: [PATCH 27/78] Apply suggestions from code review Co-authored-by: Blake Covarrubias --- .../intro/usecases/what-is-a-service-mesh.mdx | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 3101db54f2..4579dd6a57 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -1,8 +1,8 @@ --- layout: docs -page_title: What is service mesh?? +page_title: What is service mesh? description: >- - Learn what a serive mesh is, it's benefits, and how it works. + Learn what a service mesh is, it's benefits, and how it works. --- # What is a Service Mesh? @@ -12,7 +12,7 @@ Service meshes are often used with a microservice architectural pattern, but can ## Benefits of a Service Mesh -A _service mesh_ provides benefits for all organziations, ranging from security to improved application resiliency. +A service mesh provides benefits for all organizations, ranging from security to improved application resiliency. Some of the benefits of a _service mesh_ include; - service discovery @@ -21,16 +21,16 @@ Some of the benefits of a _service mesh_ include; - automatic failover - traffic management - encryption -- observability and tracability, +- observability and traceability, - authentication and authorization, - network automation -A common usecase for leveraging a _service mesh_ is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). +A common use case for leveraging a _service mesh_ is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). In a _zero trust_ model, applications require identity-based access to ensure all communication within the service mesh is authenticated with TLS certificates and encrypted in transit. ## How does a Service Mesh work? -A _service meshe_ typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. +A _service mesh_ typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. @@ -49,14 +49,14 @@ The API Gateway will route the incoming requests to the respective service. API A _service mesh_ specializes in the network management of services and the communication between services. The mesh is responsible for keeping track of services and their health status, IP address, traffic routing, and ensuring all the traffic between services are authenticated and encrypted. Unlike API Gateways, a _service mesh_ will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. -API Gateways are frequently deployed alongside a loadbalancer to ensure traffic is directed to healthy and available instances of the service. -The mesh reduces the loadbalancer footprint as routing responsibilities are handled in a decentralized manner. +API Gateways are frequently deployed alongside a load balancer to ensure traffic is directed to healthy and available instances of the service. +The mesh reduces the load balancer footprint as routing responsibilities are handled in a decentralized manner. -API Gateways can be used togehter with a _service mesh_ to bridge external networks (non-mesh) with a _service mesh_. +API Gateways can be used together with a _service mesh_ to bridge external networks (non-mesh) with a _service mesh_. --> **Note**: API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a datacenter or a virutal private network (VPC). -A _service mesh_ is primarly used for handling east-west based traffic. East-west traffic traditionaly remains inside a datacenter or a VPC. -A _service mesh_ can be connected to another _service mesh_ in another datacenter or VPC to form a federated mesh. +-> **Note**: API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a data center or a virtual private network (VPC). +A _service mesh_ is primarily used for handling east-west based traffic. East-west traffic traditionally remains inside a data center or a VPC. +A _service mesh_ can be connected to another _service mesh_ in another data center or VPC to form a federated mesh. ## What Problems Does a Service Mesh Solve? @@ -69,7 +69,7 @@ As a service mesh is aware of the state of a service and its instances, the mesh Many service meshes offer L7 traffic management capabilities. As a result, operators and developers can create powerful rules to direct network traffic as needed, such as load balancing, traffic splitting, dynamic failover, and custom resolvers. A service mesh's dynamic network behavior allows application owners to improve application resiliency and availability with no application changes. -Implementing dynamic network behavior is critical as more and more applications are deployed across different cloud providers (multi-cloud) and private datacenters. +Implementing dynamic network behavior is critical as more and more applications are deployed across different cloud providers (multi-cloud) and private data centers. Organizations may need to route network traffic to other infrastructure environments. Ensuring this traffic is secure is on top of mind for all organizations. Service meshes offer the ability to enforce network traffic encryption (mTLS) and authentication between all services. The _service mesh_ can automatically generate an SSL certificate for each service and its instances. The certificate authenticates with other services inside the mesh and encrypts the TCP/UDP/gRPC connection with SSL. @@ -84,7 +84,7 @@ This shift from an IP address-based security model to a service-focused model re ## How Do You Implement a Service Mesh? Service meshes are commonly installed in Kubernetes clusters. There are also platform-agnostic service meshes available for non-Kubernetes-based workloads. -For Kubernetes, most service mesh can be installed by operators through a [Helm chart](https://artifacthub.io/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. +For Kubernetes, most service mesh can be installed by operators through a [Helm chart](https://helm.sh/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. Non-Kubernetes based service meshes can be installed through infrastructure as code (IaC) products such as [Terraform](https://www.terraform.io/), CloudFormation, ARM Templates, Puppet, Chef, etc. ## What is a Multi Platform Service Mesh? From bd11a5fe13813d09c3c77c520c435bbc72da86d4 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Mon, 24 Jan 2022 11:25:49 -0700 Subject: [PATCH 28/78] updated introduction and service mesh styling --- .../intro/usecases/what-is-a-service-mesh.mdx | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 4579dd6a57..a2eb0f89d8 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -1,8 +1,9 @@ --- layout: docs -page_title: What is service mesh? +page_title: What is a service mesh? description: >- - Learn what a service mesh is, it's benefits, and how it works. + Learn what a service mesh is, it's benefits, and how it works. + A service mesh can solve many of the modern challenges that exist in multi-platform and multi-cloud application architectures, ranging from security to application resiliency. --- # What is a Service Mesh? @@ -13,7 +14,7 @@ Service meshes are often used with a microservice architectural pattern, but can ## Benefits of a Service Mesh A service mesh provides benefits for all organizations, ranging from security to improved application resiliency. -Some of the benefits of a _service mesh_ include; +Some of the benefits of a service mesh include; - service discovery - application health monitoring @@ -25,18 +26,18 @@ Some of the benefits of a _service mesh_ include; - authentication and authorization, - network automation -A common use case for leveraging a _service mesh_ is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). +A common use case for leveraging a service mesh is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). In a _zero trust_ model, applications require identity-based access to ensure all communication within the service mesh is authenticated with TLS certificates and encrypted in transit. ## How does a Service Mesh work? -A _service mesh_ typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called _service discovery_. +A service mesh typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called [service discovery](https://www.hashicorp.com/products/consul/service-discovery-and-health-checking). As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. The data plane handles communication between services. -Many _service mesh_ solutions employ a sidecar proxy to handle data plane communications, and thus limit the level of awareness the services need to have about the network environment. +Many service mesh solutions employ a sidecar proxy to handle data plane communications, and thus limit the level of awareness the services need to have about the network environment. ![Overview of a service mesh](/img/what_is_service_mesh_1.png) @@ -46,24 +47,24 @@ An API gateway is a centralized access point for handling incoming client reques The API Gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. The API Gateway will route the incoming requests to the respective service. API Gateways primary function is to handle requests and return the reply from the service back to the client. -A _service mesh_ specializes in the network management of services and the communication between services. +A service mesh specializes in the network management of services and the communication between services. The mesh is responsible for keeping track of services and their health status, IP address, traffic routing, and ensuring all the traffic between services are authenticated and encrypted. -Unlike API Gateways, a _service mesh_ will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. +Unlike API Gateways, a service mesh will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. API Gateways are frequently deployed alongside a load balancer to ensure traffic is directed to healthy and available instances of the service. The mesh reduces the load balancer footprint as routing responsibilities are handled in a decentralized manner. -API Gateways can be used together with a _service mesh_ to bridge external networks (non-mesh) with a _service mesh_. +API Gateways can be used together with a service mesh to bridge external networks (non-mesh) with a service mesh. -> **Note**: API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a data center or a virtual private network (VPC). -A _service mesh_ is primarily used for handling east-west based traffic. East-west traffic traditionally remains inside a data center or a VPC. -A _service mesh_ can be connected to another _service mesh_ in another data center or VPC to form a federated mesh. +A service mesh is primarily used for handling east-west based traffic. East-west traffic traditionally remains inside a data center or a VPC. +A service mesh can be connected to another service mesh in another data center or VPC to form a federated mesh. ## What Problems Does a Service Mesh Solve? Modern infrastructure is transitioning from primarily being static-based to dynamic in nature (ephemeral). This dynamic infrastructure has a short life cycle, meaning virtual machines (VM) and containers are frequently recycled. -It's difficult for an organization to manage and keep track of application services that live on short-lived resources. A _service mesh_ solves this problem by acting as a central registry of all registered services. -As service instances, either VMs or containers, come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a _service mesh_ solves. +It's difficult for an organization to manage and keep track of application services that live on short-lived resources. A service mesh solves this problem by acting as a central registry of all registered services. +As service instances, either VMs or containers, come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a service mesh solves. As a service mesh is aware of the state of a service and its instances, the mesh can implement more intelligent and dynamic network routing. Many service meshes offer L7 traffic management capabilities. As a result, operators and developers can create powerful rules to direct network traffic as needed, such as load balancing, traffic splitting, dynamic failover, and custom resolvers. @@ -71,13 +72,13 @@ A service mesh's dynamic network behavior allows application owners to improve a Implementing dynamic network behavior is critical as more and more applications are deployed across different cloud providers (multi-cloud) and private data centers. Organizations may need to route network traffic to other infrastructure environments. Ensuring this traffic is secure is on top of mind for all organizations. -Service meshes offer the ability to enforce network traffic encryption (mTLS) and authentication between all services. The _service mesh_ can automatically generate an SSL certificate for each service and its instances. +Service meshes offer the ability to enforce network traffic encryption (mTLS) and authentication between all services. The service mesh can automatically generate an SSL certificate for each service and its instances. The certificate authenticates with other services inside the mesh and encrypts the TCP/UDP/gRPC connection with SSL. -Fine-grained policies that dictate what services are allowed to communicate with each other is another benefit of a _service mesh_. +Fine-grained policies that dictate what services are allowed to communicate with each other is another benefit of a service mesh. Traditionally, services are permitted to communicate with other services through firewall rules. The traditional firewall (IP-based) model is difficult to enforce with dynamic infrastructure resources with a short lifecycle and frequently recycling IP addresses. -As a result, network administrators have to open up network ranges to permit network traffic between services without differentiating the services generating the network traffic. However, a _service mesh_ allows operators and developers to shift away from an IP-based model and focus more on service to service permissions. +As a result, network administrators have to open up network ranges to permit network traffic between services without differentiating the services generating the network traffic. However, a service mesh allows operators and developers to shift away from an IP-based model and focus more on service to service permissions. An operator defines a policy that only allows _service A_ to communicate with _service B_. Otherwise, the default action is to deny the traffic. This shift from an IP address-based security model to a service-focused model reduces the overhead of securing network traffic and allows an organization to take advantage of multi-cloud environments without sacrificing security due to complexity. @@ -101,9 +102,9 @@ You can use Consul with virtual machines (VMs), containers, or with container or Consul is platform agnostic which makes it a great fit for all environments, including legacy platforms. Consul is available as a [self-install](/downloads) project or as a fully managed service mesh solution called [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). -HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a _service mesh_ on their own. +HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. ## Next -Get started today with a _service mesh_ by leveraging [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). +Get started today with a service mesh by leveraging [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). Prepare your organization for the future of multi-cloud and embrace a [zero-trust](https://www.hashicorp.com/solutions/zero-trust-security) architecture. From ff80779d4bba400ea63226360980b16d9677f9d3 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Mon, 24 Jan 2022 11:33:08 -0700 Subject: [PATCH 29/78] added learn tutorial link --- website/content/docs/intro/usecases/what-is-a-service-mesh.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index a2eb0f89d8..d85b24b9a7 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -104,6 +104,8 @@ Consul is platform agnostic which makes it a great fit for all environments, inc Consul is available as a [self-install](/downloads) project or as a fully managed service mesh solution called [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. +You can learn more about Consul by visting the Consul Learn [tutorials](https://learn.hashicorp.com/consul). + ## Next Get started today with a service mesh by leveraging [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). From 7a6e03c19b60fa337cd2760949b58b0768fdacf4 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 26 Jan 2022 17:21:45 -0500 Subject: [PATCH 30/78] acl: Remove a call to aclAccessorID I missed this on the first pass, we no longer need to look up this ID, because we have it from the Authorizer. --- agent/acl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/acl.go b/agent/acl.go index 7b92210ed8..0c0334a2f0 100644 --- a/agent/acl.go +++ b/agent/acl.go @@ -171,7 +171,7 @@ func (a *Agent) filterMembers(token string, members *[]serf.Member) error { if authz.NodeRead(node, &authzContext) == acl.Allow { continue } - accessorID := a.aclAccessorID(token) + accessorID := authz.AccessorID() a.logger.Debug("dropping node from result due to ACLs", "node", node, "accessorID", accessorID) m = append(m[:i], m[i+1:]...) i-- From c5d2bea92c244c65f62181cda1c1bf0eca9bca10 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous <56979977+Mathew-Estafanous@users.noreply.github.com> Date: Mon, 31 Jan 2022 11:17:35 -0500 Subject: [PATCH 31/78] Change error-handling across handlers. (#12225) --- agent/catalog_endpoint.go | 24 ++++--------- agent/config_endpoint.go | 8 ++--- agent/coordinate_endpoint.go | 33 ++++++++---------- agent/coordinate_endpoint_test.go | 10 +++--- agent/discovery_chain_endpoint.go | 4 +-- agent/event_endpoint.go | 9 ++--- agent/event_endpoint_test.go | 14 ++++---- agent/health_endpoint.go | 21 +++--------- agent/health_endpoint_test.go | 29 ++++++---------- agent/http.go | 21 ++++++++++-- agent/intentions_endpoint.go | 8 ++--- agent/kvs_endpoint.go | 33 ++++++------------ agent/prepared_query_endpoint.go | 20 +++-------- agent/prepared_query_endpoint_test.go | 24 +++++-------- agent/session_endpoint.go | 24 ++++--------- agent/txn_endpoint.go | 49 +++++++++++---------------- agent/txn_endpoint_test.go | 43 ++++++++++------------- agent/ui_endpoint.go | 24 ++++--------- agent/ui_endpoint_test.go | 5 +-- 19 files changed, 149 insertions(+), 254 deletions(-) diff --git a/agent/catalog_endpoint.go b/agent/catalog_endpoint.go index 8443e31f3e..2ae1b07dc0 100644 --- a/agent/catalog_endpoint.go +++ b/agent/catalog_endpoint.go @@ -136,9 +136,7 @@ func (s *HTTPHandlers) CatalogRegister(resp http.ResponseWriter, req *http.Reque } if err := s.rewordUnknownEnterpriseFieldError(decodeBody(req.Body, &args)); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } // Setup the default DC if not provided @@ -168,9 +166,7 @@ func (s *HTTPHandlers) CatalogDeregister(resp http.ResponseWriter, req *http.Req return nil, err } if err := s.rewordUnknownEnterpriseFieldError(decodeBody(req.Body, &args)); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } // Setup the default DC if not provided @@ -367,9 +363,7 @@ func (s *HTTPHandlers) catalogServiceNodes(resp http.ResponseWriter, req *http.R return nil, err } if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing service name") - return nil, nil + return nil, BadRequestError{Reason: "Missing service name"} } // Make the RPC request @@ -444,9 +438,7 @@ func (s *HTTPHandlers) CatalogNodeServices(resp http.ResponseWriter, req *http.R return nil, err } if args.Node == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing node name") - return nil, nil + return nil, BadRequestError{Reason: "Missing node name"} } // Make the RPC request @@ -511,9 +503,7 @@ func (s *HTTPHandlers) CatalogNodeServiceList(resp http.ResponseWriter, req *htt return nil, err } if args.Node == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing node name") - return nil, nil + return nil, BadRequestError{Reason: "Missing node name"} } // Make the RPC request @@ -564,9 +554,7 @@ func (s *HTTPHandlers) CatalogGatewayServices(resp http.ResponseWriter, req *htt return nil, err } if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing gateway name") - return nil, nil + return nil, BadRequestError{Reason: "Missing gateway name"} } // Make the RPC request diff --git a/agent/config_endpoint.go b/agent/config_endpoint.go index 9f916624ef..4bd96d4363 100644 --- a/agent/config_endpoint.go +++ b/agent/config_endpoint.go @@ -90,16 +90,12 @@ func (s *HTTPHandlers) configDelete(resp http.ResponseWriter, req *http.Request) pathArgs := strings.SplitN(kindAndName, "/", 2) if len(pathArgs) != 2 { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprintf(resp, "Must provide both a kind and name to delete") - return nil, nil + return nil, NotFoundError{Reason: "Must provide both a kind and name to delete"} } entry, err := structs.MakeConfigEntry(pathArgs[0], pathArgs[1]) if err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "%v", err) - return nil, nil + return nil, BadRequestError{Reason: err.Error()} } args.Entry = entry // Parse enterprise meta. diff --git a/agent/coordinate_endpoint.go b/agent/coordinate_endpoint.go index 822ef5b39b..ff3df3d06c 100644 --- a/agent/coordinate_endpoint.go +++ b/agent/coordinate_endpoint.go @@ -8,16 +8,13 @@ import ( "github.com/hashicorp/consul/agent/structs" ) -// checkCoordinateDisabled will return a standard response if coordinates are -// disabled. This returns true if they are disabled and we should not continue. -func (s *HTTPHandlers) checkCoordinateDisabled(resp http.ResponseWriter, req *http.Request) bool { +// checkCoordinateDisabled will return an unauthorized error if coordinates are +// disabled. Otherwise, a nil error will be returned. +func (s *HTTPHandlers) checkCoordinateDisabled() error { if !s.agent.config.DisableCoordinates { - return false + return nil } - - resp.WriteHeader(http.StatusUnauthorized) - fmt.Fprint(resp, "Coordinate support disabled") - return true + return UnauthorizedError{Reason: "Coordinate support disabled"} } // sorter wraps a coordinate list and implements the sort.Interface to sort by @@ -44,8 +41,8 @@ func (s *sorter) Less(i, j int) bool { // CoordinateDatacenters returns the WAN nodes in each datacenter, along with // raw network coordinates. func (s *HTTPHandlers) CoordinateDatacenters(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkCoordinateDisabled(resp, req) { - return nil, nil + if err := s.checkCoordinateDisabled(); err != nil { + return nil, err } var out []structs.DatacenterMap @@ -73,8 +70,8 @@ func (s *HTTPHandlers) CoordinateDatacenters(resp http.ResponseWriter, req *http // CoordinateNodes returns the LAN nodes in the given datacenter, along with // raw network coordinates. func (s *HTTPHandlers) CoordinateNodes(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkCoordinateDisabled(resp, req) { - return nil, nil + if err := s.checkCoordinateDisabled(); err != nil { + return nil, err } args := structs.DCSpecificRequest{} @@ -98,8 +95,8 @@ func (s *HTTPHandlers) CoordinateNodes(resp http.ResponseWriter, req *http.Reque // CoordinateNode returns the LAN node in the given datacenter, along with // raw network coordinates. func (s *HTTPHandlers) CoordinateNode(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkCoordinateDisabled(resp, req) { - return nil, nil + if err := s.checkCoordinateDisabled(); err != nil { + return nil, err } node, err := getPathSuffixUnescaped(req.URL.Path, "/v1/coordinate/node/") @@ -153,15 +150,13 @@ func filterCoordinates(req *http.Request, in structs.Coordinates) structs.Coordi // CoordinateUpdate inserts or updates the LAN coordinate of a node. func (s *HTTPHandlers) CoordinateUpdate(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkCoordinateDisabled(resp, req) { - return nil, nil + if err := s.checkCoordinateDisabled(); err != nil { + return nil, err } args := structs.CoordinateUpdateRequest{} if err := decodeBody(req.Body, &args); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } s.parseDC(req, &args.Datacenter) s.parseToken(req, &args.Token) diff --git a/agent/coordinate_endpoint_test.go b/agent/coordinate_endpoint_test.go index 36b956a8f8..ff38d83227 100644 --- a/agent/coordinate_endpoint_test.go +++ b/agent/coordinate_endpoint_test.go @@ -39,16 +39,14 @@ func TestCoordinate_Disabled_Response(t *testing.T) { req, _ := http.NewRequest("PUT", "/should/not/care", nil) resp := httptest.NewRecorder() obj, err := tt(resp, req) - if err != nil { - t.Fatalf("err: %v", err) + err, ok := err.(UnauthorizedError) + if !ok { + t.Fatalf("expected unauthorized error but got %v", err) } if obj != nil { t.Fatalf("bad: %#v", obj) } - if got, want := resp.Code, http.StatusUnauthorized; got != want { - t.Fatalf("got %d want %d", got, want) - } - if !strings.Contains(resp.Body.String(), "Coordinate support disabled") { + if !strings.Contains(err.Error(), "Coordinate support disabled") { t.Fatalf("bad: %#v", resp) } }) diff --git a/agent/discovery_chain_endpoint.go b/agent/discovery_chain_endpoint.go index ec3d46e9e6..666841ef32 100644 --- a/agent/discovery_chain_endpoint.go +++ b/agent/discovery_chain_endpoint.go @@ -51,9 +51,7 @@ func (s *HTTPHandlers) DiscoveryChainRead(resp http.ResponseWriter, req *http.Re if apiReq.OverrideMeshGateway.Mode != "" { _, err := structs.ValidateMeshGatewayMode(string(apiReq.OverrideMeshGateway.Mode)) if err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Invalid OverrideMeshGateway.Mode parameter") - return nil, nil + return nil, BadRequestError{Reason: "Invalid OverrideMeshGateway.Mode parameter"} } args.OverrideMeshGateway = apiReq.OverrideMeshGateway } diff --git a/agent/event_endpoint.go b/agent/event_endpoint.go index 10421d6202..53b0e5d65b 100644 --- a/agent/event_endpoint.go +++ b/agent/event_endpoint.go @@ -2,7 +2,6 @@ package agent import ( "bytes" - "fmt" "io" "net/http" "strconv" @@ -26,9 +25,7 @@ func (s *HTTPHandlers) EventFire(resp http.ResponseWriter, req *http.Request) (i return nil, err } if event.Name == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing name") - return nil, nil + return nil, BadRequestError{Reason: "Missing name"} } // Get the ACL token @@ -58,9 +55,7 @@ func (s *HTTPHandlers) EventFire(resp http.ResponseWriter, req *http.Request) (i // Try to fire the event if err := s.agent.UserEvent(dc, token, event); err != nil { if acl.IsErrPermissionDenied(err) { - resp.WriteHeader(http.StatusForbidden) - fmt.Fprint(resp, acl.ErrPermissionDenied.Error()) - return nil, nil + return nil, ForbiddenError{Reason: acl.ErrPermissionDenied.Error()} } resp.WriteHeader(http.StatusInternalServerError) return nil, err diff --git a/agent/event_endpoint_test.go b/agent/event_endpoint_test.go index d430c15ddb..e5f0b39f73 100644 --- a/agent/event_endpoint_test.go +++ b/agent/event_endpoint_test.go @@ -88,13 +88,11 @@ func TestEventFire_token(t *testing.T) { url := fmt.Sprintf("/v1/event/fire/%s?token=%s", c.event, token) req, _ := http.NewRequest("PUT", url, nil) resp := httptest.NewRecorder() - if _, err := a.srv.EventFire(resp, req); err != nil { - t.Fatalf("err: %s", err) - } + _, err := a.srv.EventFire(resp, req) // Check the result - body := resp.Body.String() if c.allowed { + body := resp.Body.String() if acl.IsErrPermissionDenied(errors.New(body)) { t.Fatalf("bad: %s", body) } @@ -102,11 +100,11 @@ func TestEventFire_token(t *testing.T) { t.Fatalf("bad: %d", resp.Code) } } else { - if !acl.IsErrPermissionDenied(errors.New(body)) { - t.Fatalf("bad: %s", body) + if !acl.IsErrPermissionDenied(err) { + t.Fatalf("bad: %s", err.Error()) } - if resp.Code != 403 { - t.Fatalf("bad: %d", resp.Code) + if err, ok := err.(ForbiddenError); !ok { + t.Fatalf("Expected forbidden but got %v", err) } } } diff --git a/agent/health_endpoint.go b/agent/health_endpoint.go index f6e803a3cb..faa37b6157 100644 --- a/agent/health_endpoint.go +++ b/agent/health_endpoint.go @@ -1,7 +1,6 @@ package agent import ( - "fmt" "net/http" "net/url" "strconv" @@ -36,9 +35,7 @@ func (s *HTTPHandlers) HealthChecksInState(resp http.ResponseWriter, req *http.R return nil, err } if args.State == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing check state") - return nil, nil + return nil, BadRequestError{Reason: "Missing check state"} } // Make the RPC request @@ -82,9 +79,7 @@ func (s *HTTPHandlers) HealthNodeChecks(resp http.ResponseWriter, req *http.Requ // Pull out the service name args.Node = strings.TrimPrefix(req.URL.Path, "/v1/health/node/") if args.Node == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing node name") - return nil, nil + return nil, BadRequestError{Reason: "Missing node name"} } // Make the RPC request @@ -130,9 +125,7 @@ func (s *HTTPHandlers) HealthServiceChecks(resp http.ResponseWriter, req *http.R // Pull out the service name args.ServiceName = strings.TrimPrefix(req.URL.Path, "/v1/health/checks/") if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing service name") - return nil, nil + return nil, BadRequestError{Reason: "Missing service name"} } // Make the RPC request @@ -218,9 +211,7 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re // Pull out the service name args.ServiceName = strings.TrimPrefix(req.URL.Path, prefix) if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing service name") - return nil, nil + return nil, BadRequestError{Reason: "Missing service name"} } out, md, err := s.agent.rpcClientHealth.ServiceNodes(req.Context(), args) @@ -238,9 +229,7 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re // Filter to only passing if specified filter, err := getBoolQueryParam(params, api.HealthPassing) if err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Invalid value for ?passing") - return nil, nil + return nil, BadRequestError{Reason: "Invalid value for ?passing"} } // FIXME: remove filterNonPassing, replace with nodes.Filter, which is used by DNSServer diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 5bd5444edf..baa4c43423 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -1,14 +1,13 @@ package agent import ( - "bytes" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "net/url" "reflect" "strconv" + "strings" "testing" "time" @@ -1241,18 +1240,12 @@ func TestHealthServiceNodes_PassingFilter(t *testing.T) { t.Run("passing_bad", func(t *testing.T) { req, _ := http.NewRequest("GET", "/v1/health/service/consul?passing=nope-nope-nope", nil) resp := httptest.NewRecorder() - a.srv.HealthServiceNodes(resp, req) - - if code := resp.Code; code != 400 { - t.Errorf("bad response code %d, expected %d", code, 400) + _, err := a.srv.HealthServiceNodes(resp, req) + if _, ok := err.(BadRequestError); !ok { + t.Fatalf("Expected bad request error but got %v", err) } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } - if !bytes.Contains(body, []byte("Invalid value for ?passing")) { - t.Errorf("bad %s", body) + if !strings.Contains(err.Error(), "Invalid value for ?passing") { + t.Errorf("bad %s", err.Error()) } }) } @@ -1654,12 +1647,12 @@ func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?passing=nope-nope", args.Service.Proxy.DestinationServiceName), nil) resp := httptest.NewRecorder() - a.srv.HealthConnectServiceNodes(resp, req) - assert.Equal(t, 400, resp.Code) + _, err := a.srv.HealthConnectServiceNodes(resp, req) + assert.NotNil(t, err) + _, ok := err.(BadRequestError) + assert.True(t, ok) - body, err := ioutil.ReadAll(resp.Body) - assert.Nil(t, err) - assert.True(t, bytes.Contains(body, []byte("Invalid value for ?passing"))) + assert.True(t, strings.Contains(err.Error(), "Invalid value for ?passing")) }) } diff --git a/agent/http.go b/agent/http.go index 5fc84ea113..b470547ed1 100644 --- a/agent/http.go +++ b/agent/http.go @@ -78,6 +78,14 @@ func (e UnauthorizedError) Error() string { return e.Reason } +type EntityTooLargeError struct { + Reason string +} + +func (e EntityTooLargeError) Error() string { + return e.Reason +} + // CodeWithPayloadError allow returning non HTTP 200 // Error codes while not returning PlainText payload type CodeWithPayloadError struct { @@ -91,10 +99,11 @@ func (e CodeWithPayloadError) Error() string { } type ForbiddenError struct { + Reason string } func (e ForbiddenError) Error() string { - return "Access is restricted" + return e.Reason } // HTTPHandlers provides an HTTP api for an agent. @@ -443,6 +452,11 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc return err.Error() == consul.ErrRateLimited.Error() } + isEntityToLarge := func(err error) bool { + _, ok := err.(EntityTooLargeError) + return ok + } + addAllowHeader := func(methods []string) { resp.Header().Add("Allow", strings.Join(methods, ",")) } @@ -488,6 +502,9 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc case isTooManyRequests(err): resp.WriteHeader(http.StatusTooManyRequests) fmt.Fprint(resp, err.Error()) + case isEntityToLarge(err): + resp.WriteHeader(http.StatusRequestEntityTooLarge) + fmt.Fprint(resp, err.Error()) default: resp.WriteHeader(http.StatusInternalServerError) fmt.Fprint(resp, err.Error()) @@ -1136,7 +1153,7 @@ func (s *HTTPHandlers) checkWriteAccess(req *http.Request) error { } } - return ForbiddenError{} + return ForbiddenError{Reason: "Access is restricted"} } func (s *HTTPHandlers) parseFilter(req *http.Request, filter *string) { diff --git a/agent/intentions_endpoint.go b/agent/intentions_endpoint.go index 2bb55b7f4b..4c326b4f1e 100644 --- a/agent/intentions_endpoint.go +++ b/agent/intentions_endpoint.go @@ -323,9 +323,7 @@ func (s *HTTPHandlers) IntentionGetExact(resp http.ResponseWriter, req *http.Req if err := s.agent.RPC("Intention.Get", &args, &reply); err != nil { // We have to check the string since the RPC sheds the error type if err.Error() == consul.ErrIntentionNotFound.Error() { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprint(resp, err.Error()) - return nil, nil + return nil, NotFoundError{Reason: err.Error()} } // Not ideal, but there are a number of error scenarios that are not @@ -521,9 +519,7 @@ func (s *HTTPHandlers) IntentionSpecificGet(id string, resp http.ResponseWriter, if err := s.agent.RPC("Intention.Get", &args, &reply); err != nil { // We have to check the string since the RPC sheds the error type if err.Error() == consul.ErrIntentionNotFound.Error() { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprint(resp, err.Error()) - return nil, nil + return nil, NotFoundError{Reason: err.Error()} } // Not ideal, but there are a number of error scenarios that are not diff --git a/agent/kvs_endpoint.go b/agent/kvs_endpoint.go index b6bed301be..4b8cc3348f 100644 --- a/agent/kvs_endpoint.go +++ b/agent/kvs_endpoint.go @@ -55,8 +55,8 @@ func (s *HTTPHandlers) KVSGet(resp http.ResponseWriter, req *http.Request, args params := req.URL.Query() if _, ok := params["recurse"]; ok { method = "KVS.List" - } else if missingKey(resp, args) { - return nil, nil + } else if args.Key == "" { + return nil, BadRequestError{Reason: "Missing key name"} } // Do not allow wildcard NS on GET reqs @@ -156,8 +156,8 @@ func (s *HTTPHandlers) KVSPut(resp http.ResponseWriter, req *http.Request, args if err := s.parseEntMetaNoWildcard(req, &args.EnterpriseMeta); err != nil { return nil, err } - if missingKey(resp, args) { - return nil, nil + if args.Key == "" { + return nil, BadRequestError{Reason: "Missing key name"} } if conflictingFlags(resp, req, "cas", "acquire", "release") { return nil, nil @@ -208,13 +208,10 @@ func (s *HTTPHandlers) KVSPut(resp http.ResponseWriter, req *http.Request, args // Check the content-length if req.ContentLength > int64(s.agent.config.KVMaxValueSize) { - resp.WriteHeader(http.StatusRequestEntityTooLarge) - fmt.Fprintf(resp, - "Request body(%d bytes) too large, max size: %d bytes. See %s.", - req.ContentLength, s.agent.config.KVMaxValueSize, - "https://www.consul.io/docs/agent/options.html#kv_max_value_size", - ) - return nil, nil + return nil, EntityTooLargeError{ + Reason: fmt.Sprintf("Request body(%d bytes) too large, max size: %d bytes. See %s.", + req.ContentLength, s.agent.config.KVMaxValueSize, "https://www.consul.io/docs/agent/options.html#kv_max_value_size"), + } } // Copy the value @@ -259,8 +256,8 @@ func (s *HTTPHandlers) KVSDelete(resp http.ResponseWriter, req *http.Request, ar params := req.URL.Query() if _, ok := params["recurse"]; ok { applyReq.Op = api.KVDeleteTree - } else if missingKey(resp, args) { - return nil, nil + } else if args.Key == "" { + return nil, BadRequestError{Reason: "Missing key name"} } // Check for cas value @@ -286,16 +283,6 @@ func (s *HTTPHandlers) KVSDelete(resp http.ResponseWriter, req *http.Request, ar return true, nil } -// missingKey checks if the key is missing -func missingKey(resp http.ResponseWriter, args *structs.KeyRequest) bool { - if args.Key == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing key name") - return true - } - return false -} - // conflictingFlags determines if non-composable flags were passed in a request. func conflictingFlags(resp http.ResponseWriter, req *http.Request, flags ...string) bool { params := req.URL.Query() diff --git a/agent/prepared_query_endpoint.go b/agent/prepared_query_endpoint.go index 31e900288e..b398e24465 100644 --- a/agent/prepared_query_endpoint.go +++ b/agent/prepared_query_endpoint.go @@ -23,9 +23,7 @@ func (s *HTTPHandlers) preparedQueryCreate(resp http.ResponseWriter, req *http.R s.parseDC(req, &args.Datacenter) s.parseToken(req, &args.Token) if err := decodeBody(req.Body, &args.Query); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } var reply string @@ -145,9 +143,7 @@ func (s *HTTPHandlers) preparedQueryExecute(id string, resp http.ResponseWriter, // We have to check the string since the RPC sheds // the specific error type. if structs.IsErrQueryNotFound(err) { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprint(resp, err.Error()) - return nil, nil + return nil, NotFoundError{Reason: err.Error()} } return nil, err } @@ -200,9 +196,7 @@ RETRY_ONCE: // We have to check the string since the RPC sheds // the specific error type. if structs.IsErrQueryNotFound(err) { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprint(resp, err.Error()) - return nil, nil + return nil, NotFoundError{Reason: err.Error()} } return nil, err } @@ -231,9 +225,7 @@ RETRY_ONCE: // We have to check the string since the RPC sheds // the specific error type. if structs.IsErrQueryNotFound(err) { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprint(resp, err.Error()) - return nil, nil + return nil, NotFoundError{Reason: err.Error()} } return nil, err } @@ -255,9 +247,7 @@ func (s *HTTPHandlers) preparedQueryUpdate(id string, resp http.ResponseWriter, s.parseToken(req, &args.Token) if req.ContentLength > 0 { if err := decodeBody(req.Body, &args.Query); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } } diff --git a/agent/prepared_query_endpoint_test.go b/agent/prepared_query_endpoint_test.go index 79658f8c11..e4d3056e83 100644 --- a/agent/prepared_query_endpoint_test.go +++ b/agent/prepared_query_endpoint_test.go @@ -620,11 +620,9 @@ func TestPreparedQuery_Execute(t *testing.T) { body := bytes.NewBuffer(nil) req, _ := http.NewRequest("GET", "/v1/query/not-there/execute", body) resp := httptest.NewRecorder() - if _, err := a.srv.PreparedQuerySpecific(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 404 { - t.Fatalf("bad code: %d", resp.Code) + _, err := a.srv.PreparedQuerySpecific(resp, req) + if err, ok := err.(NotFoundError); !ok { + t.Fatalf("Expected not found error but got %v", err) } }) } @@ -757,11 +755,9 @@ func TestPreparedQuery_Explain(t *testing.T) { body := bytes.NewBuffer(nil) req, _ := http.NewRequest("GET", "/v1/query/not-there/explain", body) resp := httptest.NewRecorder() - if _, err := a.srv.PreparedQuerySpecific(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 404 { - t.Fatalf("bad code: %d", resp.Code) + _, err := a.srv.PreparedQuerySpecific(resp, req) + if err, ok := err.(NotFoundError); !ok { + t.Fatalf("Expected not found error but got %v", err) } }) @@ -848,11 +844,9 @@ func TestPreparedQuery_Get(t *testing.T) { body := bytes.NewBuffer(nil) req, _ := http.NewRequest("GET", "/v1/query/f004177f-2c28-83b7-4229-eacc25fe55d1", body) resp := httptest.NewRecorder() - if _, err := a.srv.PreparedQuerySpecific(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 404 { - t.Fatalf("bad code: %d", resp.Code) + _, err := a.srv.PreparedQuerySpecific(resp, req) + if err, ok := err.(NotFoundError); !ok { + t.Fatalf("Expected not found error but got %v", err) } }) } diff --git a/agent/session_endpoint.go b/agent/session_endpoint.go index 9371bf7418..afe3faa3c4 100644 --- a/agent/session_endpoint.go +++ b/agent/session_endpoint.go @@ -40,9 +40,7 @@ func (s *HTTPHandlers) SessionCreate(resp http.ResponseWriter, req *http.Request // Handle optional request body if req.ContentLength > 0 { if err := s.rewordUnknownEnterpriseFieldError(lib.DecodeJSON(req.Body, &args.Session)); err != nil { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Request decode failed: %v", err) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)} } } @@ -77,9 +75,7 @@ func (s *HTTPHandlers) SessionDestroy(resp http.ResponseWriter, req *http.Reques return nil, err } if args.Session.ID == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing session") - return nil, nil + return nil, BadRequestError{Reason: "Missing session"} } var out string @@ -107,18 +103,14 @@ func (s *HTTPHandlers) SessionRenew(resp http.ResponseWriter, req *http.Request) } args.Session = args.SessionID if args.SessionID == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing session") - return nil, nil + return nil, BadRequestError{Reason: "Missing session"} } var out structs.IndexedSessions if err := s.agent.RPC("Session.Renew", &args, &out); err != nil { return nil, err } else if out.Sessions == nil { - resp.WriteHeader(http.StatusNotFound) - fmt.Fprintf(resp, "Session id '%s' not found", args.SessionID) - return nil, nil + return nil, NotFoundError{Reason: fmt.Sprintf("Session id '%s' not found", args.SessionID)} } return out.Sessions, nil @@ -142,9 +134,7 @@ func (s *HTTPHandlers) SessionGet(resp http.ResponseWriter, req *http.Request) ( } args.Session = args.SessionID if args.SessionID == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing session") - return nil, nil + return nil, BadRequestError{Reason: "Missing session"} } var out structs.IndexedSessions @@ -200,9 +190,7 @@ func (s *HTTPHandlers) SessionsForNode(resp http.ResponseWriter, req *http.Reque return nil, err } if args.Node == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing node name") - return nil, nil + return nil, BadRequestError{Reason: "Missing node name"} } var out structs.IndexedSessions diff --git a/agent/txn_endpoint.go b/agent/txn_endpoint.go index f954ace410..58a1cd4b0f 100644 --- a/agent/txn_endpoint.go +++ b/agent/txn_endpoint.go @@ -63,7 +63,7 @@ func isWrite(op api.KVOp) bool { // internal RPC format. This returns a count of the number of write ops, and // a boolean, that if false means an error response has been generated and // processing should stop. -func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (structs.TxnOps, int, bool) { +func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) (structs.TxnOps, int, error) { // The TxnMaxReqLen limit and KVMaxValueSize limit both default to the // suggested raft data size and can be configured independently. The // TxnMaxReqLen is enforced on the cumulative size of the transaction, @@ -87,13 +87,10 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) ( // Check Content-Length first before decoding to return early if req.ContentLength > maxTxnLen { - resp.WriteHeader(http.StatusRequestEntityTooLarge) - fmt.Fprintf(resp, - "Request body(%d bytes) too large, max size: %d bytes. See %s.", - req.ContentLength, maxTxnLen, - "https://www.consul.io/docs/agent/options.html#txn_max_req_len", - ) - return nil, 0, false + return nil, 0, EntityTooLargeError{ + Reason: fmt.Sprintf("Request body(%d bytes) too large, max size: %d bytes. See %s.", + req.ContentLength, maxTxnLen, "https://www.consul.io/docs/agent/options.html#txn_max_req_len"), + } } var ops api.TxnOps @@ -102,30 +99,24 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) ( if err.Error() == "http: request body too large" { // The request size is also verified during decoding to double check // if the Content-Length header was not set by the client. - resp.WriteHeader(http.StatusRequestEntityTooLarge) - fmt.Fprintf(resp, - "Request body too large, max size: %d bytes. See %s.", - maxTxnLen, - "https://www.consul.io/docs/agent/options.html#txn_max_req_len", - ) + return nil, 0, EntityTooLargeError{ + Reason: fmt.Sprintf("Request body too large, max size: %d bytes. See %s.", + maxTxnLen, "https://www.consul.io/docs/agent/options.html#txn_max_req_len"), + } } else { // Note the body is in API format, and not the RPC format. If we can't // decode it, we will return a 400 since we don't have enough context to // associate the error with a given operation. - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Failed to parse body: %v", err) + return nil, 0, BadRequestError{Reason: fmt.Sprintf("Failed to parse body: %v", err)} } - return nil, 0, false } // Enforce a reasonable upper limit on the number of operations in a // transaction in order to curb abuse. if size := len(ops); size > maxTxnOps { - resp.WriteHeader(http.StatusRequestEntityTooLarge) - fmt.Fprintf(resp, "Transaction contains too many operations (%d > %d)", - size, maxTxnOps) - - return nil, 0, false + return nil, 0, EntityTooLargeError{ + Reason: fmt.Sprintf("Transaction contains too many operations (%d > %d)", size, maxTxnOps), + } } // Convert the KV API format into the RPC format. Note that fixupKVOps @@ -138,9 +129,9 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) ( case in.KV != nil: size := len(in.KV.Value) if int64(size) > kvMaxValueSize { - resp.WriteHeader(http.StatusRequestEntityTooLarge) - fmt.Fprintf(resp, "Value for key %q is too large (%d > %d bytes)", in.KV.Key, size, s.agent.config.KVMaxValueSize) - return nil, 0, false + return nil, 0, EntityTooLargeError{ + Reason: fmt.Sprintf("Value for key %q is too large (%d > %d bytes)", in.KV.Key, size, s.agent.config.KVMaxValueSize), + } } verb := in.KV.Verb @@ -297,7 +288,7 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) ( } } - return opsRPC, writes, true + return opsRPC, writes, nil } // Txn handles requests to apply multiple operations in a single, atomic @@ -306,9 +297,9 @@ func (s *HTTPHandlers) convertOps(resp http.ResponseWriter, req *http.Request) ( // and everything else will be routed through Raft like a normal write. func (s *HTTPHandlers) Txn(resp http.ResponseWriter, req *http.Request) (interface{}, error) { // Convert the ops from the API format to the internal format. - ops, writes, ok := s.convertOps(resp, req) - if !ok { - return nil, nil + ops, writes, err := s.convertOps(resp, req) + if err != nil { + return nil, err } // Fast-path a transaction with only writes to the read-only endpoint, diff --git a/agent/txn_endpoint_test.go b/agent/txn_endpoint_test.go index 6b3a7c4680..2f9d6fbca1 100644 --- a/agent/txn_endpoint_test.go +++ b/agent/txn_endpoint_test.go @@ -30,13 +30,12 @@ func TestTxnEndpoint_Bad_JSON(t *testing.T) { buf := bytes.NewBuffer([]byte("{")) req, _ := http.NewRequest("PUT", "/v1/txn", buf) resp := httptest.NewRecorder() - if _, err := a.srv.Txn(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 400 { - t.Fatalf("expected 400, got %d", resp.Code) + _, err := a.srv.Txn(resp, req) + err, ok := err.(BadRequestError) + if !ok { + t.Fatalf("expected bad request error but got %v", err) } - if !bytes.Contains(resp.Body.Bytes(), []byte("Failed to parse")) { + if !strings.Contains(err.Error(), "Failed to parse") { t.Fatalf("expected conflicting args error") } } @@ -63,14 +62,12 @@ func TestTxnEndpoint_Bad_Size_Item(t *testing.T) { `, value))) req, _ := http.NewRequest("PUT", "/v1/txn", buf) resp := httptest.NewRecorder() - if _, err := agent.srv.Txn(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 413 && !wantPass { - t.Fatalf("expected 413, got %d", resp.Code) + _, err := agent.srv.Txn(resp, req) + if err, ok := err.(EntityTooLargeError); !ok && !wantPass { + t.Fatalf("expected too large error but got %v", err) } - if resp.Code != 200 && wantPass { - t.Fatalf("expected 200, got %d", resp.Code) + if err != nil && wantPass { + t.Fatalf("err: %v", err) } } @@ -140,14 +137,12 @@ func TestTxnEndpoint_Bad_Size_Net(t *testing.T) { `, value, value, value))) req, _ := http.NewRequest("PUT", "/v1/txn", buf) resp := httptest.NewRecorder() - if _, err := agent.srv.Txn(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 413 && !wantPass { - t.Fatalf("expected 413, got %d", resp.Code) + _, err := agent.srv.Txn(resp, req) + if err, ok := err.(EntityTooLargeError); !ok && !wantPass { + t.Fatalf("expected too large error but got %v", err) } - if resp.Code != 200 && wantPass { - t.Fatalf("expected 200, got %d", resp.Code) + if err != nil && wantPass { + t.Fatalf("err: %v", err) } } @@ -209,11 +204,9 @@ func TestTxnEndpoint_Bad_Size_Ops(t *testing.T) { `, strings.Repeat(`{ "KV": { "Verb": "get", "Key": "key" } },`, 2*maxTxnOps)))) req, _ := http.NewRequest("PUT", "/v1/txn", buf) resp := httptest.NewRecorder() - if _, err := a.srv.Txn(resp, req); err != nil { - t.Fatalf("err: %v", err) - } - if resp.Code != 413 { - t.Fatalf("expected 413, got %d", resp.Code) + _, err := a.srv.Txn(resp, req) + if err, ok := err.(EntityTooLargeError); !ok { + t.Fatalf("expected too large error but got %v", err) } } diff --git a/agent/ui_endpoint.go b/agent/ui_endpoint.go index 4c6b3e7686..56de071c08 100644 --- a/agent/ui_endpoint.go +++ b/agent/ui_endpoint.go @@ -139,9 +139,7 @@ func (s *HTTPHandlers) UINodeInfo(resp http.ResponseWriter, req *http.Request) ( return nil, err } if args.Node == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing node name") - return nil, nil + return nil, BadRequestError{Reason: "Missing node name"} } // Make the RPC request @@ -255,9 +253,7 @@ func (s *HTTPHandlers) UIGatewayServicesNodes(resp http.ResponseWriter, req *htt return nil, err } if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing gateway name") - return nil, nil + return nil, BadRequestError{Reason: "Missing gateway name"} } // Make the RPC request @@ -301,16 +297,12 @@ func (s *HTTPHandlers) UIServiceTopology(resp http.ResponseWriter, req *http.Req return nil, err } if args.ServiceName == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing service name") - return nil, nil + return nil, BadRequestError{Reason: "Missing service name"} } kind, ok := req.URL.Query()["kind"] if !ok { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing service kind") - return nil, nil + return nil, BadRequestError{Reason: "Missing service kind"} } args.ServiceKind = structs.ServiceKind(kind[0]) @@ -318,9 +310,7 @@ func (s *HTTPHandlers) UIServiceTopology(resp http.ResponseWriter, req *http.Req case structs.ServiceKindTypical, structs.ServiceKindIngressGateway: // allowed default: - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(resp, "Unsupported service kind %q", args.ServiceKind) - return nil, nil + return nil, BadRequestError{Reason: fmt.Sprintf("Unsupported service kind %q", args.ServiceKind)} } // Make the RPC request @@ -584,9 +574,7 @@ func (s *HTTPHandlers) UIGatewayIntentions(resp http.ResponseWriter, req *http.R return nil, err } if name == "" { - resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Missing gateway name") - return nil, nil + return nil, BadRequestError{Reason: "Missing gateway name"} } args.Match = &structs.IntentionQueryMatch{ Type: structs.IntentionMatchDestination, diff --git a/agent/ui_endpoint_test.go b/agent/ui_endpoint_test.go index 84cd971a7a..757975bc5c 100644 --- a/agent/ui_endpoint_test.go +++ b/agent/ui_endpoint_test.go @@ -1409,14 +1409,15 @@ func TestUIServiceTopology(t *testing.T) { retry.Run(t, func(r *retry.R) { resp := httptest.NewRecorder() obj, err := a.srv.UIServiceTopology(resp, tc.httpReq) - assert.Nil(r, err) if tc.wantErr != "" { + assert.NotNil(r, err) assert.Nil(r, tc.want) // should not define a non-nil want - require.Equal(r, tc.wantErr, resp.Body.String()) + require.Contains(r, err.Error(), tc.wantErr) require.Nil(r, obj) return } + assert.Nil(r, err) require.NoError(r, checkIndex(resp)) require.NotNil(r, obj) From c84fe812c5e67c466f95f5ffb82783a48bc990cb Mon Sep 17 00:00:00 2001 From: David Yu Date: Mon, 31 Jan 2022 09:00:20 -0800 Subject: [PATCH 32/78] docs: Small changes to API Gateway docs (#12226) * docs: Small changes to API Gateway docs * Update api-gateway.mdx * Update website/content/docs/api-gateway.mdx Co-authored-by: mrspanishviking Co-authored-by: mrspanishviking --- website/content/docs/api-gateway.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/content/docs/api-gateway.mdx b/website/content/docs/api-gateway.mdx index 229ba0e9ec..7c1c096b92 100644 --- a/website/content/docs/api-gateway.mdx +++ b/website/content/docs/api-gateway.mdx @@ -21,10 +21,10 @@ Consul API Gateway implements the Kubernetes [Gateway API Specification](https:/ Your datacenter must meet the following requirements prior to configuring the Consul API Gateway: -- A Kubernetes cluster must be running +- Kubernetes 1.21+ - `kubectl` 1.21+ - Consul 1.11.2+ -- HashiCorp Helm chart 0.40.0+ +- HashiCorp Consul Helm chart 0.40.0+ ## Installation @@ -38,7 +38,7 @@ Your datacenter must meet the following requirements prior to configuring the Co -1. Create a values file for your Consul server agents that contains the following parameters: +1. Create a `values.yaml` file for your Consul API Gateway deployment. Copy the content below into the `values.yaml` file. The `values.yaml` will be used by the Consul Helm chart. See [Helm Chart Configuration - apigateway](https://www.consul.io/docs/k8s/helm#apigateway) for more available options on how to configure your Consul API Gateway deployment via the Helm chart. From 569f460b1859629a47645ae9c5efb863948a7b25 Mon Sep 17 00:00:00 2001 From: Peter M <36747421+pcmccarron@users.noreply.github.com> Date: Mon, 31 Jan 2022 11:44:17 -0700 Subject: [PATCH 33/78] updating press kit link pointing to the brand page instead of a zip file. --- website/components/footer/index.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/components/footer/index.jsx b/website/components/footer/index.jsx index 86d72cb193..f06bc0a974 100644 --- a/website/components/footer/index.jsx +++ b/website/components/footer/index.jsx @@ -21,9 +21,7 @@ export default function Footer({ openConsentManager }) { Security - - Press Kit - + Press Kit Consent Manager From 998a339eb198ff410523ccb62449b4951ae62081 Mon Sep 17 00:00:00 2001 From: Peter M <36747421+pcmccarron@users.noreply.github.com> Date: Mon, 31 Jan 2022 13:21:19 -0700 Subject: [PATCH 34/78] Update website/components/footer/index.jsx Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com> --- website/components/footer/index.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/components/footer/index.jsx b/website/components/footer/index.jsx index f06bc0a974..c8d9b2c6f0 100644 --- a/website/components/footer/index.jsx +++ b/website/components/footer/index.jsx @@ -21,7 +21,9 @@ export default function Footer({ openConsentManager }) { Security - Press Kit + + Press Kit + Consent Manager From b113bf86cf26cad0a48e20a2c9e5d8c486322ec7 Mon Sep 17 00:00:00 2001 From: Peter M <36747421+pcmccarron@users.noreply.github.com> Date: Mon, 31 Jan 2022 13:22:29 -0700 Subject: [PATCH 35/78] updating to brand --- website/components/footer/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/components/footer/index.jsx b/website/components/footer/index.jsx index c8d9b2c6f0..6df5112338 100644 --- a/website/components/footer/index.jsx +++ b/website/components/footer/index.jsx @@ -22,7 +22,7 @@ export default function Footer({ openConsentManager }) { Security - Press Kit + Brand Consent Manager From d363cc0f0728f3c41a04c69fac9c936cb4c02a60 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Mon, 31 Jan 2022 14:21:57 -0500 Subject: [PATCH 36/78] acl: remove unused methods on fakes, and add changelog Also document the metric that was removed in a previous commit. --- .changelog/12166.txt | 3 +++ agent/acl_test.go | 8 -------- agent/consul/acl.go | 4 ---- agent/delegate_mock_test.go | 5 ----- website/content/docs/agent/telemetry.mdx | 2 +- 5 files changed, 4 insertions(+), 18 deletions(-) create mode 100644 .changelog/12166.txt diff --git a/.changelog/12166.txt b/.changelog/12166.txt new file mode 100644 index 0000000000..06b4340003 --- /dev/null +++ b/.changelog/12166.txt @@ -0,0 +1,3 @@ +```release-note:deprecation +acl: The `consul.acl.ResolveTokenToIdentity` metric is no longer reported. The values that were previous reported as part of this metric will now be part of the `consul.acl.ResolveToken` metric. +``` diff --git a/agent/acl_test.go b/agent/acl_test.go index b205220f67..a26798bba8 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -94,14 +94,6 @@ func (a *TestACLAgent) ResolveTokenToIdentityAndAuthorizer(secretID string) (str return a.resolveAuthzFn(secretID) } -func (a *TestACLAgent) ResolveTokenToIdentity(secretID string) (structs.ACLIdentity, error) { - if a.resolveIdentFn == nil { - return nil, fmt.Errorf("ResolveTokenToIdentity call is unexpected - no ident resolver callback set") - } - - return a.resolveIdentFn(secretID) -} - func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) { identity, authz, err := a.ResolveTokenToIdentityAndAuthorizer(secretID) if err != nil { diff --git a/agent/consul/acl.go b/agent/consul/acl.go index da89e2dd3d..ab637b7209 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -34,10 +34,6 @@ var ACLSummaries = []prometheus.SummaryDefinition{ Name: []string{"acl", "ResolveToken"}, Help: "This measures the time it takes to resolve an ACL token.", }, - { - Name: []string{"acl", "ResolveTokenToIdentity"}, - Help: "This measures the time it takes to resolve an ACL token to an Identity.", - }, } // These must be kept in sync with the constants in command/agent/acl.go. diff --git a/agent/delegate_mock_test.go b/agent/delegate_mock_test.go index 678b0b87bc..d2c6e267ce 100644 --- a/agent/delegate_mock_test.go +++ b/agent/delegate_mock_test.go @@ -47,11 +47,6 @@ func (m *delegateMock) RemoveFailedNode(node string, prune bool, entMeta *struct return m.Called(node, prune, entMeta).Error(0) } -func (m *delegateMock) ResolveTokenToIdentity(token string) (structs.ACLIdentity, error) { - ret := m.Called(token) - return ret.Get(0).(structs.ACLIdentity), ret.Error(1) -} - func (m *delegateMock) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) { ret := m.Called(token, entMeta, authzContext) return ret.Get(0).(acl.Authorizer), ret.Error(1) diff --git a/website/content/docs/agent/telemetry.mdx b/website/content/docs/agent/telemetry.mdx index 0c8ea8d01d..749e2fa17c 100644 --- a/website/content/docs/agent/telemetry.mdx +++ b/website/content/docs/agent/telemetry.mdx @@ -334,7 +334,7 @@ These metrics are used to monitor the health of the Consul servers. | Metric | Description | Unit | Type | | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------- | | `consul.acl.ResolveToken` | Measures the time it takes to resolve an ACL token. | ms | timer | -| `consul.acl.ResolveTokenToIdentity` | Measures the time it takes to resolve an ACL token to an Identity. | ms | timer | +| `consul.acl.ResolveTokenToIdentity` | Measures the time it takes to resolve an ACL token to an Identity. This metric was removed in Consul 1.12. The time will now be reflected in `consul.acl.ResolveToken`. | ms | timer | | `consul.acl.token.cache_hit` | Increments if Consul is able to resolve a token's identity, or a legacy token, from the cache. | cache read op | counter | | `consul.acl.token.cache_miss` | Increments if Consul cannot resolve a token's identity, or a legacy token, from the cache. | cache read op | counter | | `consul.cache.bypass` | Counts how many times a request bypassed the cache because no cache-key was provided. | counter | counter | From 343b6deb7970a07011ed37469cd8fec49540c569 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Sun, 23 Jan 2022 12:31:48 -0500 Subject: [PATCH 37/78] acl: rename ResolveTokenToIdentityAndAuthorizer to ResolveToken This change allows us to remove one of the last remaining duplicate resolve token methods (Server.ResolveToken). With this change we are down to only 2, where the second one also handles setting the default EnterpriseMeta from the token. --- agent/acl_test.go | 13 ++-- agent/consul/acl.go | 34 ++++++----- agent/consul/acl_server.go | 6 -- agent/consul/acl_test.go | 67 ++++++++++----------- agent/consul/intention_endpoint.go | 14 +---- agent/consul/internal_endpoint.go | 4 +- agent/consul/operator_autopilot_endpoint.go | 16 ++--- agent/consul/operator_raft_endpoint.go | 8 +-- 8 files changed, 73 insertions(+), 89 deletions(-) diff --git a/agent/acl_test.go b/agent/acl_test.go index a26798bba8..5ad4880ed0 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -86,16 +86,13 @@ func (a *TestACLAgent) ResolveToken(secretID string) (acl.Authorizer, error) { return authz, err } -func (a *TestACLAgent) ResolveTokenToIdentityAndAuthorizer(secretID string) (structs.ACLIdentity, acl.Authorizer, error) { - if a.resolveAuthzFn == nil { - return nil, nil, fmt.Errorf("ResolveTokenToIdentityAndAuthorizer call is unexpected - no authz resolver callback set") +func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) { + authz, err := a.ResolveToken(secretID) + if err != nil { + return consul.ACLResolveResult{}, err } - return a.resolveAuthzFn(secretID) -} - -func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (consul.ACLResolveResult, error) { - identity, authz, err := a.ResolveTokenToIdentityAndAuthorizer(secretID) + identity, err := a.resolveIdentFn(secretID) if err != nil { return consul.ACLResolveResult{}, err } diff --git a/agent/consul/acl.go b/agent/consul/acl.go index ab637b7209..4dcd5e623f 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1051,13 +1051,16 @@ func (r *ACLResolver) resolveLocallyManagedToken(token string) (structs.ACLIdent return r.resolveLocallyManagedEnterpriseToken(token) } -func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs.ACLIdentity, acl.Authorizer, error) { +// ResolveToken to an acl.Authorizer and structs.ACLIdentity. The acl.Authorizer +// can be used to check permissions granted to the token, and the ACLIdentity +// describes the token and any defaults applied to it. +func (r *ACLResolver) ResolveToken(token string) (ACLResolveResult, error) { if !r.ACLsEnabled() { - return nil, acl.ManageAll(), nil + return ACLResolveResult{Authorizer: acl.ManageAll()}, nil } if acl.RootAuthorizer(token) != nil { - return nil, nil, acl.ErrRootDenied + return ACLResolveResult{}, acl.ErrRootDenied } // handle the anonymous token @@ -1066,7 +1069,7 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs } if ident, authz, ok := r.resolveLocallyManagedToken(token); ok { - return ident, authz, nil + return ACLResolveResult{Authorizer: authz, ACLIdentity: ident}, nil } defer metrics.MeasureSince([]string{"acl", "ResolveToken"}, time.Now()) @@ -1076,10 +1079,11 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs r.handleACLDisabledError(err) if IsACLRemoteError(err) { r.logger.Error("Error resolving token", "error", err) - return &missingIdentity{reason: "primary-dc-down", token: token}, r.down, nil + ident := &missingIdentity{reason: "primary-dc-down", token: token} + return ACLResolveResult{Authorizer: r.down, ACLIdentity: ident}, nil } - return nil, nil, err + return ACLResolveResult{}, err } // Build the Authorizer @@ -1092,7 +1096,7 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs authz, err := policies.Compile(r.cache, &conf) if err != nil { - return nil, nil, err + return ACLResolveResult{}, err } chain = append(chain, authz) @@ -1100,15 +1104,15 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs if err != nil { if IsACLRemoteError(err) { r.logger.Error("Error resolving identity defaults", "error", err) - return identity, r.down, nil + return ACLResolveResult{Authorizer: r.down, ACLIdentity: identity}, nil } - return nil, nil, err + return ACLResolveResult{}, err } else if authz != nil { chain = append(chain, authz) } chain = append(chain, acl.RootAuthorizer(r.config.ACLDefaultPolicy)) - return identity, acl.NewChainedAuthorizer(chain), nil + return ACLResolveResult{Authorizer: acl.NewChainedAuthorizer(chain), ACLIdentity: identity}, nil } type ACLResolveResult struct { @@ -1141,7 +1145,7 @@ func (r *ACLResolver) ACLsEnabled() bool { } func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (ACLResolveResult, error) { - identity, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) + result, err := r.ResolveToken(token) if err != nil { return ACLResolveResult{}, err } @@ -1152,8 +1156,8 @@ func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs. // Default the EnterpriseMeta based on the Tokens meta or actual defaults // in the case of unknown identity - if identity != nil { - entMeta.Merge(identity.EnterpriseMetadata()) + if result.ACLIdentity != nil { + entMeta.Merge(result.ACLIdentity.EnterpriseMetadata()) } else { entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) } @@ -1161,7 +1165,7 @@ func (r *ACLResolver) ResolveTokenAndDefaultMeta(token string, entMeta *structs. // Use the meta to fill in the ACL authorization context entMeta.FillAuthzContext(authzContext) - return ACLResolveResult{Authorizer: authz, ACLIdentity: identity}, err + return result, err } // aclFilter is used to filter results from our state store based on ACL rules @@ -1971,7 +1975,7 @@ func filterACLWithAuthorizer(logger hclog.Logger, authorizer acl.Authorizer, sub // not authorized for read access will be removed from subj. func filterACL(r *ACLResolver, token string, subj interface{}) error { // Get the ACL from the token - _, authorizer, err := r.ResolveTokenToIdentityAndAuthorizer(token) + authorizer, err := r.ResolveToken(token) if err != nil { return err } diff --git a/agent/consul/acl_server.go b/agent/consul/acl_server.go index 21b4d95032..e21c066b41 100644 --- a/agent/consul/acl_server.go +++ b/agent/consul/acl_server.go @@ -159,12 +159,6 @@ func (s *Server) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error return s.InPrimaryDatacenter() || index > 0, role, acl.ErrNotFound } -// TODO: remove -func (s *Server) ResolveToken(token string) (acl.Authorizer, error) { - _, authz, err := s.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) - return authz, err -} - func (s *Server) filterACL(token string, subj interface{}) error { return filterACL(s.ACLResolver, token, subj) } diff --git a/agent/consul/acl_test.go b/agent/consul/acl_test.go index 0e663120a9..b88f57d883 100644 --- a/agent/consul/acl_test.go +++ b/agent/consul/acl_test.go @@ -46,10 +46,11 @@ type asyncResolutionResult struct { err error } -func verifyAuthorizerChain(t *testing.T, expected acl.Authorizer, actual acl.Authorizer) { - expectedChainAuthz, ok := expected.(*acl.ChainedAuthorizer) +func verifyAuthorizerChain(t *testing.T, expected ACLResolveResult, actual ACLResolveResult) { + t.Helper() + expectedChainAuthz, ok := expected.Authorizer.(*acl.ChainedAuthorizer) require.True(t, ok, "expected Authorizer is not a ChainedAuthorizer") - actualChainAuthz, ok := actual.(*acl.ChainedAuthorizer) + actualChainAuthz, ok := actual.Authorizer.(*acl.ChainedAuthorizer) require.True(t, ok, "actual Authorizer is not a ChainedAuthorizer") expectedChain := expectedChainAuthz.AuthorizerChain() @@ -65,19 +66,13 @@ func verifyAuthorizerChain(t *testing.T, expected acl.Authorizer, actual acl.Aut } func resolveTokenAsync(r *ACLResolver, token string, ch chan *asyncResolutionResult) { - _, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) + authz, err := r.ResolveToken(token) ch <- &asyncResolutionResult{authz: authz, err: err} } -// Deprecated: use resolveToken or ACLResolver.ResolveTokenToIdentityAndAuthorizer instead -func (r *ACLResolver) ResolveToken(token string) (acl.Authorizer, error) { - _, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) - return authz, err -} - func resolveToken(t *testing.T, r *ACLResolver, token string) acl.Authorizer { t.Helper() - _, authz, err := r.ResolveTokenToIdentityAndAuthorizer(token) + authz, err := r.ResolveToken(token) require.NoError(t, err) return authz } @@ -739,7 +734,7 @@ func TestACLResolver_Disabled(t *testing.T) { r := newTestACLResolver(t, delegate, nil) authz, err := r.ResolveToken("does not exist") - require.Equal(t, acl.ManageAll(), authz) + require.Equal(t, ACLResolveResult{Authorizer: acl.ManageAll()}, authz) require.Nil(t, err) } @@ -753,22 +748,19 @@ func TestACLResolver_ResolveRootACL(t *testing.T) { r := newTestACLResolver(t, delegate, nil) t.Run("Allow", func(t *testing.T) { - authz, err := r.ResolveToken("allow") - require.Nil(t, authz) + _, err := r.ResolveToken("allow") require.Error(t, err) require.True(t, acl.IsErrRootDenied(err)) }) t.Run("Deny", func(t *testing.T) { - authz, err := r.ResolveToken("deny") - require.Nil(t, authz) + _, err := r.ResolveToken("deny") require.Error(t, err) require.True(t, acl.IsErrRootDenied(err)) }) t.Run("Manage", func(t *testing.T) { - authz, err := r.ResolveToken("manage") - require.Nil(t, authz) + _, err := r.ResolveToken("manage") require.Error(t, err) require.True(t, acl.IsErrRootDenied(err)) }) @@ -817,7 +809,11 @@ func TestACLResolver_DownPolicy(t *testing.T) { authz, err := r.ResolveToken("foo") require.NoError(t, err) require.NotNil(t, authz) - require.Equal(t, authz, acl.DenyAll()) + expected := ACLResolveResult{ + Authorizer: acl.DenyAll(), + ACLIdentity: &missingIdentity{reason: "primary-dc-down", token: "foo"}, + } + require.Equal(t, expected, authz) requireIdentityCached(t, r, tokenSecretCacheID("foo"), false, "not present") }) @@ -841,7 +837,11 @@ func TestACLResolver_DownPolicy(t *testing.T) { authz, err := r.ResolveToken("foo") require.NoError(t, err) require.NotNil(t, authz) - require.Equal(t, authz, acl.AllowAll()) + expected := ACLResolveResult{ + Authorizer: acl.AllowAll(), + ACLIdentity: &missingIdentity{reason: "primary-dc-down", token: "foo"}, + } + require.Equal(t, expected, authz) requireIdentityCached(t, r, tokenSecretCacheID("foo"), false, "not present") }) @@ -958,7 +958,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { config.Config.ACLDownPolicy = "extend-cache" }) - _, authz, err := r.ResolveTokenToIdentityAndAuthorizer("not-found") + authz, err := r.ResolveToken("not-found") require.NoError(t, err) require.NotNil(t, authz) require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil)) @@ -1255,10 +1255,9 @@ func TestACLResolver_DownPolicy(t *testing.T) { // the go routine spawned will eventually return and this will be a not found error retry.Run(t, func(t *retry.R) { - authz3, err := r.ResolveToken("found") + _, err := r.ResolveToken("found") assert.Error(t, err) assert.True(t, acl.IsErrNotFound(err)) - assert.Nil(t, authz3) }) requireIdentityCached(t, r, tokenSecretCacheID("found"), false, "no longer cached") @@ -1526,7 +1525,6 @@ func TestACLResolver_Client(t *testing.T) { // policies within the cache) authz, err = r.ResolveToken("a1a54629-5050-4d17-8a4e-560d2423f835") require.EqualError(t, err, acl.ErrNotFound.Error()) - require.Nil(t, authz) require.True(t, modified) require.True(t, deleted) @@ -1675,8 +1673,7 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega runTwiceAndReset("Missing Identity", func(t *testing.T) { delegate.UseTestLocalData(nil) - authz, err := r.ResolveToken("doesn't exist") - require.Nil(t, authz) + _, err := r.ResolveToken("doesn't exist") require.Error(t, err) require.True(t, acl.IsErrNotFound(err)) }) @@ -3929,12 +3926,12 @@ func TestACLResolver_AgentRecovery(t *testing.T) { tokens.UpdateAgentRecoveryToken("9a184a11-5599-459e-b71a-550e5f9a5a23", token.TokenSourceConfig) - ident, authz, err := r.ResolveTokenToIdentityAndAuthorizer("9a184a11-5599-459e-b71a-550e5f9a5a23") + authz, err := r.ResolveToken("9a184a11-5599-459e-b71a-550e5f9a5a23") require.NoError(t, err) - require.NotNil(t, ident) - require.Equal(t, "agent-recovery:foo", ident.ID()) - require.NotNil(t, authz) - require.Equal(t, r.agentRecoveryAuthz, authz) + require.NotNil(t, authz.ACLIdentity) + require.Equal(t, "agent-recovery:foo", authz.ACLIdentity.ID()) + require.NotNil(t, authz.Authorizer) + require.Equal(t, r.agentRecoveryAuthz, authz.Authorizer) require.Equal(t, acl.Allow, authz.AgentWrite("foo", nil)) require.Equal(t, acl.Allow, authz.NodeRead("bar", nil)) require.Equal(t, acl.Deny, authz.NodeWrite("bar", nil)) @@ -3998,7 +3995,7 @@ func TestACLResolver_ACLsEnabled(t *testing.T) { } -func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t *testing.T) { +func TestACLResolver_ResolveToken_UpdatesPurgeTheCache(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") } @@ -4035,7 +4032,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t require.NoError(t, err) runStep(t, "first resolve", func(t *testing.T) { - _, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) + authz, err := srv.ACLResolver.ResolveToken(token) require.NoError(t, err) require.NotNil(t, authz) require.Equal(t, acl.Allow, authz.KeyRead("foo", nil)) @@ -4054,7 +4051,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t err := msgpackrpc.CallWithCodec(codec, "ACL.PolicySet", &reqPolicy, &structs.ACLPolicy{}) require.NoError(t, err) - _, authz, err := srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) + authz, err := srv.ACLResolver.ResolveToken(token) require.NoError(t, err) require.NotNil(t, authz) require.Equal(t, acl.Deny, authz.KeyRead("foo", nil)) @@ -4070,7 +4067,7 @@ func TestACLResolver_ResolveTokenToIdentityAndAuthorizer_UpdatesPurgeTheCache(t err := msgpackrpc.CallWithCodec(codec, "ACL.TokenDelete", &req, &resp) require.NoError(t, err) - _, _, err = srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(token) + _, err = srv.ACLResolver.ResolveToken(token) require.True(t, acl.IsErrNotFound(err), "Error %v is not acl.ErrNotFound", err) }) } diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go index 2031641caa..1fb8946623 100644 --- a/agent/consul/intention_endpoint.go +++ b/agent/consul/intention_endpoint.go @@ -100,21 +100,13 @@ func (s *Intention) Apply(args *structs.IntentionRequest, reply *string) error { } // Get the ACL token for the request for the checks below. - // TODO: use ResolveTokenAndDefaultMeta - identity, authz, err := s.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + var entMeta structs.EnterpriseMeta + authz, err := s.srv.ACLResolver.ResolveTokenAndDefaultMeta(args.Token, &entMeta, nil) if err != nil { return err } - var accessorID string - var entMeta structs.EnterpriseMeta - if identity != nil { - entMeta.Merge(identity.EnterpriseMetadata()) - accessorID = identity.ID() - } else { - entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) - } - + accessorID := authz.AccessorID() var ( mut *structs.IntentionMutation legacyWrite bool diff --git a/agent/consul/internal_endpoint.go b/agent/consul/internal_endpoint.go index 5213349e79..44b6af5aaf 100644 --- a/agent/consul/internal_endpoint.go +++ b/agent/consul/internal_endpoint.go @@ -433,11 +433,11 @@ func (m *Internal) KeyringOperation( } // Check ACLs - identity, authz, err := m.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := m.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := m.srv.validateEnterpriseToken(identity); err != nil { + if err := m.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } switch args.Operation { diff --git a/agent/consul/operator_autopilot_endpoint.go b/agent/consul/operator_autopilot_endpoint.go index d600df83cb..f4a3db65e6 100644 --- a/agent/consul/operator_autopilot_endpoint.go +++ b/agent/consul/operator_autopilot_endpoint.go @@ -17,11 +17,11 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r } // This action requires operator read access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { @@ -49,11 +49,11 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe } // This action requires operator write access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { @@ -84,11 +84,11 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *structs } // This action requires operator read access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { @@ -151,11 +151,11 @@ func (op *Operator) AutopilotState(args *structs.DCSpecificRequest, reply *autop } // This action requires operator read access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { diff --git a/agent/consul/operator_raft_endpoint.go b/agent/consul/operator_raft_endpoint.go index 72ae5b195b..431b455c08 100644 --- a/agent/consul/operator_raft_endpoint.go +++ b/agent/consul/operator_raft_endpoint.go @@ -81,11 +81,11 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest, // This is a super dangerous operation that requires operator write // access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { @@ -134,11 +134,11 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl // This is a super dangerous operation that requires operator write // access. - identity, authz, err := op.srv.ACLResolver.ResolveTokenToIdentityAndAuthorizer(args.Token) + authz, err := op.srv.ACLResolver.ResolveToken(args.Token) if err != nil { return err } - if err := op.srv.validateEnterpriseToken(identity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { From 2893275e33f3d5b2e184e94d7c63f0ea496fc936 Mon Sep 17 00:00:00 2001 From: David Yu Date: Mon, 31 Jan 2022 17:26:44 -0800 Subject: [PATCH 38/78] docs: slight formatting update and provide example with service mesh enabled (#12227) * docs: slight formatting update and provide example with service mesh install * add status * Update website/content/docs/k8s/installation/install.mdx Co-authored-by: mrspanishviking * Update install.mdx * Update install.mdx * Update install.mdx * Update install.mdx * Update install.mdx Co-authored-by: mrspanishviking --- .../content/docs/k8s/installation/install.mdx | 76 ++++++++++++------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/website/content/docs/k8s/installation/install.mdx b/website/content/docs/k8s/installation/install.mdx index 9d0543519f..1d166c2921 100644 --- a/website/content/docs/k8s/installation/install.mdx +++ b/website/content/docs/k8s/installation/install.mdx @@ -27,7 +27,7 @@ mesh](https://learn.hashicorp.com/tutorials/consul/service-mesh-deploy?utm_sourc ## Consul K8s CLI Installation -We recommend using the [Consul K8S CLI](/docs/k8s/k8s-cli) to install Consul on Kubernetes for single-cluster deployments. You can install Consul on Kubernetes using the Consul K8s CLI tool after installing the CLI. +We recommend using the [Consul K8s CLI](/docs/k8s/k8s-cli) to install Consul on Kubernetes for single-cluster deployments. You can install Consul on Kubernetes using the Consul K8s CLI tool after installing the CLI. Before beginning the installation process, verify that `kubectl` is already configured to authenticate to the Kubernetes cluster using a valid `kubeconfig` file. @@ -45,38 +45,58 @@ The [Homebrew](https://brew.sh) package manager is required to complete the foll $ brew install hashicorp/tap/consul-k8s ``` -1. Issue the `install` subcommand to install Consul on Kubernetes: +1. Issue the `install` subcommand to install Consul on Kubernetes. Refer to the [Consul K8s CLI reference](/docs/k8s/k8s-cli) for details about all commands and available options. Without any additional options passed, the `consul-k8s` CLI will install Consul on Kubernetes by using the Consul Helm chart's default values. Below is an example that installs Consul on Kubernetes with Service Mesh and CRDs enabled. If you did not set the `-auto-approve` option to `true`, you will be prompted to proceed with the installation if the pre-install checks pass. - ```shell-session - consul-k8s install - ``` - - Refer to the [Consul K8s CLI reference](/docs/k8s/k8s-cli) for details about all commands and available options. - - If you did not set the `-auto-approve` option to `true`, you will be prompted to proceed with the installation if the pre-install checks pass. + -> The pre-install checks may fail if existing `PersistentVolumeClaims` (PVC) are detected. Refer to the [uninstall instructions](/docs/k8s/operations/uninstall#uninstall-consul) for information about removing PVCs. + + ```shell-session + $ consul-k8s install -set connectInject.enabled=true -set controller.enabled=true - ```shell-session - ==> Pre-Install Checks - ✓ No existing installations found + ==> Pre-Install Checks + No existing installations found. ✓ No previous persistent volume claims found ✓ No previous secrets found - ==> Consul Installation Summary - Installation name: consul - Namespace: myns - Overrides: - connectInject: - enabled: true - global: - name: consul - server: - bootstrapExpect: 1 - replicas: 1 - - Proceed with installation? (y/n) - ``` - -1. Enter `y` to proceed. The pre-install checks may fail if existing `PersistentVolumeClaims` (PVC) are detected. Refer to the [uninstall instructions](/docs/k8s/operations/uninstall#uninstall-consul) for information about removing PVCs. + ==> Consul Installation Summary + Installation name: consul + Namespace: consul + Overrides: + connectInject: + enabled: true + controller: + enabled: true + + Proceed with installation? (y/N) y + + ==> Running Installation + ✓ Downloaded charts + --> creating 1 resource(s) + --> creating 45 resource(s) + --> beginning wait for 45 resources with timeout of 10m0s + ✓ Consul installed into namespace "consul" + ``` + +1. (Optional) Run `consul-k8s status` command to quickly glance at the status of the installed Consul cluster. + + ```shell-session + $ consul-k8s status + + ==> Consul-K8s Status Summary + NAME | NAMESPACE | STATUS | CHARTVERSION | APPVERSION | REVISION | LAST UPDATED + ---------+-----------+----------+--------------+------------+----------+-------------------------- + consul | consul | deployed | 0.40.0 | 1.11.2 | 1 | 2022/01/31 16:58:51 PST + + ==> Config: + connectInject: + enabled: true + controller: + enabled: true + global: + name: consul + + ✓ Consul servers healthy (3/3) + ✓ Consul clients healthy (3/3) + ``` ## Helm Chart Installation From 59756e4a8872a0db3d284e6d3f289afb6e287099 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Tue, 1 Feb 2022 14:25:24 +0000 Subject: [PATCH 39/78] ui: on-outside modifier (#12206) --- .../consul-ui/app/modifiers/on-outside.js | 45 +++++++++++++++++++ .../consul-ui/app/modifiers/on-outside.mdx | 22 +++++++++ 2 files changed, 67 insertions(+) create mode 100644 ui/packages/consul-ui/app/modifiers/on-outside.js create mode 100644 ui/packages/consul-ui/app/modifiers/on-outside.mdx diff --git a/ui/packages/consul-ui/app/modifiers/on-outside.js b/ui/packages/consul-ui/app/modifiers/on-outside.js new file mode 100644 index 0000000000..fe32dee5ac --- /dev/null +++ b/ui/packages/consul-ui/app/modifiers/on-outside.js @@ -0,0 +1,45 @@ +import Modifier from 'ember-modifier'; +import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; + +export default class OnOutsideModifier extends Modifier { + @service('dom') dom; + + constructor() { + super(...arguments); + this.doc = this.dom.document(); + } + async connect(params, options) { + await new Promise(resolve => setTimeout(resolve, 0)); + try { + this.doc.addEventListener(params[0], this.listen); + } catch (e) { + // continue + } + } + + @action + listen(e) { + if (this.dom.isOutside(this.element, e.target)) { + const dispatch = typeof this.params[1] === 'function' ? this.params[1] : _ => {}; + dispatch.apply(this.element, [e]); + } + } + + disconnect() { + this.doc.removeEventListener('click', this.listen); + } + + didReceiveArguments() { + this.params = this.args.positional; + this.options = this.args.named; + } + + didInstall() { + this.connect(this.args.positional, this.args.named); + } + + willRemove() { + this.disconnect(); + } +} diff --git a/ui/packages/consul-ui/app/modifiers/on-outside.mdx b/ui/packages/consul-ui/app/modifiers/on-outside.mdx new file mode 100644 index 0000000000..325091b99e --- /dev/null +++ b/ui/packages/consul-ui/app/modifiers/on-outside.mdx @@ -0,0 +1,22 @@ +# on-outside + +`{{on-outside 'click' (fn @callback}}` works similarly to `{{on }}` but allows +you to attach handlers that is specifically not the currently modified +element. + +```hbs preview-template + +``` + +## Positional Arguments + +| Argument | Type | Default | Description | +| --- | --- | --- | --- | +| `event` | `string` | | Name of the event to listen for | +| `handler` | `function` | | Function to handle the event | From 189895e8faa1e57e9c595e73b71f5b83f31d3811 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Tue, 1 Feb 2022 16:39:02 +0000 Subject: [PATCH 40/78] ui: style-map helper (#12203) --- .../consul-ui/app/helpers/style-map.js | 22 +++++++ .../consul-ui/app/helpers/style-map.mdx | 58 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 ui/packages/consul-ui/app/helpers/style-map.js create mode 100644 ui/packages/consul-ui/app/helpers/style-map.mdx diff --git a/ui/packages/consul-ui/app/helpers/style-map.js b/ui/packages/consul-ui/app/helpers/style-map.js new file mode 100644 index 0000000000..259effd1e1 --- /dev/null +++ b/ui/packages/consul-ui/app/helpers/style-map.js @@ -0,0 +1,22 @@ +import { helper } from '@ember/component/helper'; + +/** + * Conditionally maps styles to a string ready for typical DOM + * usage (i.e. semi-colon delimited) + * + * @typedef {([string, (string | undefined), string] | [string, (string | undefined)])} styleInfo + * @param {styleInfo[]} entries - An array of `styleInfo`s to map + * @param {boolean} transform=true - whether to perform the build-time 'helper + * to modifier' transpilation. Note a transpiler needs installing separately. + */ +const styleMap = (entries, transform = true) => { + const str = entries.reduce((prev, [prop, value, unit = '']) => { + if (value == null) { + return prev; + } + return `${prev}${prop}:${value.toString()}${unit};`; + }, ''); + return str.length > 0 ? str : undefined; +}; + +export default helper(styleMap); diff --git a/ui/packages/consul-ui/app/helpers/style-map.mdx b/ui/packages/consul-ui/app/helpers/style-map.mdx new file mode 100644 index 0000000000..cb7fb6362b --- /dev/null +++ b/ui/packages/consul-ui/app/helpers/style-map.mdx @@ -0,0 +1,58 @@ +# style-map + +`{{style-map}}` is used to easily add a list of styles, conditionally, and +have them all formatted nicely to be printed in a DOM `style` attribute. + +As well as an entry-like array you can also pass an additional `unit` property +as the 3rd item in the array. This is to make it easier to do mathamatical +calculations for units without having to use `(concat)`. + +If any property has a value of `null` or `undefined`, that style property will +not be included in the resulting string. + +```hbs preview-template +
+
+ This div has the correct style added/omitted. +
+
+ + style={{style-map + (array 'outline' '1px solid red') + (array 'width' '600px') + (array 'height' 100 'px') + (array 'padding' 1 'rem') + (array 'background' null) + }} + +
+
+``` + +## Positional Arguments + +| Argument | Type | Default | Description | +| --- | --- | --- | --- | +| `entries` | `styleInfo[]` | | An array of `styleInfo`s to map | + +## Named Arguments + +| Argument | Type | Default | Description | +| --- | --- | --- | --- | +| `transform` | `boolean` | true | whether to perform the build-time 'helper to modifier' transpilation | + +## Types + +| Type | Default | Description | +| --- | --- | --- | +| `styleInfo` | `([string, (string \| undefined), string] \| [string, (string \| undefined)])` | | + + From db9c6acf04983bc2bbdf06fe1f5ebb2f8e31e9bf Mon Sep 17 00:00:00 2001 From: Ricardo Oliveira <17067463+gitrgoliveira@users.noreply.github.com> Date: Tue, 1 Feb 2022 17:10:49 +0000 Subject: [PATCH 41/78] Update redirect-traffic.mdx --- website/content/commands/connect/redirect-traffic.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/website/content/commands/connect/redirect-traffic.mdx b/website/content/commands/connect/redirect-traffic.mdx index 27313d5367..b56012c1a3 100644 --- a/website/content/commands/connect/redirect-traffic.mdx +++ b/website/content/commands/connect/redirect-traffic.mdx @@ -36,6 +36,8 @@ Usage: `consul connect redirect-traffic [options]` #### Options for Traffic Redirection Rules +- `-consul-dns-ip` - IP used to reach Consul DNS. If provided, DNS queries will be redirected to Consul. + - `-proxy-id` - The [proxy service](/docs/connect/registration/service-registration) ID. This service ID must already be registered with the local agent. @@ -47,13 +49,13 @@ Usage: `consul connect redirect-traffic [options]` - `-exclude-inbound-port` - Inbound port to exclude from traffic redirection. May be provided multiple times. -- `exclude-outbound-cidr` - Outbound CIDR to exclude from traffic redirection. May be provided multiple times. +- `-exclude-outbound-cidr` - Outbound CIDR to exclude from traffic redirection. May be provided multiple times. -- `exclude-outbound-port` - Outbound port to exclude from traffic redirection. May be provided multiple times. +- `-exclude-outbound-port` - Outbound port to exclude from traffic redirection. May be provided multiple times. -- `exclude-uid` - Additional user ID to exclude from traffic redirection. May be provided multiple times. +- `-exclude-uid` - Additional user ID to exclude from traffic redirection. May be provided multiple times. -- `netns` - The Linux network namespace where traffic redirection rules should apply. +- `-netns` - The Linux network namespace where traffic redirection rules should apply. This must be a path to the network namespace, e.g. /var/run/netns/foo. #### Enterprise Options From c4ea9229587996879dc8efb00b57a7e5fe615dd4 Mon Sep 17 00:00:00 2001 From: Ricardo Oliveira <17067463+gitrgoliveira@users.noreply.github.com> Date: Tue, 1 Feb 2022 17:20:20 +0000 Subject: [PATCH 42/78] Update website/content/commands/connect/redirect-traffic.mdx Co-authored-by: mrspanishviking --- website/content/commands/connect/redirect-traffic.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/commands/connect/redirect-traffic.mdx b/website/content/commands/connect/redirect-traffic.mdx index b56012c1a3..2707350ab0 100644 --- a/website/content/commands/connect/redirect-traffic.mdx +++ b/website/content/commands/connect/redirect-traffic.mdx @@ -36,7 +36,7 @@ Usage: `consul connect redirect-traffic [options]` #### Options for Traffic Redirection Rules -- `-consul-dns-ip` - IP used to reach Consul DNS. If provided, DNS queries will be redirected to Consul. +- `-consul-dns-ip` - The IP address of the Consul DNS resolver. If provided, Consul DNS queries will be redirected to the provided IP address for resolving. - `-proxy-id` - The [proxy service](/docs/connect/registration/service-registration) ID. This service ID must already be registered with the local agent. From e2385fe329909fd1b7d349071f46f23722a8eaff Mon Sep 17 00:00:00 2001 From: Jared Kirschner Date: Wed, 11 Aug 2021 16:47:30 -0400 Subject: [PATCH 43/78] docs: show how to cross-compile from source --- website/content/docs/install/index.mdx | 44 ++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/website/content/docs/install/index.mdx b/website/content/docs/install/index.mdx index f85405f96a..1ba04c683c 100644 --- a/website/content/docs/install/index.mdx +++ b/website/content/docs/install/index.mdx @@ -56,14 +56,44 @@ a copy of [`git`](https://www.git-scm.com/) in your `PATH`. $ make tools ``` -1. Build Consul for your current system and put the binary in `./bin/` - (relative to the git checkout). The `make dev` target is just a shortcut that - builds `consul` for only your local build environment (no cross-compiled - targets). +1. Build Consul for your target system. The binary will be placed in `./bin` + (relative to the git checkout). - ```shell - $ make dev - ``` + + + + + +```shell-session +$ make dev +``` + + + + +Specify your target system by setting the following environment variables +before building: + +- `XC_OS`: Target operating system. Valid values include: + `linux`, `darwin`, `windows`, `solaris`, `freebsd`. +- `XC_ARCH`: Target architecture. Valid values include: + `386`, `amd64`, `arm`, `arm64` + +```shell-session +$ export XC_OS=linux XC_ARCH=amd64 +$ make dev +``` + + + ## Verifying the Installation From c42186f3602433228cb0198b38d82a16083c674e Mon Sep 17 00:00:00 2001 From: Jared Kirschner Date: Wed, 11 Aug 2021 16:48:29 -0400 Subject: [PATCH 44/78] docs: link from makefile to compile instructions Some practitioners look to the makefile directly rather than to the consul website for information on how to compile from source. Link to the website instructions directly from the makefile so the practitioner can accomplish their task successfully without a careful read of the makefile. --- GNUmakefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GNUmakefile b/GNUmakefile index 311a47533f..823ca06fe0 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,3 +1,6 @@ +# For documentation on building consul from source, refer to: +# https://www.consul.io/docs/install#compiling-from-source + SHELL = bash GOGOVERSION?=$(shell grep github.com/gogo/protobuf go.mod | awk '{print $$2}') GOTOOLS = \ From 947e972dd2dc2807ce3e521057a328b3344b56f2 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 9 Sep 2021 11:32:05 -0400 Subject: [PATCH 45/78] docs: update install from source GOPATH is not longer necessary as of Go1.11. No additional tools are required, just Go. --- website/content/docs/install/index.mdx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/website/content/docs/install/index.mdx b/website/content/docs/install/index.mdx index 1ba04c683c..95ac37996e 100644 --- a/website/content/docs/install/index.mdx +++ b/website/content/docs/install/index.mdx @@ -38,24 +38,15 @@ command-line, make sure to place it somewhere on your `PATH`. ## Compiling from Source To compile from source, you will need [Go](https://golang.org) installed and -configured properly (including a `GOPATH` environment variable set), as well as a copy of [`git`](https://www.git-scm.com/) in your `PATH`. -1. Clone the Consul repository from GitHub into your `GOPATH`: +1. Clone the Consul repository from GitHub: ```shell - $ mkdir -p $GOPATH/src/github.com/hashicorp && cd !$ $ git clone https://github.com/hashicorp/consul.git $ cd consul ``` -1. Bootstrap the project. This will download and compile libraries and tools - needed to compile Consul: - - ```shell - $ make tools - ``` - 1. Build Consul for your target system. The binary will be placed in `./bin` (relative to the git checkout). @@ -82,13 +73,13 @@ $ make dev Specify your target system by setting the following environment variables before building: -- `XC_OS`: Target operating system. Valid values include: +- `GOOS`: Target operating system. Valid values include: `linux`, `darwin`, `windows`, `solaris`, `freebsd`. -- `XC_ARCH`: Target architecture. Valid values include: +- `GOARCH`: Target architecture. Valid values include: `386`, `amd64`, `arm`, `arm64` ```shell-session -$ export XC_OS=linux XC_ARCH=amd64 +$ export GOOS=linux GOARCH=amd64 $ make dev ``` From 9cfe4aebcf038d4823584feb6795eecf250a7e82 Mon Sep 17 00:00:00 2001 From: Jake Herschman Date: Tue, 1 Feb 2022 13:59:26 -0500 Subject: [PATCH 46/78] Updated copy based on feedback --- website/content/docs/nia/compatibility.mdx | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index bf0b568b3f..bdba0a4fbd 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -11,30 +11,30 @@ The following tables list the Consul-Terraform-Sync (CTS) version compatibility ## Consul -Below are Consul-Terraform-Sync versions with supported Consul versions. The latest Consul-Terraform-Sync binary targets supporting the latest patch version of the three most recent Consul minor versions. +Below are CTS versions with supported Consul versions. The latest CTS binary supports the three most recent Consul minor versions, along with their latest patch versions. -| Consul-Terraform-Sync Version | Consul OSS & Enterprise Version | -| :---------------------------- | :------------------------------ | -| CTS Enterprise 0.3+ | 1.8+ | -| CTS OSS 0.1+ | 1.8+ | +| CTS Version | Consul OSS & Enterprise Version | +| :------------------ | :------------------------------ | +| CTS Enterprise 0.3+ | 1.8+ | +| CTS OSS 0.1+ | 1.8+ | ## Terraform -Consul-Terraform-Sync integration with Terraform is supported for the following: +CTS integration with Terraform is supported for the following: -| Consul-Terraform-Sync Version | Terraform CLI Version | Terraform Cloud Version | Terraform Enterprise Version | -| :---------------------------- | :-------------------- | :---------------------- | :--------------------------- | -| CTS Enterprise 0.4+ | 0.13 - 1.1 | Latest | v202010-2 - Latest | -| CTS Enterprise 0.3+ | 0.13 - 1.1 | N/A | v202010-2 - Latest | -| CTS OSS 0.3+ | 0.13 - 1.1 | N/A | N/A | -| CTS OSS 0.2 | 0.13 - 1.0 | N/A | N/A | -| CTS OSS 0.1 | 0.13 - 0.14 | N/A | N/A | +| CTS Version | Terraform CLI Version | Terraform Cloud Version | Terraform Enterprise Version | +| :------------------ | :-------------------- | :---------------------- | :--------------------------- | +| CTS Enterprise 0.4+ | 0.13 - 1.1 | Latest | v202010-2 - Latest | +| CTS Enterprise 0.3+ | 0.13 - 1.1 | N/A | v202010-2 - Latest | +| CTS OSS 0.3+ | 0.13 - 1.1 | N/A | N/A | +| CTS OSS 0.2 | 0.13 - 1.0 | N/A | N/A | +| CTS OSS 0.1 | 0.13 - 0.14 | N/A | N/A | ## Vault -Consul-Terraform-Sync integrates with Vault to query secrets, and is supported for the following: +CTS integrates with Vault to query secrets, the integration is supported for the following: -| Consul-Terraform-Sync Version | Vault OSS & Enterprise Version | -| :---------------------------- | :----------------------------- | -| CTS Enterprise 0.3+ | 0.7+ | -| CTS OSS 0.1+ | 0.7+ | +| CTS Version | Vault OSS & Enterprise Version | +| :------------------ | :----------------------------- | +| CTS Enterprise 0.3+ | 0.7+ | +| CTS OSS 0.1+ | 0.7+ | From 417cb8d838827a4f11eec6041718c4ee3ec899e9 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Tue, 1 Feb 2022 19:48:57 +0000 Subject: [PATCH 47/78] ui: attach-shadow modifier (#12207) * ui: attach-shadow modifier * ui: adopt-styles helper (#12208) --- .../consul-ui/app/helpers/adopt-styles.js | 18 ++++++++++++ .../consul-ui/app/helpers/adopt-styles.mdx | 28 +++++++++++++++++++ ui/packages/consul-ui/app/helpers/css.js | 8 ++++++ .../consul-ui/app/modifiers/attach-shadow.js | 23 +++++++++++++++ .../consul-ui/app/modifiers/attach-shadow.mdx | 28 +++++++++++++++++++ ui/packages/consul-ui/package.json | 3 +- ui/yarn.lock | 5 ++++ 7 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 ui/packages/consul-ui/app/helpers/adopt-styles.js create mode 100644 ui/packages/consul-ui/app/helpers/adopt-styles.mdx create mode 100644 ui/packages/consul-ui/app/helpers/css.js create mode 100644 ui/packages/consul-ui/app/modifiers/attach-shadow.js create mode 100644 ui/packages/consul-ui/app/modifiers/attach-shadow.mdx diff --git a/ui/packages/consul-ui/app/helpers/adopt-styles.js b/ui/packages/consul-ui/app/helpers/adopt-styles.js new file mode 100644 index 0000000000..4fd10a71bc --- /dev/null +++ b/ui/packages/consul-ui/app/helpers/adopt-styles.js @@ -0,0 +1,18 @@ +import Helper from '@ember/component/helper'; +import { assert } from '@ember/debug'; +import { adoptStyles } from '@lit/reactive-element'; + +export default class AdoptStylesHelper extends Helper { + /** + * Adopt/apply given styles to a `ShadowRoot` using constructable styleSheets if supported + * + * @param {[ShadowRoot, CSSResultGroup]} params + */ + compute([$shadow, styles], hash) { + assert( + 'adopt-styles can only be used to apply styles to ShadowDOM elements', + $shadow instanceof ShadowRoot + ); + adoptStyles($shadow, [styles]); + } +} diff --git a/ui/packages/consul-ui/app/helpers/adopt-styles.mdx b/ui/packages/consul-ui/app/helpers/adopt-styles.mdx new file mode 100644 index 0000000000..b2d09331bb --- /dev/null +++ b/ui/packages/consul-ui/app/helpers/adopt-styles.mdx @@ -0,0 +1,28 @@ +# adopt-styles + +Adopt/apply given styles to a `ShadowRoot` using constructable styleSheets if supported + +```hbs preview-template +
+ {{#if this.shadow}} + {{#in-element this.shadow}} + {{adopt-styles this.shadow (css ' + :host { + background-color: red; + width: 100px; + height: 100px; + } + ')}} + {{/in-element}} + {{/if}} +
+``` + +## Positional Arguments + +| Argument | Type | Default | Description | +| --- | --- | --- | --- | +| `params` | `[ShadowRoot, CSSResultGroup]` | | | + diff --git a/ui/packages/consul-ui/app/helpers/css.js b/ui/packages/consul-ui/app/helpers/css.js new file mode 100644 index 0000000000..35bb4aabad --- /dev/null +++ b/ui/packages/consul-ui/app/helpers/css.js @@ -0,0 +1,8 @@ +import Helper from '@ember/component/helper'; +import { css } from '@lit/reactive-element'; + +export default class ConsoleLogHelper extends Helper { + compute([str], hash) { + return css([str]); + } +} diff --git a/ui/packages/consul-ui/app/modifiers/attach-shadow.js b/ui/packages/consul-ui/app/modifiers/attach-shadow.js new file mode 100644 index 0000000000..94901c67d6 --- /dev/null +++ b/ui/packages/consul-ui/app/modifiers/attach-shadow.js @@ -0,0 +1,23 @@ +import { setModifierManager, capabilities } from '@ember/modifier'; + +export default setModifierManager( + () => ({ + capabilities: capabilities('3.13', { disableAutoTracking: true }), + + createModifier() {}, + + installModifier(_state, element, { positional: [fn, ...args], named }) { + let shadow; + try { + shadow = element.attachShadow({ mode: 'open' }); + } catch (e) { + // shadow = false; + console.error(e); + } + fn(shadow); + }, + updateModifier() {}, + destroyModifier() {}, + }), + class CustomElementModifier {} +); diff --git a/ui/packages/consul-ui/app/modifiers/attach-shadow.mdx b/ui/packages/consul-ui/app/modifiers/attach-shadow.mdx new file mode 100644 index 0000000000..3e973665ca --- /dev/null +++ b/ui/packages/consul-ui/app/modifiers/attach-shadow.mdx @@ -0,0 +1,28 @@ +# attach-shadow + +`{{attach-shadow (set this 'shadow')}}` attaches a `ShadowRoot` to the modified DOM element +and pass a reference to that `ShadowRoot` to the setter function. + + +Please note: This should be used as a utility modifier for when having access +to the shadow DOM is handy, not really for building full blown shadow DOM +based Web Components. + +```hbs preview-template +
+ {{#if this.shadow}} + {{#in-element this.shadow}} + + {{/in-element}} + {{/if}} +

Hello from the shadows!

+
+``` + +## Positional Arguments + +| Argument | Type | Default | Description | +| --- | --- | --- | --- | +| `setter` | `function` | | Usually `set` or `mut` or similar | diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json index 5c4035202e..18bb4e6ad6 100644 --- a/ui/packages/consul-ui/package.json +++ b/ui/packages/consul-ui/package.json @@ -63,6 +63,7 @@ "@glimmer/component": "^1.0.0", "@glimmer/tracking": "^1.0.0", "@hashicorp/ember-cli-api-double": "^3.1.0", + "@lit/reactive-element": "^1.2.1", "@mapbox/rehype-prism": "^0.6.0", "@xstate/fsm": "^1.4.0", "a11y-dialog": "^6.0.1", @@ -79,8 +80,8 @@ "chalk": "^4.1.0", "clipboard": "^2.0.4", "consul-acls": "*", - "consul-partitions": "*", "consul-nspaces": "*", + "consul-partitions": "*", "css.escape": "^1.5.1", "d3-array": "^2.8.0", "d3-scale": "^3.2.3", diff --git a/ui/yarn.lock b/ui/yarn.lock index e9d89fefac..d61667fbd7 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1560,6 +1560,11 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== +"@lit/reactive-element@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.2.1.tgz#8620d7f0baf63e12821fa93c34d21e23477736f7" + integrity sha512-03FYfMguIWo9E1y1qcTpXzoO8Ukpn0j5o4GjNFq/iHqJEPY6pYopsU44e7NSFIgCTorr8wdUU5PfVy8VeD6Rwg== + "@mapbox/rehype-prism@^0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@mapbox/rehype-prism/-/rehype-prism-0.6.0.tgz#3d8a860870951d4354257d0ba908d11545bd5ed5" From d433a9d0850789cac0afd73d30c20567a3edcfd0 Mon Sep 17 00:00:00 2001 From: JG Date: Tue, 1 Feb 2022 12:07:18 -0800 Subject: [PATCH 48/78] packaging: fix issues in pre/postremove scripts (#12147) Fixes several issues with the pre/postremove scripts for both rpm and deb packages. Specifically: For postremove: - the postremove script now functions correctly (i.e. restarts consul after a package upgrade) on rpm-based systems (where $1 is numeric rather than `purge` or `upgrade`) - `systemctl daemon-reload` is called on package removal (rather than only on upgrade) - calls `systemctl try-restart` instead of `systemctl restart`, which will only (re)start consul if it was already running when the upgrade happened. For preremove: - if the package is being completely uninstalled (rather than upgraded), stop consul before removing the package --- .github/workflows/build.yml | 3 ++- .release/linux/postremove | 21 +++++++++++++-------- .release/linux/preremove | 11 +++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 .release/linux/preremove diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 277a116100..5b8666bfcd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: build on: push: # Sequence of patterns matched against refs/heads - branches: [ + branches: [ "main" ] @@ -145,6 +145,7 @@ jobs: config_dir: ".release/linux/package" preinstall: ".release/linux/preinstall" postinstall: ".release/linux/postinstall" + preremove: ".release/linux/preremove" postremove: ".release/linux/postremove" - name: Set Package Names diff --git a/.release/linux/postremove b/.release/linux/postremove index f317598216..b09bdfe60e 100644 --- a/.release/linux/postremove +++ b/.release/linux/postremove @@ -1,14 +1,19 @@ #!/bin/bash -if [ "$1" = "purge" ] -then - userdel consul +if [ -d "/run/systemd/system" ]; then + systemctl --system daemon-reload >/dev/null || : fi -if [ "$1" == "upgrade" ] && [ -d /run/systemd/system ]; then - systemctl --system daemon-reload >/dev/null || true - systemctl restart consul >/dev/null || true -fi +case "$1" in + purge | 0) + userdel consul + ;; -exit 0 + upgrade | [1-9]*) + if [ -d "/run/systemd/system" ]; then + systemctl try-restart consul.service >/dev/null || : + fi + ;; +esac +exit 0 diff --git a/.release/linux/preremove b/.release/linux/preremove new file mode 100644 index 0000000000..16fef7f3b4 --- /dev/null +++ b/.release/linux/preremove @@ -0,0 +1,11 @@ +#!/bin/bash +case "$1" in + remove | 0) + if [ -d "/run/systemd/system" ]; then + systemctl --no-reload disable consul.service > /dev/null || : + systemctl stop consul.service > /dev/null || : + fi + ;; +esac + +exit 0 From ed586ade37ffd268bd8d79448087a37e417515dc Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Tue, 1 Feb 2022 15:08:23 -0700 Subject: [PATCH 49/78] Update website/content/commands/connect/redirect-traffic.mdx Co-authored-by: Blake Covarrubias --- website/content/commands/connect/redirect-traffic.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/commands/connect/redirect-traffic.mdx b/website/content/commands/connect/redirect-traffic.mdx index 2707350ab0..fef0dc716b 100644 --- a/website/content/commands/connect/redirect-traffic.mdx +++ b/website/content/commands/connect/redirect-traffic.mdx @@ -36,7 +36,7 @@ Usage: `consul connect redirect-traffic [options]` #### Options for Traffic Redirection Rules -- `-consul-dns-ip` - The IP address of the Consul DNS resolver. If provided, Consul DNS queries will be redirected to the provided IP address for resolving. +- `-consul-dns-ip` - The IP address of the Consul DNS resolver. If provided, DNS queries will be redirected to the provided IP address for name resolution. - `-proxy-id` - The [proxy service](/docs/connect/registration/service-registration) ID. This service ID must already be registered with the local agent. From 6be597021776893a0ffb6bdeecd8162cfd1ff500 Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Tue, 1 Feb 2022 15:18:47 -0700 Subject: [PATCH 50/78] Apply suggestions from code review Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com> --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index d85b24b9a7..3d54fec7a9 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -2,13 +2,13 @@ layout: docs page_title: What is a service mesh? description: >- - Learn what a service mesh is, it's benefits, and how it works. + Learn what a service mesh is, its benefits, and how it works. A service mesh can solve many of the modern challenges that exist in multi-platform and multi-cloud application architectures, ranging from security to application resiliency. --- # What is a Service Mesh? -A _service mesh_ is a dedicated network layer that provides secure service-to-service communication for on-prem, cloud, or multi-cloud infrastructure. +A _service mesh_ is a dedicated network layer that provides secure service-to-service communication within and across infrastructure, including on-premises and cloud environments. Service meshes are often used with a microservice architectural pattern, but can provide value in any scenario where complex networking is involved. ## Benefits of a Service Mesh From a8c6543e721ca1d7261724807aed8a956548ccb3 Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Tue, 1 Feb 2022 15:22:32 -0700 Subject: [PATCH 51/78] Apply suggestions from code review Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com> --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 3d54fec7a9..a3e5dfd1dd 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -61,7 +61,7 @@ A service mesh can be connected to another service mesh in another data center o ## What Problems Does a Service Mesh Solve? -Modern infrastructure is transitioning from primarily being static-based to dynamic in nature (ephemeral). +Modern infrastructure is transitioning from being primarily static to dynamic in nature (ephemeral). This dynamic infrastructure has a short life cycle, meaning virtual machines (VM) and containers are frequently recycled. It's difficult for an organization to manage and keep track of application services that live on short-lived resources. A service mesh solves this problem by acting as a central registry of all registered services. As service instances, either VMs or containers, come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a service mesh solves. @@ -85,7 +85,7 @@ This shift from an IP address-based security model to a service-focused model re ## How Do You Implement a Service Mesh? Service meshes are commonly installed in Kubernetes clusters. There are also platform-agnostic service meshes available for non-Kubernetes-based workloads. -For Kubernetes, most service mesh can be installed by operators through a [Helm chart](https://helm.sh/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. +For Kubernetes, most service meshes can be installed by operators through a [Helm chart](https://helm.sh/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. Non-Kubernetes based service meshes can be installed through infrastructure as code (IaC) products such as [Terraform](https://www.terraform.io/), CloudFormation, ARM Templates, Puppet, Chef, etc. ## What is a Multi Platform Service Mesh? From 0f94ce3964ad0db1492d855b6e2693bf47ef1009 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Wed, 2 Feb 2022 13:24:47 +0000 Subject: [PATCH 52/78] ui: Alias all our Structure Icons to Flight Icons (#12209) --- .changelog/12209.txt | 3 + .../app/components/buttons/skin.scss | 1 - .../consul/external-source/index.scss | 28 + .../consul/intention/components.scss | 8 +- .../consul/intention/form/fieldsets/skin.scss | 7 +- .../consul-ui/app/components/pill/index.scss | 28 - .../consul-ui/app/components/pill/layout.scss | 3 +- .../app/components/popover-select/index.scss | 2 +- .../styles/base/icons/base-placeholders.scss | 12 +- .../app/styles/base/icons/base-variables.scss | 2382 +++++---- .../app/styles/base/icons/debug.scss | 4706 +++++++++++++---- .../styles/base/icons/icon-placeholders.scss | 2554 ++++++--- ui/packages/consul-ui/app/styles/icons.scss | 67 + 13 files changed, 6759 insertions(+), 3042 deletions(-) create mode 100644 .changelog/12209.txt diff --git a/.changelog/12209.txt b/.changelog/12209.txt new file mode 100644 index 0000000000..5847b091c5 --- /dev/null +++ b/.changelog/12209.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +ui: Use @hashicorp/flight icons for all our icons. +``` diff --git a/ui/packages/consul-ui/app/components/buttons/skin.scss b/ui/packages/consul-ui/app/components/buttons/skin.scss index d6d36d8297..facc85a208 100644 --- a/ui/packages/consul-ui/app/components/buttons/skin.scss +++ b/ui/packages/consul-ui/app/components/buttons/skin.scss @@ -100,7 +100,6 @@ %sort-button::before { @extend %with-sort-mask, %as-pseudo; position: relative; - top: 4px; width: 16px; height: 16px; } diff --git a/ui/packages/consul-ui/app/components/consul/external-source/index.scss b/ui/packages/consul-ui/app/components/consul/external-source/index.scss index 8cc460f164..b05acb45b2 100644 --- a/ui/packages/consul-ui/app/components/consul/external-source/index.scss +++ b/ui/packages/consul-ui/app/components/consul/external-source/index.scss @@ -1,3 +1,31 @@ .consul-external-source { @extend %pill-200, %frame-gray-600, %p1; } +.consul-external-source.kubernetes::before { + @extend %with-logo-kubernetes-color-icon, %as-pseudo; +} +.consul-external-source.terraform::before { + @extend %with-logo-terraform-color-icon, %as-pseudo; +} +.consul-external-source.nomad::before { + @extend %with-logo-nomad-color-icon, %as-pseudo; +} +.consul-external-source.consul::before, +.consul-external-source.consul-api-gateway::before { + @extend %with-logo-consul-color-icon, %as-pseudo; +} +.consul-external-source.vault::before { + @extend %with-vault-100; +} +.consul-external-source.aws::before { + @extend %with-aws-100; +} +.consul-external-source.leader::before { + @extend %with-star-outline-mask, %as-pseudo; +} +.consul-external-source.jwt::before { + @extend %with-logo-jwt-color-icon, %as-pseudo; +} +.consul-external-source.oidc::before { + @extend %with-logo-oidc-color-icon, %as-pseudo; +} diff --git a/ui/packages/consul-ui/app/components/consul/intention/components.scss b/ui/packages/consul-ui/app/components/consul/intention/components.scss index 59dfcd2fea..ed98c84994 100644 --- a/ui/packages/consul-ui/app/components/consul/intention/components.scss +++ b/ui/packages/consul-ui/app/components/consul/intention/components.scss @@ -1,9 +1,7 @@ %pill-allow::before, %pill-deny::before, %pill-l7::before { - @extend %as-pseudo; margin-right: 5px; - font-size: 0.9em; } %pill-allow, %pill-deny, @@ -24,11 +22,11 @@ @extend %frame-gray-900; } %pill-allow::before { - @extend %with-arrow-right-mask; + @extend %with-allow-300; } %pill-deny::before { - @extend %with-deny-color-mask; + @extend %with-deny-300; } %pill-l7::before { - @extend %with-layers-mask; + @extend %with-l7-300; } diff --git a/ui/packages/consul-ui/app/components/consul/intention/form/fieldsets/skin.scss b/ui/packages/consul-ui/app/components/consul/intention/form/fieldsets/skin.scss index 5057fc0420..242b593b0c 100644 --- a/ui/packages/consul-ui/app/components/consul/intention/form/fieldsets/skin.scss +++ b/ui/packages/consul-ui/app/components/consul/intention/form/fieldsets/skin.scss @@ -1,12 +1,11 @@ .consul-intention-fieldsets { .value-allow > :last-child::before { - @extend %with-arrow-right-mask, %as-pseudo; - color: rgb(var(--tone-green-500)); + @extend %with-allow-500; } .value-deny > :last-child::before { - @extend %with-deny-color-icon, %as-pseudo; + @extend %with-deny-500; } .value- > :last-child::before { - @extend %with-layers-mask, %as-pseudo; + @extend %with-l7-500; } } diff --git a/ui/packages/consul-ui/app/components/pill/index.scss b/ui/packages/consul-ui/app/components/pill/index.scss index 1ad95dfe86..f5a7642f2c 100644 --- a/ui/packages/consul-ui/app/components/pill/index.scss +++ b/ui/packages/consul-ui/app/components/pill/index.scss @@ -20,31 +20,3 @@ span.policy-node-identity::before { span.policy-service-identity::before { content: 'Service Identity: '; } -%pill.kubernetes::before { - @extend %with-logo-kubernetes-color-icon, %as-pseudo; -} -%pill.terraform::before { - @extend %with-logo-terraform-color-icon, %as-pseudo; -} -%pill.nomad::before { - @extend %with-logo-nomad-color-icon, %as-pseudo; -} -%pill.consul::before, -%pill.consul-api-gateway::before { - @extend %with-logo-consul-color-icon, %as-pseudo; -} -%pill.vault::before { - @extend %with-vault-300; -} -%pill.aws::before { - @extend %with-logo-aws-color-icon, %as-pseudo; -} -%pill.leader::before { - @extend %with-star-outline-mask, %as-pseudo; -} -%pill.jwt::before { - @extend %with-logo-jwt-color-icon, %as-pseudo; -} -%pill.oidc::before { - @extend %with-logo-oidc-color-icon, %as-pseudo; -} diff --git a/ui/packages/consul-ui/app/components/pill/layout.scss b/ui/packages/consul-ui/app/components/pill/layout.scss index 6b63f13d69..60b15f82ba 100644 --- a/ui/packages/consul-ui/app/components/pill/layout.scss +++ b/ui/packages/consul-ui/app/components/pill/layout.scss @@ -6,7 +6,8 @@ } %pill::before { margin-right: 4px; - font-size: 0.8em; + width: 0.75rem !important; /* 12px */ + height: 0.75rem !important; /* 12px */ } %pill-200 { @extend %pill; diff --git a/ui/packages/consul-ui/app/components/popover-select/index.scss b/ui/packages/consul-ui/app/components/popover-select/index.scss index a4fc7df8e9..badd21eb43 100644 --- a/ui/packages/consul-ui/app/components/popover-select/index.scss +++ b/ui/packages/consul-ui/app/components/popover-select/index.scss @@ -50,7 +50,7 @@ color: rgb(var(--tone-gray-500)); } %popover-select .aws button::before { - @extend %with-logo-aws-color-icon, %as-pseudo; + @extend %with-aws-300; } %popover-select .kubernetes button::before { @extend %with-logo-kubernetes-color-icon, %as-pseudo; diff --git a/ui/packages/consul-ui/app/styles/base/icons/base-placeholders.scss b/ui/packages/consul-ui/app/styles/base/icons/base-placeholders.scss index c659f53745..e15efe3aa5 100644 --- a/ui/packages/consul-ui/app/styles/base/icons/base-placeholders.scss +++ b/ui/packages/consul-ui/app/styles/base/icons/base-placeholders.scss @@ -1,3 +1,11 @@ +%theme-light { + --theme-dark-none: ; + --theme-light-none: initial; +} +%theme-dark { + --theme-dark-none: initial; + --theme-light-none: ; +} %with-icon { background-repeat: no-repeat; background-position: center; @@ -20,8 +28,8 @@ content: ''; visibility: visible; background-size: contain; - width: 1.2em; - height: 1.2em; + width: 1rem; /* 16px */ + height: 1rem; /* 16px */ vertical-align: text-top; } %led-icon { diff --git a/ui/packages/consul-ui/app/styles/base/icons/base-variables.scss b/ui/packages/consul-ui/app/styles/base/icons/base-variables.scss index 70a4e386e6..6be0782563 100644 --- a/ui/packages/consul-ui/app/styles/base/icons/base-variables.scss +++ b/ui/packages/consul-ui/app/styles/base/icons/base-variables.scss @@ -1,893 +1,949 @@ %activity-16-svg-prop { - --activity-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --activity-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %activity-24-svg-prop { - --activity-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --activity-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-circle-16-svg-prop { - --alert-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-circle-24-svg-prop { - --alert-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-circle-fill-16-svg-prop { - --alert-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-circle-fill-24-svg-prop { - --alert-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-circle-fill-svg-prop { - --alert-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %alert-circle-16-svg-prop; } %alert-circle-outline-svg-prop { - --alert-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %alert-circle-16-svg-prop; } %alert-octagon-16-svg-prop { - --alert-octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-octagon-24-svg-prop { - --alert-octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-octagon-fill-16-svg-prop { - --alert-octagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-octagon-fill-24-svg-prop { - --alert-octagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-triangle-16-svg-prop { - --alert-triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-triangle-24-svg-prop { - --alert-triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-triangle-fill-16-svg-prop { - --alert-triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-triangle-fill-24-svg-prop { - --alert-triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alert-triangle-svg-prop { - --alert-triangle-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %alert-triangle-16-svg-prop; } %alibaba-16-svg-prop { - --alibaba-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alibaba-24-svg-prop { - --alibaba-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alibaba-color-16-svg-prop { - --alibaba-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %alibaba-color-24-svg-prop { - --alibaba-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-center-16-svg-prop { - --align-center-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-center-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-center-24-svg-prop { - --align-center-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-center-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-justify-16-svg-prop { - --align-justify-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-justify-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-justify-24-svg-prop { - --align-justify-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-justify-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-left-16-svg-prop { - --align-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-left-24-svg-prop { - --align-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-right-16-svg-prop { - --align-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %align-right-24-svg-prop { - --align-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%amazon-eks-16-svg-prop { + --amazon-eks-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%amazon-eks-24-svg-prop { + --amazon-eks-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%amazon-eks-color-16-svg-prop { + --amazon-eks-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%amazon-eks-color-24-svg-prop { + --amazon-eks-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %apple-16-svg-prop { - --apple-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %apple-24-svg-prop { - --apple-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %apple-color-16-svg-prop { - --apple-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %apple-color-24-svg-prop { - --apple-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %archive-16-svg-prop { - --archive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --archive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %archive-24-svg-prop { - --archive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --archive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-16-svg-prop { - --arrow-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-24-svg-prop { - --arrow-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-circle-16-svg-prop { - --arrow-down-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-circle-24-svg-prop { - --arrow-down-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-left-16-svg-prop { - --arrow-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-left-24-svg-prop { - --arrow-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-right-16-svg-prop { - --arrow-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-right-24-svg-prop { - --arrow-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-down-svg-prop { - --arrow-down-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %arrow-down-16-svg-prop; } %arrow-left-16-svg-prop { - --arrow-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-left-24-svg-prop { - --arrow-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-left-circle-16-svg-prop { - --arrow-left-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-left-circle-24-svg-prop { - --arrow-left-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-left-svg-prop { - --arrow-left-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %arrow-left-16-svg-prop; } %arrow-right-16-svg-prop { - --arrow-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-right-24-svg-prop { - --arrow-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-right-circle-16-svg-prop { - --arrow-right-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-right-circle-24-svg-prop { - --arrow-right-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-right-svg-prop { - --arrow-right-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %arrow-right-16-svg-prop; } %arrow-up-16-svg-prop { - --arrow-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-24-svg-prop { - --arrow-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-circle-16-svg-prop { - --arrow-up-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-circle-24-svg-prop { - --arrow-up-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-left-16-svg-prop { - --arrow-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-left-24-svg-prop { - --arrow-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-right-16-svg-prop { - --arrow-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-right-24-svg-prop { - --arrow-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %arrow-up-svg-prop { - --arrow-up-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %arrow-up-16-svg-prop; } %at-sign-16-svg-prop { - --at-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --at-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %at-sign-24-svg-prop { - --at-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --at-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auth0-16-svg-prop { - --auth0-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auth0-24-svg-prop { - --auth0-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auth0-color-16-svg-prop { - --auth0-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auth0-color-24-svg-prop { - --auth0-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auto-apply-16-svg-prop { - --auto-apply-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auto-apply-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %auto-apply-24-svg-prop { - --auto-apply-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auto-apply-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %award-16-svg-prop { - --award-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --award-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %award-24-svg-prop { - --award-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --award-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %aws-16-svg-prop { - --aws-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %aws-24-svg-prop { - --aws-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %aws-color-16-svg-prop { - --aws-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %aws-color-24-svg-prop { - --aws-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%aws-ec2-16-svg-prop { + --aws-ec2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%aws-ec2-24-svg-prop { + --aws-ec2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%aws-ec2-color-16-svg-prop { + --aws-ec2-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%aws-ec2-color-24-svg-prop { + --aws-ec2-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-16-svg-prop { - --azure-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-24-svg-prop { - --azure-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-color-16-svg-prop { - --azure-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-color-24-svg-prop { - --azure-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-devops-16-svg-prop { - --azure-devops-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-devops-24-svg-prop { - --azure-devops-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-devops-color-16-svg-prop { - --azure-devops-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %azure-devops-color-24-svg-prop { - --azure-devops-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%bank-vault-16-svg-prop { + --bank-vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%bank-vault-24-svg-prop { + --bank-vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bar-chart-16-svg-prop { - --bar-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bar-chart-24-svg-prop { - --bar-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bar-chart-alt-16-svg-prop { - --bar-chart-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bar-chart-alt-24-svg-prop { - --bar-chart-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %battery-16-svg-prop { - --battery-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %battery-24-svg-prop { - --battery-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %battery-charging-16-svg-prop { - --battery-charging-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-charging-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %battery-charging-24-svg-prop { - --battery-charging-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-charging-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %beaker-16-svg-prop { - --beaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --beaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %beaker-24-svg-prop { - --beaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --beaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-16-svg-prop { - --bell-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-24-svg-prop { - --bell-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-active-16-svg-prop { - --bell-active-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-active-24-svg-prop { - --bell-active-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-active-fill-16-svg-prop { - --bell-active-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-active-fill-24-svg-prop { - --bell-active-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-off-16-svg-prop { - --bell-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bell-off-24-svg-prop { - --bell-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bitbucket-16-svg-prop { - --bitbucket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bitbucket-24-svg-prop { - --bitbucket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bitbucket-color-16-svg-prop { - --bitbucket-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bitbucket-color-24-svg-prop { - --bitbucket-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bolt-svg-prop { - --bolt-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %zap-16-svg-prop; } %bookmark-16-svg-prop { - --bookmark-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-24-svg-prop { - --bookmark-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-add-16-svg-prop { - --bookmark-add-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-add-24-svg-prop { - --bookmark-add-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-add-fill-16-svg-prop { - --bookmark-add-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-add-fill-24-svg-prop { - --bookmark-add-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-fill-16-svg-prop { - --bookmark-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-fill-24-svg-prop { - --bookmark-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-remove-16-svg-prop { - --bookmark-remove-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-remove-24-svg-prop { - --bookmark-remove-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-remove-fill-16-svg-prop { - --bookmark-remove-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bookmark-remove-fill-24-svg-prop { - --bookmark-remove-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bottom-16-svg-prop { - --bottom-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bottom-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bottom-24-svg-prop { - --bottom-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bottom-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%boundary-16-svg-prop { + --boundary-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%boundary-24-svg-prop { + --boundary-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%boundary-color-16-svg-prop { + --boundary-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%boundary-color-24-svg-prop { + --boundary-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %box-16-svg-prop { - --box-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --box-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %box-24-svg-prop { - --box-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --box-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %box-check-fill-svg-prop { - --box-check-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %check-square-fill-16-svg-prop; } %box-outline-svg-prop { - --box-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %square-16-svg-prop; } %briefcase-16-svg-prop { - --briefcase-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --briefcase-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %briefcase-24-svg-prop { - --briefcase-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --briefcase-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %broadcast-svg-prop { - --broadcast-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %radio-16-svg-prop; } %bug-16-svg-prop { - --bug-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bug-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bug-24-svg-prop { - --bug-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bug-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %bug-svg-prop { - --bug-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bug-16-svg-prop; } %build-16-svg-prop { - --build-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --build-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %build-24-svg-prop { - --build-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --build-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %calendar-16-svg-prop { - --calendar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --calendar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %calendar-24-svg-prop { - --calendar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --calendar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %calendar-svg-prop { - --calendar-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %calendar-16-svg-prop; } %camera-16-svg-prop { - --camera-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %camera-24-svg-prop { - --camera-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %camera-off-16-svg-prop { - --camera-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %camera-off-24-svg-prop { - --camera-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cancel-circle-fill-svg-prop { - --cancel-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %x-circle-fill-16-svg-prop; } %cancel-circle-outline-svg-prop { - --cancel-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %x-circle-16-svg-prop; } %cancel-plain-svg-prop { - --cancel-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %x-16-svg-prop; } %cancel-square-fill-svg-prop { - --cancel-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %x-square-fill-16-svg-prop; } %cancel-square-outline-svg-prop { - --cancel-square-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %x-square-16-svg-prop; } %caret-16-svg-prop { - --caret-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --caret-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %caret-24-svg-prop { - --caret-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --caret-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %caret-down-svg-prop { - --caret-down-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %caret-16-svg-prop; } %caret-up-svg-prop { - --caret-up-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %chevron-up-16-svg-prop; } %cast-16-svg-prop { - --cast-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cast-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cast-24-svg-prop { - --cast-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cast-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %certificate-16-svg-prop { - --certificate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --certificate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %certificate-24-svg-prop { - --certificate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --certificate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-16-svg-prop { - --change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-24-svg-prop { - --change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-circle-16-svg-prop { - --change-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-circle-24-svg-prop { - --change-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-square-16-svg-prop { - --change-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %change-square-24-svg-prop { - --change-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-16-svg-prop { - --check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-24-svg-prop { - --check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-circle-16-svg-prop { - --check-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-circle-24-svg-prop { - --check-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-circle-fill-16-svg-prop { - --check-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-circle-fill-24-svg-prop { - --check-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-circle-fill-svg-prop { - --check-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %check-circle-fill-16-svg-prop; } %check-circle-outline-svg-prop { - --check-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %check-circle-16-svg-prop; } %check-diamond-16-svg-prop { - --check-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-diamond-24-svg-prop { - --check-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-diamond-fill-16-svg-prop { - --check-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-diamond-fill-24-svg-prop { - --check-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-hexagon-16-svg-prop { - --check-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-hexagon-24-svg-prop { - --check-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-hexagon-fill-16-svg-prop { - --check-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-hexagon-fill-24-svg-prop { - --check-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-plain-svg-prop { - --check-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %check-16-svg-prop; } %check-square-16-svg-prop { - --check-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-square-24-svg-prop { - --check-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-square-fill-16-svg-prop { - --check-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %check-square-fill-24-svg-prop { - --check-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-down-16-svg-prop { - --chevron-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-down-24-svg-prop { - --chevron-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-down-svg-prop { - --chevron-down-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %chevron-down-16-svg-prop; } %chevron-left-16-svg-prop { - --chevron-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-left-24-svg-prop { - --chevron-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-left-svg-prop { - --chevron-left-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %chevron-left-16-svg-prop; } %chevron-right-16-svg-prop { - --chevron-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-right-24-svg-prop { - --chevron-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-right-svg-prop { - --chevron-right-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %chevron-right-16-svg-prop; } %chevron-up-16-svg-prop { - --chevron-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-up-24-svg-prop { - --chevron-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevron-up-svg-prop { - --chevron-up-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %chevron-up-16-svg-prop; } %chevrons-down-16-svg-prop { - --chevrons-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-down-24-svg-prop { - --chevrons-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-left-16-svg-prop { - --chevrons-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-left-24-svg-prop { - --chevrons-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-right-16-svg-prop { - --chevrons-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-right-24-svg-prop { - --chevrons-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-up-16-svg-prop { - --chevrons-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %chevrons-up-24-svg-prop { - --chevrons-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-16-svg-prop { - --circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-24-svg-prop { - --circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-dot-16-svg-prop { - --circle-dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-dot-24-svg-prop { - --circle-dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-fill-16-svg-prop { - --circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-fill-24-svg-prop { - --circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-half-16-svg-prop { - --circle-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %circle-half-24-svg-prop { - --circle-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-16-svg-prop { - --clipboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-24-svg-prop { - --clipboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-checked-16-svg-prop { - --clipboard-checked-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-checked-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-checked-24-svg-prop { - --clipboard-checked-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-checked-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-copy-16-svg-prop { - --clipboard-copy-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-copy-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clipboard-copy-24-svg-prop { - --clipboard-copy-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-copy-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clock-16-svg-prop { - --clock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clock-24-svg-prop { - --clock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %clock-fill-svg-prop { - --clock-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %clock-16-svg-prop; } %clock-outline-svg-prop { - --clock-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %clock-16-svg-prop; } %cloud-16-svg-prop { - --cloud-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-24-svg-prop { - --cloud-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-check-16-svg-prop { - --cloud-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-check-24-svg-prop { - --cloud-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-cross-svg-prop { @@ -895,255 +951,287 @@ } %cloud-download-16-svg-prop { - --cloud-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-download-24-svg-prop { - --cloud-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-lightning-16-svg-prop { - --cloud-lightning-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lightning-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-lightning-24-svg-prop { - --cloud-lightning-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lightning-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-lock-16-svg-prop { - --cloud-lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-lock-24-svg-prop { - --cloud-lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-off-16-svg-prop { - --cloud-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-off-24-svg-prop { - --cloud-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-upload-16-svg-prop { - --cloud-upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-upload-24-svg-prop { - --cloud-upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-x-16-svg-prop { - --cloud-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cloud-x-24-svg-prop { - --cloud-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %code-16-svg-prop { - --code-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --code-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %code-24-svg-prop { - --code-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --code-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %code-svg-prop { - --code-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %code-16-svg-prop; +} + +%codepen-16-svg-prop { + --codepen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%codepen-24-svg-prop { + --codepen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%codepen-color-16-svg-prop { + --codepen-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%codepen-color-24-svg-prop { + --codepen-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %collections-16-svg-prop { - --collections-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --collections-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %collections-24-svg-prop { - --collections-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --collections-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %command-16-svg-prop { - --command-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --command-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %command-24-svg-prop { - --command-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --command-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %compass-16-svg-prop { - --compass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --compass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %compass-24-svg-prop { - --compass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --compass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %connection-16-svg-prop { - --connection-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %connection-24-svg-prop { - --connection-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %connection-gateway-16-svg-prop { - --connection-gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %connection-gateway-24-svg-prop { - --connection-gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %console-svg-prop { - --console-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %terminal-16-svg-prop; +} + +%consul-16-svg-prop { + --consul-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%consul-24-svg-prop { + --consul-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%consul-color-16-svg-prop { + --consul-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%consul-color-24-svg-prop { + --consul-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %copy-action-svg-prop { - --copy-action-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %clipboard-copy-16-svg-prop; } %copy-success-svg-prop { - --copy-success-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %clipboard-checked-16-svg-prop; } %corner-down-left-16-svg-prop { - --corner-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-down-left-24-svg-prop { - --corner-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-down-right-16-svg-prop { - --corner-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-down-right-24-svg-prop { - --corner-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-left-down-16-svg-prop { - --corner-left-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-left-down-24-svg-prop { - --corner-left-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-left-up-16-svg-prop { - --corner-left-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-left-up-24-svg-prop { - --corner-left-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-right-down-16-svg-prop { - --corner-right-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-right-down-24-svg-prop { - --corner-right-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-right-up-16-svg-prop { - --corner-right-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-right-up-24-svg-prop { - --corner-right-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-up-left-16-svg-prop { - --corner-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-up-left-24-svg-prop { - --corner-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-up-right-16-svg-prop { - --corner-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %corner-up-right-24-svg-prop { - --corner-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cpu-16-svg-prop { - --cpu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cpu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %cpu-24-svg-prop { - --cpu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cpu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %credit-card-16-svg-prop { - --credit-card-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --credit-card-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %credit-card-24-svg-prop { - --credit-card-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --credit-card-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %crop-16-svg-prop { - --crop-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crop-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %crop-24-svg-prop { - --crop-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crop-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %crosshair-16-svg-prop { - --crosshair-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crosshair-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %crosshair-24-svg-prop { - --crosshair-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crosshair-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dashboard-16-svg-prop { - --dashboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dashboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dashboard-24-svg-prop { - --dashboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dashboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %database-16-svg-prop { - --database-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --database-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %database-24-svg-prop { - --database-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --database-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %database-svg-prop { - --database-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %database-16-svg-prop; } %delay-16-svg-prop { - --delay-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delay-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %delay-24-svg-prop { - --delay-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delay-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %delay-svg-prop { - --delay-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %delay-16-svg-prop; } %delete-16-svg-prop { - --delete-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delete-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %delete-24-svg-prop { - --delete-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delete-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %deny-alt-svg-prop { - --deny-alt-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %skip-16-svg-prop; } %deny-color-svg-prop { @@ -1151,1075 +1239,1163 @@ } %deny-default-svg-prop { - --deny-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %skip-16-svg-prop; } %diamond-16-svg-prop { - --diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %diamond-24-svg-prop { - --diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %diamond-fill-16-svg-prop { - --diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %diamond-fill-24-svg-prop { - --diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %disabled-svg-prop { - --disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %skip-16-svg-prop; } %disc-16-svg-prop { - --disc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --disc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %disc-24-svg-prop { - --disc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --disc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %discussion-circle-16-svg-prop { - --discussion-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %discussion-circle-24-svg-prop { - --discussion-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %discussion-square-16-svg-prop { - --discussion-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %discussion-square-24-svg-prop { - --discussion-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docker-16-svg-prop { - --docker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docker-24-svg-prop { - --docker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docker-color-16-svg-prop { - --docker-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docker-color-24-svg-prop { - --docker-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-16-svg-prop { - --docs-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-24-svg-prop { - --docs-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-download-16-svg-prop { - --docs-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-download-24-svg-prop { - --docs-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-link-16-svg-prop { - --docs-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-link-24-svg-prop { - --docs-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %docs-svg-prop { - --docs-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %docs-link-16-svg-prop; } %dollar-sign-16-svg-prop { - --dollar-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dollar-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dollar-sign-24-svg-prop { - --dollar-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dollar-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dot-16-svg-prop { - --dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dot-24-svg-prop { - --dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dot-half-16-svg-prop { - --dot-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %dot-half-24-svg-prop { - --dot-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %download-16-svg-prop { - --download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %download-24-svg-prop { - --download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %download-svg-prop { - --download-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %download-16-svg-prop; } %droplet-16-svg-prop { - --droplet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --droplet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %droplet-24-svg-prop { - --droplet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --droplet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %duplicate-16-svg-prop { - --duplicate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --duplicate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %duplicate-24-svg-prop { - --duplicate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --duplicate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %edit-16-svg-prop { - --edit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --edit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %edit-24-svg-prop { - --edit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --edit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %edit-svg-prop { - --edit-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %edit-16-svg-prop; } %entry-point-16-svg-prop { - --entry-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --entry-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %entry-point-24-svg-prop { - --entry-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --entry-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %envelope-sealed-fill-svg-prop { - --envelope-sealed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %mail-16-svg-prop; } %envelope-sealed-outline-svg-prop { - --envelope-sealed-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %mail-16-svg-prop; } %envelope-unsealed--outline-svg-prop { - --envelope-unsealed--outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %mail-open-16-svg-prop; } %envelope-unsealed-fill-svg-prop { - --envelope-unsealed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %mail-open-16-svg-prop; } %event-16-svg-prop { - --event-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --event-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %event-24-svg-prop { - --event-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --event-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %exit-point-16-svg-prop { - --exit-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --exit-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %exit-point-24-svg-prop { - --exit-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --exit-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %exit-svg-prop { - --exit-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %external-link-16-svg-prop; } %expand-less-svg-prop { - --expand-less-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %minimize-16-svg-prop; } %expand-more-svg-prop { - --expand-more-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %maximize-16-svg-prop; } %external-link-16-svg-prop { - --external-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --external-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %external-link-24-svg-prop { - --external-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --external-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %eye-16-svg-prop { - --eye-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %eye-24-svg-prop { - --eye-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %eye-off-16-svg-prop { - --eye-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %eye-off-24-svg-prop { - --eye-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %f5-16-svg-prop { - --f5-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %f5-24-svg-prop { - --f5-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %f5-color-16-svg-prop { - --f5-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %f5-color-24-svg-prop { - --f5-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%facebook-16-svg-prop { + --facebook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%facebook-24-svg-prop { + --facebook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%facebook-color-16-svg-prop { + --facebook-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%facebook-color-24-svg-prop { + --facebook-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %fast-forward-16-svg-prop { - --fast-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fast-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %fast-forward-24-svg-prop { - --fast-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fast-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-16-svg-prop { - --file-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-24-svg-prop { - --file-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-change-16-svg-prop { - --file-change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-change-24-svg-prop { - --file-change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-check-16-svg-prop { - --file-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-check-24-svg-prop { - --file-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-diff-16-svg-prop { - --file-diff-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-diff-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-diff-24-svg-prop { - --file-diff-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-diff-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-fill-svg-prop { - --file-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %file-16-svg-prop; } %file-minus-16-svg-prop { - --file-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-minus-24-svg-prop { - --file-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-outline-svg-prop { - --file-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %file-16-svg-prop; } %file-plus-16-svg-prop { - --file-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-plus-24-svg-prop { - --file-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-source-16-svg-prop { - --file-source-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-source-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-source-24-svg-prop { - --file-source-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-source-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-text-16-svg-prop { - --file-text-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-text-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-text-24-svg-prop { - --file-text-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-text-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-x-16-svg-prop { - --file-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %file-x-24-svg-prop { - --file-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %files-16-svg-prop { - --files-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --files-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %files-24-svg-prop { - --files-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --files-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %film-16-svg-prop { - --film-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --film-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %film-24-svg-prop { - --film-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --film-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-16-svg-prop { - --filter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-24-svg-prop { - --filter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-circle-16-svg-prop { - --filter-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-circle-24-svg-prop { - --filter-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-fill-16-svg-prop { - --filter-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-fill-24-svg-prop { - --filter-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %filter-svg-prop { - --filter-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %filter-16-svg-prop; } %fingerprint-16-svg-prop { - --fingerprint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fingerprint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %fingerprint-24-svg-prop { - --fingerprint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fingerprint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %flag-16-svg-prop { - --flag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --flag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %flag-24-svg-prop { - --flag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --flag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %flag-svg-prop { - --flag-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %flag-16-svg-prop; } %folder-16-svg-prop { - --folder-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-24-svg-prop { - --folder-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-fill-16-svg-prop { - --folder-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-fill-24-svg-prop { - --folder-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-fill-svg-prop { - --folder-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %folder-fill-16-svg-prop; } %folder-minus-16-svg-prop { - --folder-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-minus-24-svg-prop { - --folder-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-minus-fill-16-svg-prop { - --folder-minus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-minus-fill-24-svg-prop { - --folder-minus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-outline-svg-prop { - --folder-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %folder-16-svg-prop; } %folder-plus-16-svg-prop { - --folder-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-plus-24-svg-prop { - --folder-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-plus-fill-16-svg-prop { - --folder-plus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-plus-fill-24-svg-prop { - --folder-plus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-star-16-svg-prop { - --folder-star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-star-24-svg-prop { - --folder-star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-users-16-svg-prop { - --folder-users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %folder-users-24-svg-prop { - --folder-users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %frown-16-svg-prop { - --frown-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --frown-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %frown-24-svg-prop { - --frown-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --frown-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gateway-16-svg-prop { - --gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gateway-24-svg-prop { - --gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gateway-svg-prop { - --gateway-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gateway-16-svg-prop; } %gcp-16-svg-prop { - --gcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gcp-24-svg-prop { - --gcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gcp-color-16-svg-prop { - --gcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gcp-color-24-svg-prop { - --gcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gift-16-svg-prop { - --gift-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gift-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gift-24-svg-prop { - --gift-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gift-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gift-fill-svg-prop { - --gift-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gift-16-svg-prop; } %gift-outline-svg-prop { - --gift-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gift-16-svg-prop; } %git-branch-16-svg-prop { - --git-branch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-branch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-branch-24-svg-prop { - --git-branch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-branch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-branch-svg-prop { - --git-branch-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %git-branch-16-svg-prop; } %git-commit-16-svg-prop { - --git-commit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-commit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-commit-24-svg-prop { - --git-commit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-commit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-commit-svg-prop { - --git-commit-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %git-commit-16-svg-prop; } %git-merge-16-svg-prop { - --git-merge-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-merge-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-merge-24-svg-prop { - --git-merge-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-merge-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-pull-request-16-svg-prop { - --git-pull-request-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-pull-request-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-pull-request-24-svg-prop { - --git-pull-request-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-pull-request-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-pull-request-svg-prop { - --git-pull-request-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %git-pull-request-16-svg-prop; } %git-repo-16-svg-prop { - --git-repo-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-repo-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-repo-24-svg-prop { - --git-repo-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-repo-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %git-repository-svg-prop { - --git-repository-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %git-repo-16-svg-prop; } %github-16-svg-prop { - --github-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %github-24-svg-prop { - --github-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %github-color-16-svg-prop { - --github-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %github-color-24-svg-prop { - --github-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gitlab-16-svg-prop { - --gitlab-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gitlab-24-svg-prop { - --gitlab-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gitlab-color-16-svg-prop { - --gitlab-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %gitlab-color-24-svg-prop { - --gitlab-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %globe-16-svg-prop { - --globe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %globe-24-svg-prop { - --globe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %globe-private-16-svg-prop { - --globe-private-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-private-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %globe-private-24-svg-prop { - --globe-private-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-private-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %google-16-svg-prop { - --google-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %google-24-svg-prop { - --google-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %google-color-16-svg-prop { - --google-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %google-color-24-svg-prop { - --google-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %grid-16-svg-prop { - --grid-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %grid-24-svg-prop { - --grid-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %grid-alt-16-svg-prop { - --grid-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %grid-alt-24-svg-prop { - --grid-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %guide-16-svg-prop { - --guide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %guide-24-svg-prop { - --guide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %guide-link-16-svg-prop { - --guide-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %guide-link-24-svg-prop { - --guide-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %guide-svg-prop { - --guide-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %guide-16-svg-prop; } %hammer-16-svg-prop { - --hammer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hammer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hammer-24-svg-prop { - --hammer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hammer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%handshake-16-svg-prop { + --handshake-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%handshake-24-svg-prop { + --handshake-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hard-drive-16-svg-prop { - --hard-drive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hard-drive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hard-drive-24-svg-prop { - --hard-drive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hard-drive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hash-16-svg-prop { - --hash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hash-24-svg-prop { - --hash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hashicorp-16-svg-prop { + --hashicorp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hashicorp-24-svg-prop { + --hashicorp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hashicorp-color-16-svg-prop { + --hashicorp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hashicorp-color-24-svg-prop { + --hashicorp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hcp-16-svg-prop { + --hcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hcp-24-svg-prop { + --hcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hcp-color-16-svg-prop { + --hcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%hcp-color-24-svg-prop { + --hcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %headphones-16-svg-prop { - --headphones-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --headphones-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %headphones-24-svg-prop { - --headphones-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --headphones-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %health-svg-prop { - --health-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %activity-16-svg-prop; } %heart-16-svg-prop { - --heart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %heart-24-svg-prop { - --heart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %heart-fill-16-svg-prop { - --heart-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %heart-fill-24-svg-prop { - --heart-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %heart-off-16-svg-prop { - --heart-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %heart-off-24-svg-prop { - --heart-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %help-16-svg-prop { - --help-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --help-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %help-24-svg-prop { - --help-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --help-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %help-circle-fill-svg-prop { - --help-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %help-16-svg-prop; } %help-circle-outline-svg-prop { - --help-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %help-16-svg-prop; } %hexagon-16-svg-prop { - --hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hexagon-24-svg-prop { - --hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hexagon-fill-16-svg-prop { - --hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hexagon-fill-24-svg-prop { - --hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %history-16-svg-prop { - --history-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --history-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %history-24-svg-prop { - --history-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --history-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %history-svg-prop { - --history-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %history-16-svg-prop; } %home-16-svg-prop { - --home-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --home-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %home-24-svg-prop { - --home-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --home-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hourglass-16-svg-prop { - --hourglass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hourglass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %hourglass-24-svg-prop { - --hourglass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hourglass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %identity-service-16-svg-prop { - --identity-service-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-service-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %identity-service-24-svg-prop { - --identity-service-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-service-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %identity-user-16-svg-prop { - --identity-user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %identity-user-24-svg-prop { - --identity-user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %image-16-svg-prop { - --image-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --image-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %image-24-svg-prop { - --image-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --image-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %inbox-16-svg-prop { - --inbox-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --inbox-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %inbox-24-svg-prop { - --inbox-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --inbox-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %info-16-svg-prop { - --info-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --info-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %info-24-svg-prop { - --info-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --info-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %info-circle-fill-svg-prop { - --info-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %info-16-svg-prop; } %info-circle-outline-svg-prop { - --info-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %info-16-svg-prop; } %jump-link-16-svg-prop { - --jump-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --jump-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %jump-link-24-svg-prop { - --jump-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --jump-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %key-16-svg-prop { - --key-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %key-24-svg-prop { - --key-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %key-values-16-svg-prop { - --key-values-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-values-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %key-values-24-svg-prop { - --key-values-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-values-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %key-svg-prop { - --key-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %key-16-svg-prop; +} + +%keychain-16-svg-prop { + --keychain-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%keychain-24-svg-prop { + --keychain-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %kubernetes-16-svg-prop { - --kubernetes-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %kubernetes-24-svg-prop { - --kubernetes-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %kubernetes-color-16-svg-prop { - --kubernetes-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %kubernetes-color-24-svg-prop { - --kubernetes-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %labyrinth-16-svg-prop { - --labyrinth-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --labyrinth-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %labyrinth-24-svg-prop { - --labyrinth-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --labyrinth-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %layers-16-svg-prop { - --layers-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layers-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %layers-24-svg-prop { - --layers-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layers-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %layers-svg-prop { - --layers-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %layers-16-svg-prop; } %layout-16-svg-prop { - --layout-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layout-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %layout-24-svg-prop { - --layout-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layout-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %learn-16-svg-prop { - --learn-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %learn-24-svg-prop { - --learn-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %learn-link-16-svg-prop { - --learn-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %learn-link-24-svg-prop { - --learn-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %learn-svg-prop { - --learn-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %learn-16-svg-prop; } %line-chart-16-svg-prop { - --line-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %line-chart-24-svg-prop { - --line-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %line-chart-up-16-svg-prop { - --line-chart-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %line-chart-up-24-svg-prop { - --line-chart-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %link-16-svg-prop { - --link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %link-24-svg-prop { - --link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %link-svg-prop { - --link-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %link-16-svg-prop; +} + +%linkedin-16-svg-prop { + --linkedin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%linkedin-24-svg-prop { + --linkedin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%linkedin-color-16-svg-prop { + --linkedin-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%linkedin-color-24-svg-prop { + --linkedin-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %list-16-svg-prop { - --list-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --list-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %list-24-svg-prop { - --list-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --list-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%load-balancer-16-svg-prop { + --load-balancer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%load-balancer-24-svg-prop { + --load-balancer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %loading-svg-prop { - --loading-svg: url('data:image/svg+xml;charset=UTF-8,'); + --loading-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-16-svg-prop { - --lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-24-svg-prop { - --lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-closed-fill-svg-prop { - --lock-closed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %lock-fill-16-svg-prop; } %lock-closed-outline-svg-prop { - --lock-closed-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %lock-16-svg-prop; } %lock-closed-svg-prop { - --lock-closed-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %lock-fill-16-svg-prop; } %lock-disabled-svg-prop { - --lock-disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %lock-off-16-svg-prop; } %lock-fill-16-svg-prop { - --lock-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-fill-24-svg-prop { - --lock-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-off-16-svg-prop { - --lock-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-off-24-svg-prop { - --lock-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %lock-open-svg-prop { - --lock-open-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %unlock-16-svg-prop; } %logo-alicloud-color-svg-prop { - --logo-alicloud-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %alibaba-color-16-svg-prop; } %logo-alicloud-monochrome-svg-prop { - --logo-alicloud-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %alibaba-16-svg-prop; } %logo-auth0-color-svg-prop { - --logo-auth0-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %auth0-color-16-svg-prop; } %logo-aws-color-svg-prop { - --logo-aws-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %aws-color-16-svg-prop; } %logo-aws-monochrome-svg-prop { - --logo-aws-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %aws-16-svg-prop; } %logo-azure-color-svg-prop { - --logo-azure-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %azure-color-16-svg-prop; } %logo-azure-dev-ops-color-svg-prop { - --logo-azure-dev-ops-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %azure-devops-color-16-svg-prop; } %logo-azure-dev-ops-monochrome-svg-prop { - --logo-azure-dev-ops-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %azure-devops-16-svg-prop; } %logo-azure-monochrome-svg-prop { - --logo-azure-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %azure-16-svg-prop; } %logo-bitbucket-color-svg-prop { - --logo-bitbucket-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bitbucket-color-16-svg-prop; } %logo-bitbucket-monochrome-svg-prop { - --logo-bitbucket-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bitbucket-16-svg-prop; } %logo-consul-color-svg-prop { - --logo-consul-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %consul-color-16-svg-prop; } %logo-ember-circle-color-svg-prop { @@ -2227,27 +2403,27 @@ } %logo-gcp-color-svg-prop { - --logo-gcp-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gcp-color-16-svg-prop; } %logo-gcp-monochrome-svg-prop { - --logo-gcp-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gcp-16-svg-prop; } %logo-github-color-svg-prop { - --logo-github-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %github-color-16-svg-prop; } %logo-github-monochrome-svg-prop { - --logo-github-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %github-16-svg-prop; } %logo-gitlab-color-svg-prop { - --logo-gitlab-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gitlab-color-16-svg-prop; } %logo-gitlab-monochrome-svg-prop { - --logo-gitlab-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %gitlab-16-svg-prop; } %logo-glimmer-color-svg-prop { @@ -2255,11 +2431,11 @@ } %logo-google-color-svg-prop { - --logo-google-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %google-color-16-svg-prop; } %logo-google-monochrome-svg-prop { - --logo-google-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %google-16-svg-prop; } %logo-hashicorp-color-svg-prop { @@ -2271,19 +2447,19 @@ } %logo-kubernetes-color-svg-prop { - --logo-kubernetes-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %kubernetes-color-16-svg-prop; } %logo-kubernetes-monochrome-svg-prop { - --logo-kubernetes-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %kubernetes-16-svg-prop; } %logo-microsoft-color-svg-prop { - --logo-microsoft-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %microsoft-color-16-svg-prop; } %logo-nomad-color-svg-prop { - --logo-nomad-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %nomad-color-16-svg-prop; } %logo-oidc-color-svg-prop { @@ -2291,27 +2467,27 @@ } %logo-okta-color-svg-prop { - --logo-okta-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %okta-color-16-svg-prop; } %logo-oracle-color-svg-prop { - --logo-oracle-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %oracle-color-16-svg-prop; } %logo-oracle-monochrome-svg-prop { - --logo-oracle-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %oracle-16-svg-prop; } %logo-slack-color-svg-prop { - --logo-slack-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %slack-color-16-svg-prop; } %logo-slack-monochrome-svg-prop { - --logo-slack-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %slack-16-svg-prop; } %logo-terraform-color-svg-prop { - --logo-terraform-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %terraform-color-16-svg-prop; } %logo-vault-color-svg-prop { @@ -2319,619 +2495,675 @@ } %logo-vmware-color-svg-prop { - --logo-vmware-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %vmware-color-16-svg-prop; } %logo-vmware-monochrome-svg-prop { - --logo-vmware-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %vmware-16-svg-prop; } %mail-16-svg-prop { - --mail-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mail-24-svg-prop { - --mail-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mail-open-16-svg-prop { - --mail-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mail-open-24-svg-prop { - --mail-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%mainframe-16-svg-prop { + --mainframe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%mainframe-24-svg-prop { + --mainframe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %map-16-svg-prop { - --map-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %map-24-svg-prop { - --map-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %map-pin-16-svg-prop { - --map-pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %map-pin-24-svg-prop { - --map-pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %maximize-16-svg-prop { - --maximize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %maximize-24-svg-prop { - --maximize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %maximize-alt-16-svg-prop { - --maximize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %maximize-alt-24-svg-prop { - --maximize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %meh-16-svg-prop { - --meh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --meh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %meh-24-svg-prop { - --meh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --meh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %menu-16-svg-prop { - --menu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --menu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %menu-24-svg-prop { - --menu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --menu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %menu-svg-prop { - --menu-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %menu-16-svg-prop; } %mesh-16-svg-prop { - --mesh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mesh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mesh-24-svg-prop { - --mesh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mesh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mesh-svg-prop { - --mesh-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %mesh-16-svg-prop; } %message-circle-16-svg-prop { - --message-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-circle-24-svg-prop { - --message-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-circle-fill-16-svg-prop { - --message-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-circle-fill-24-svg-prop { - --message-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-square-16-svg-prop { - --message-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-square-24-svg-prop { - --message-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-square-fill-16-svg-prop { - --message-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-square-fill-24-svg-prop { - --message-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %message-svg-prop { - --message-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %message-square-fill-16-svg-prop; } %mic-16-svg-prop { - --mic-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mic-24-svg-prop { - --mic-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mic-off-16-svg-prop { - --mic-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mic-off-24-svg-prop { - --mic-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %microsoft-16-svg-prop { - --microsoft-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %microsoft-24-svg-prop { - --microsoft-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %microsoft-color-16-svg-prop { - --microsoft-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %microsoft-color-24-svg-prop { - --microsoft-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %migrate-16-svg-prop { - --migrate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --migrate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %migrate-24-svg-prop { - --migrate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --migrate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minimize-16-svg-prop { - --minimize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minimize-24-svg-prop { - --minimize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minimize-alt-16-svg-prop { - --minimize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minimize-alt-24-svg-prop { - --minimize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-16-svg-prop { - --minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-24-svg-prop { - --minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-circle-16-svg-prop { - --minus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-circle-24-svg-prop { - --minus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-circle-fill-svg-prop { - --minus-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %minus-circle-16-svg-prop; } %minus-circle-outline-svg-prop { - --minus-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %minus-circle-16-svg-prop; } %minus-plain-svg-prop { - --minus-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %minus-16-svg-prop; } %minus-plus-16-svg-prop { - --minus-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-plus-24-svg-prop { - --minus-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-plus-circle-16-svg-prop { - --minus-plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-plus-circle-24-svg-prop { - --minus-plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-plus-square-16-svg-prop { - --minus-plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-plus-square-24-svg-prop { - --minus-plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-square-16-svg-prop { - --minus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-square-24-svg-prop { - --minus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %minus-square-fill-svg-prop { - --minus-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %minus-square-16-svg-prop; } %module-16-svg-prop { - --module-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --module-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %module-24-svg-prop { - --module-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --module-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %module-svg-prop { - --module-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %module-16-svg-prop; } %monitor-16-svg-prop { - --monitor-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --monitor-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %monitor-24-svg-prop { - --monitor-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --monitor-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %moon-16-svg-prop { - --moon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --moon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %moon-24-svg-prop { - --moon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --moon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %more-horizontal-16-svg-prop { - --more-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %more-horizontal-24-svg-prop { - --more-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %more-horizontal-svg-prop { - --more-horizontal-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %more-horizontal-16-svg-prop; } %more-vertical-16-svg-prop { - --more-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %more-vertical-24-svg-prop { - --more-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %more-vertical-svg-prop { - --more-vertical-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %more-vertical-16-svg-prop; } %mouse-pointer-16-svg-prop { - --mouse-pointer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mouse-pointer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %mouse-pointer-24-svg-prop { - --mouse-pointer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mouse-pointer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %move-16-svg-prop { - --move-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --move-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %move-24-svg-prop { - --move-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --move-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %music-16-svg-prop { - --music-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --music-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %music-24-svg-prop { - --music-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --music-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %navigation-16-svg-prop { - --navigation-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %navigation-24-svg-prop { - --navigation-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %navigation-alt-16-svg-prop { - --navigation-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %navigation-alt-24-svg-prop { - --navigation-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %network-16-svg-prop { - --network-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %network-24-svg-prop { - --network-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %network-alt-16-svg-prop { - --network-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %network-alt-24-svg-prop { - --network-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %newspaper-16-svg-prop { - --newspaper-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --newspaper-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %newspaper-24-svg-prop { - --newspaper-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --newspaper-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %node-16-svg-prop { - --node-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --node-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %node-24-svg-prop { - --node-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --node-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%nomad-16-svg-prop { + --nomad-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%nomad-24-svg-prop { + --nomad-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%nomad-color-16-svg-prop { + --nomad-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%nomad-color-24-svg-prop { + --nomad-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %notification-disabled-svg-prop { - --notification-disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bell-off-16-svg-prop; } %notification-fill-svg-prop { - --notification-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bell-active-fill-16-svg-prop; } %notification-outline-svg-prop { - --notification-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %bell-16-svg-prop; } %octagon-16-svg-prop { - --octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %octagon-24-svg-prop { - --octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %okta-16-svg-prop { - --okta-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %okta-24-svg-prop { - --okta-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %okta-color-16-svg-prop { - --okta-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %okta-color-24-svg-prop { - --okta-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %oracle-16-svg-prop { - --oracle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %oracle-24-svg-prop { - --oracle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %oracle-color-16-svg-prop { - --oracle-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %oracle-color-24-svg-prop { - --oracle-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %org-16-svg-prop { - --org-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --org-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %org-24-svg-prop { - --org-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --org-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %outline-16-svg-prop { - --outline-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --outline-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %outline-24-svg-prop { - --outline-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --outline-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %outline-svg-prop { - --outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %outline-16-svg-prop; +} + +%pack-16-svg-prop { + --pack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%pack-24-svg-prop { + --pack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%pack-color-16-svg-prop { + --pack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%pack-color-24-svg-prop { + --pack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %package-16-svg-prop { - --package-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --package-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %package-24-svg-prop { - --package-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --package-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%packer-16-svg-prop { + --packer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%packer-24-svg-prop { + --packer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%packer-color-16-svg-prop { + --packer-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%packer-color-24-svg-prop { + --packer-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %page-outline-svg-prop { - --page-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %outline-16-svg-prop; } %paperclip-16-svg-prop { - --paperclip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --paperclip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %paperclip-24-svg-prop { - --paperclip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --paperclip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %partner-svg-prop { - --partner-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %users-16-svg-prop; } %path-16-svg-prop { - --path-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --path-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %path-24-svg-prop { - --path-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --path-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %path-svg-prop { - --path-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %path-16-svg-prop; } %pause-16-svg-prop { - --pause-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pause-24-svg-prop { - --pause-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pause-circle-16-svg-prop { - --pause-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pause-circle-24-svg-prop { - --pause-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pen-tool-16-svg-prop { - --pen-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pen-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pen-tool-24-svg-prop { - --pen-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pen-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pencil-tool-16-svg-prop { - --pencil-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pencil-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pencil-tool-24-svg-prop { - --pencil-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pencil-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-16-svg-prop { - --phone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-24-svg-prop { - --phone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-call-16-svg-prop { - --phone-call-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-call-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-call-24-svg-prop { - --phone-call-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-call-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-off-16-svg-prop { - --phone-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %phone-off-24-svg-prop { - --phone-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pie-chart-16-svg-prop { - --pie-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pie-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pie-chart-24-svg-prop { - --pie-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pie-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pin-16-svg-prop { - --pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %pin-24-svg-prop { - --pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %play-16-svg-prop { - --play-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %play-24-svg-prop { - --play-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %play-circle-16-svg-prop { - --play-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %play-circle-24-svg-prop { - --play-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %play-fill-svg-prop { - --play-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %play-circle-16-svg-prop; } %play-outline-svg-prop { - --play-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %play-circle-16-svg-prop; } %play-plain-svg-prop { - --play-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %play-16-svg-prop; } %plus-16-svg-prop { - --plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-24-svg-prop { - --plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-circle-16-svg-prop { - --plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-circle-24-svg-prop { - --plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-circle-fill-svg-prop { - --plus-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %plus-circle-16-svg-prop; } %plus-circle-outline-svg-prop { - --plus-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %plus-circle-16-svg-prop; } %plus-plain-svg-prop { - --plus-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %plus-16-svg-prop; } %plus-square-16-svg-prop { - --plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-square-24-svg-prop { - --plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %plus-square-fill-svg-prop { - --plus-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %plus-square-16-svg-prop; } %port-svg-prop { @@ -2939,19 +3171,19 @@ } %power-16-svg-prop { - --power-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --power-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %power-24-svg-prop { - --power-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --power-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %printer-16-svg-prop { - --printer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --printer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %printer-24-svg-prop { - --printer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --printer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %protocol-svg-prop { @@ -2959,191 +3191,191 @@ } %provider-16-svg-prop { - --provider-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --provider-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %provider-24-svg-prop { - --provider-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --provider-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %provider-svg-prop { - --provider-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %provider-16-svg-prop; } %public-default-svg-prop { - --public-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %globe-16-svg-prop; } %public-locked-svg-prop { - --public-locked-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %globe-private-16-svg-prop; } %queue-16-svg-prop { - --queue-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --queue-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %queue-24-svg-prop { - --queue-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --queue-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %queue-svg-prop { - --queue-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %queue-16-svg-prop; } %radio-16-svg-prop { - --radio-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --radio-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %radio-24-svg-prop { - --radio-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --radio-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %radio-button-checked-svg-prop { - --radio-button-checked-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %circle-dot-16-svg-prop; } %radio-button-unchecked-svg-prop { - --radio-button-unchecked-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %circle-16-svg-prop; } %random-16-svg-prop { - --random-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --random-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %random-24-svg-prop { - --random-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --random-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %random-svg-prop { - --random-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %random-16-svg-prop; } %redirect-16-svg-prop { - --redirect-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --redirect-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %redirect-24-svg-prop { - --redirect-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --redirect-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %redirect-svg-prop { - --redirect-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %redirect-16-svg-prop; } %refresh-alert-svg-prop { - --refresh-alert-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %sync-alert-16-svg-prop; } %refresh-default-svg-prop { - --refresh-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %sync-16-svg-prop; } %reload-16-svg-prop { - --reload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --reload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %reload-24-svg-prop { - --reload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --reload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %remix-svg-prop { - --remix-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %shuffle-16-svg-prop; } %repeat-16-svg-prop { - --repeat-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --repeat-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %repeat-24-svg-prop { - --repeat-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --repeat-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %replication-direct-16-svg-prop { - --replication-direct-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-direct-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %replication-direct-24-svg-prop { - --replication-direct-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-direct-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %replication-perf-16-svg-prop { - --replication-perf-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-perf-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %replication-perf-24-svg-prop { - --replication-perf-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-perf-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rewind-16-svg-prop { - --rewind-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rewind-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rewind-24-svg-prop { - --rewind-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rewind-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %ribbon-svg-prop { - --ribbon-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %award-16-svg-prop; } %rocket-16-svg-prop { - --rocket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rocket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rocket-24-svg-prop { - --rocket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rocket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rotate-ccw-16-svg-prop { - --rotate-ccw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-ccw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rotate-ccw-24-svg-prop { - --rotate-ccw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-ccw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rotate-cw-16-svg-prop { - --rotate-cw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-cw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rotate-cw-24-svg-prop { - --rotate-cw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-cw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rss-16-svg-prop { - --rss-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rss-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %rss-24-svg-prop { - --rss-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rss-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %run-svg-prop { - --run-svg: url('data:image/svg+xml;charset=UTF-8,'); + --run-svg: url('data:image/svg+xml;charset=UTF-8,'); } %save-16-svg-prop { - --save-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --save-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %save-24-svg-prop { - --save-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --save-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %scissors-16-svg-prop { - --scissors-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --scissors-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %scissors-24-svg-prop { - --scissors-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --scissors-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %search-16-svg-prop { - --search-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --search-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %search-24-svg-prop { - --search-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --search-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %search-color-svg-prop { @@ -3151,251 +3383,251 @@ } %search-svg-prop { - --search-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %search-16-svg-prop; } %send-16-svg-prop { - --send-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --send-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %send-24-svg-prop { - --send-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --send-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %server-16-svg-prop { - --server-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %server-24-svg-prop { - --server-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %server-cluster-16-svg-prop { - --server-cluster-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-cluster-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %server-cluster-24-svg-prop { - --server-cluster-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-cluster-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %serverless-16-svg-prop { - --serverless-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --serverless-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %serverless-24-svg-prop { - --serverless-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --serverless-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %settings-16-svg-prop { - --settings-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --settings-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %settings-24-svg-prop { - --settings-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --settings-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %settings-svg-prop { - --settings-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %settings-16-svg-prop; } %share-16-svg-prop { - --share-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --share-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %share-24-svg-prop { - --share-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --share-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-16-svg-prop { - --shield-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-24-svg-prop { - --shield-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-alert-16-svg-prop { - --shield-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-alert-24-svg-prop { - --shield-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-check-16-svg-prop { - --shield-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-check-24-svg-prop { - --shield-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-off-16-svg-prop { - --shield-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-off-24-svg-prop { - --shield-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-x-16-svg-prop { - --shield-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shield-x-24-svg-prop { - --shield-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shopping-bag-16-svg-prop { - --shopping-bag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-bag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shopping-bag-24-svg-prop { - --shopping-bag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-bag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shopping-cart-16-svg-prop { - --shopping-cart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-cart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shopping-cart-24-svg-prop { - --shopping-cart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-cart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shuffle-16-svg-prop { - --shuffle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shuffle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %shuffle-24-svg-prop { - --shuffle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shuffle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-16-svg-prop { - --sidebar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-24-svg-prop { - --sidebar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-hide-16-svg-prop { - --sidebar-hide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-hide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-hide-24-svg-prop { - --sidebar-hide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-hide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-show-16-svg-prop { - --sidebar-show-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-show-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sidebar-show-24-svg-prop { - --sidebar-show-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-show-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sign-in-16-svg-prop { - --sign-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sign-in-24-svg-prop { - --sign-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sign-out-16-svg-prop { - --sign-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sign-out-24-svg-prop { - --sign-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-16-svg-prop { - --skip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-24-svg-prop { - --skip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-back-16-svg-prop { - --skip-back-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-back-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-back-24-svg-prop { - --skip-back-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-back-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-forward-16-svg-prop { - --skip-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %skip-forward-24-svg-prop { - --skip-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slack-16-svg-prop { - --slack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slack-24-svg-prop { - --slack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slack-color-16-svg-prop { - --slack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slack-color-24-svg-prop { - --slack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slash-16-svg-prop { - --slash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slash-24-svg-prop { - --slash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slash-square-16-svg-prop { - --slash-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %slash-square-24-svg-prop { - --slash-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sliders-16-svg-prop { - --sliders-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sliders-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sliders-24-svg-prop { - --sliders-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sliders-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %smartphone-16-svg-prop { - --smartphone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smartphone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %smartphone-24-svg-prop { - --smartphone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smartphone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %smile-16-svg-prop { - --smile-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smile-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %smile-24-svg-prop { - --smile-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smile-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %socket-16-svg-prop { - --socket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --socket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %socket-24-svg-prop { - --socket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --socket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %socket-svg-prop { @@ -3403,733 +3635,837 @@ } %sort-asc-16-svg-prop { - --sort-asc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-asc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sort-asc-24-svg-prop { - --sort-asc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-asc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sort-desc-16-svg-prop { - --sort-desc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-desc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sort-desc-24-svg-prop { - --sort-desc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-desc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sort-svg-prop { - --sort-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %sort-desc-16-svg-prop; } %source-file-svg-prop { - --source-file-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %file-source-16-svg-prop; } %speaker-16-svg-prop { - --speaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --speaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %speaker-24-svg-prop { - --speaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --speaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %square-16-svg-prop { - --square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %square-24-svg-prop { - --square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %square-fill-16-svg-prop { - --square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %square-fill-24-svg-prop { - --square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-16-svg-prop { - --star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-24-svg-prop { - --star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-circle-16-svg-prop { - --star-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-circle-24-svg-prop { - --star-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-fill-16-svg-prop { - --star-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-fill-24-svg-prop { - --star-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-fill-svg-prop { - --star-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %star-fill-16-svg-prop; } %star-off-16-svg-prop { - --star-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-off-24-svg-prop { - --star-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %star-outline-svg-prop { - --star-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %star-16-svg-prop; } %stop-circle-16-svg-prop { - --stop-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --stop-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %stop-circle-24-svg-prop { - --stop-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --stop-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sub-left-svg-prop { - --sub-left-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %corner-down-left-16-svg-prop; } %sub-right-svg-prop { - --sub-right-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %corner-down-right-16-svg-prop; } %sun-16-svg-prop { - --sun-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sun-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sun-24-svg-prop { - --sun-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sun-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %support-16-svg-prop { - --support-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --support-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %support-24-svg-prop { - --support-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --support-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %support-svg-prop { - --support-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %support-16-svg-prop; } %swap-horizontal-16-svg-prop { - --swap-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %swap-horizontal-24-svg-prop { - --swap-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %swap-horizontal-svg-prop { - --swap-horizontal-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %swap-horizontal-16-svg-prop; } %swap-vertical-16-svg-prop { - --swap-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %swap-vertical-24-svg-prop { - --swap-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %swap-vertical-svg-prop { - --swap-vertical-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %swap-vertical-16-svg-prop; } %switcher-16-svg-prop { - --switcher-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --switcher-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %switcher-24-svg-prop { - --switcher-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --switcher-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-16-svg-prop { - --sync-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-24-svg-prop { - --sync-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-alert-16-svg-prop { - --sync-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-alert-24-svg-prop { - --sync-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-reverse-16-svg-prop { - --sync-reverse-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-reverse-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %sync-reverse-24-svg-prop { - --sync-reverse-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-reverse-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tablet-16-svg-prop { - --tablet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tablet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tablet-24-svg-prop { - --tablet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tablet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tag-16-svg-prop { - --tag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tag-24-svg-prop { - --tag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tag-svg-prop { - --tag-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %tag-16-svg-prop; } %target-16-svg-prop { - --target-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --target-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %target-24-svg-prop { - --target-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --target-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %terminal-16-svg-prop { - --terminal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %terminal-24-svg-prop { - --terminal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %terminal-screen-16-svg-prop { - --terminal-screen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-screen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %terminal-screen-24-svg-prop { - --terminal-screen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-screen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%terraform-16-svg-prop { + --terraform-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%terraform-24-svg-prop { + --terraform-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%terraform-color-16-svg-prop { + --terraform-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%terraform-color-24-svg-prop { + --terraform-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %thumbs-down-16-svg-prop { - --thumbs-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %thumbs-down-24-svg-prop { - --thumbs-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %thumbs-up-16-svg-prop { - --thumbs-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %thumbs-up-24-svg-prop { - --thumbs-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %toggle-left-16-svg-prop { - --toggle-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %toggle-left-24-svg-prop { - --toggle-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %toggle-right-16-svg-prop { - --toggle-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %toggle-right-24-svg-prop { - --toggle-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %token-16-svg-prop { - --token-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --token-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %token-24-svg-prop { - --token-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --token-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tools-16-svg-prop { - --tools-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tools-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tools-24-svg-prop { - --tools-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tools-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %top-16-svg-prop { - --top-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --top-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %top-24-svg-prop { - --top-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --top-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trash-16-svg-prop { - --trash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trash-24-svg-prop { - --trash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trash-svg-prop { - --trash-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %trash-16-svg-prop; } %trend-down-16-svg-prop { - --trend-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trend-down-24-svg-prop { - --trend-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trend-up-16-svg-prop { - --trend-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %trend-up-24-svg-prop { - --trend-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %triangle-16-svg-prop { - --triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %triangle-24-svg-prop { - --triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %triangle-fill-16-svg-prop { - --triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %triangle-fill-24-svg-prop { - --triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %truck-16-svg-prop { - --truck-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --truck-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %truck-24-svg-prop { - --truck-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --truck-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tune-svg-prop { - --tune-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %sliders-16-svg-prop; } %tv-16-svg-prop { - --tv-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tv-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %tv-24-svg-prop { - --tv-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tv-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitch-16-svg-prop { + --twitch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitch-24-svg-prop { + --twitch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitch-color-16-svg-prop { + --twitch-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitch-color-24-svg-prop { + --twitch-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitter-16-svg-prop { + --twitter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitter-24-svg-prop { + --twitter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitter-color-16-svg-prop { + --twitter-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%twitter-color-24-svg-prop { + --twitter-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %type-16-svg-prop { - --type-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --type-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %type-24-svg-prop { - --type-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --type-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unfold-close-16-svg-prop { - --unfold-close-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-close-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unfold-close-24-svg-prop { - --unfold-close-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-close-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unfold-less-svg-prop { - --unfold-less-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %unfold-close-16-svg-prop; } %unfold-more-svg-prop { - --unfold-more-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %unfold-open-16-svg-prop; } %unfold-open-16-svg-prop { - --unfold-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unfold-open-24-svg-prop { - --unfold-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } -%union-svg { - --union-svg: url('data:image/svg+xml;charset=UTF-8,'); +%union-svg-prop { + --union-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unlock-16-svg-prop { - --unlock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unlock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %unlock-24-svg-prop { - --unlock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unlock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %upload-16-svg-prop { - --upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %upload-24-svg-prop { - --upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %upload-svg-prop { - --upload-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %upload-16-svg-prop; } %user-16-svg-prop { - --user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-24-svg-prop { - --user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-add-svg-prop { - --user-add-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %user-plus-16-svg-prop; } %user-check-16-svg-prop { - --user-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-check-24-svg-prop { - --user-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-circle-16-svg-prop { - --user-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-circle-24-svg-prop { - --user-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-circle-fill-16-svg-prop { - --user-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-circle-fill-24-svg-prop { - --user-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-minus-16-svg-prop { - --user-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-minus-24-svg-prop { - --user-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-organization-svg-prop { - --user-organization-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %org-16-svg-prop; } %user-plain-svg-prop { - --user-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %user-16-svg-prop; } %user-plus-16-svg-prop { - --user-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-plus-24-svg-prop { - --user-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-square-fill-svg-prop { - --user-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %user-circle-fill-16-svg-prop; } %user-square-outline-svg-prop { - --user-square-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %user-circle-16-svg-prop; } %user-team-svg-prop { - --user-team-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %users-16-svg-prop; } %user-x-16-svg-prop { - --user-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %user-x-24-svg-prop { - --user-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %users-16-svg-prop { - --users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %users-24-svg-prop { - --users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vagrant-16-svg-prop { + --vagrant-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vagrant-24-svg-prop { + --vagrant-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vagrant-color-16-svg-prop { + --vagrant-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vagrant-color-24-svg-prop { + --vagrant-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %vault-16-svg-prop { - --vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %vault-24-svg-prop { - --vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vault-color-16-svg-prop { + --vault-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%vault-color-24-svg-prop { + --vault-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %verified-16-svg-prop { - --verified-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --verified-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %verified-24-svg-prop { - --verified-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --verified-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %video-16-svg-prop { - --video-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %video-24-svg-prop { - --video-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %video-off-16-svg-prop { - --video-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %video-off-24-svg-prop { - --video-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %visibility-hide-svg-prop { - --visibility-hide-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %eye-off-16-svg-prop; } %visibility-show-svg-prop { - --visibility-show-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %eye-16-svg-prop; } %vmware-16-svg-prop { - --vmware-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %vmware-24-svg-prop { - --vmware-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %vmware-color-16-svg-prop { - --vmware-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %vmware-color-24-svg-prop { - --vmware-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-16-svg-prop { - --volume-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-2-16-svg-prop { - --volume-2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-2-24-svg-prop { - --volume-2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-24-svg-prop { - --volume-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-down-16-svg-prop { - --volume-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-down-24-svg-prop { - --volume-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-x-16-svg-prop { - --volume-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %volume-x-24-svg-prop { - --volume-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wall-16-svg-prop { - --wall-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wall-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wall-24-svg-prop { - --wall-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wall-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %watch-16-svg-prop { - --watch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --watch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %watch-24-svg-prop { - --watch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --watch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%waypoint-16-svg-prop { + --waypoint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%waypoint-24-svg-prop { + --waypoint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%waypoint-color-16-svg-prop { + --waypoint-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%waypoint-color-24-svg-prop { + --waypoint-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %webhook-16-svg-prop { - --webhook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --webhook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %webhook-24-svg-prop { - --webhook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --webhook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %webhook-svg-prop { - --webhook-svg: url('data:image/svg+xml;charset=UTF-8,'); + @extend %webhook-16-svg-prop; } %wifi-16-svg-prop { - --wifi-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wifi-24-svg-prop { - --wifi-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wifi-off-16-svg-prop { - --wifi-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wifi-off-24-svg-prop { - --wifi-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wrench-16-svg-prop { - --wrench-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wrench-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %wrench-24-svg-prop { - --wrench-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wrench-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-16-svg-prop { - --x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-24-svg-prop { - --x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-circle-16-svg-prop { - --x-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-circle-24-svg-prop { - --x-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-circle-fill-16-svg-prop { - --x-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-circle-fill-24-svg-prop { - --x-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-diamond-16-svg-prop { - --x-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-diamond-24-svg-prop { - --x-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-diamond-fill-16-svg-prop { - --x-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-diamond-fill-24-svg-prop { - --x-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-hexagon-16-svg-prop { - --x-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-hexagon-24-svg-prop { - --x-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-hexagon-fill-16-svg-prop { - --x-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-hexagon-fill-24-svg-prop { - --x-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-square-16-svg-prop { - --x-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-square-24-svg-prop { - --x-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-square-fill-16-svg-prop { - --x-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %x-square-fill-24-svg-prop { - --x-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%youtube-16-svg-prop { + --youtube-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%youtube-24-svg-prop { + --youtube-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%youtube-color-16-svg-prop { + --youtube-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); +} + +%youtube-color-24-svg-prop { + --youtube-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zap-16-svg-prop { - --zap-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zap-24-svg-prop { - --zap-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zap-off-16-svg-prop { - --zap-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zap-off-24-svg-prop { - --zap-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zoom-in-16-svg-prop { - --zoom-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zoom-in-24-svg-prop { - --zoom-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zoom-out-16-svg-prop { - --zoom-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); } %zoom-out-24-svg-prop { - --zoom-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } diff --git a/ui/packages/consul-ui/app/styles/base/icons/debug.scss b/ui/packages/consul-ui/app/styles/base/icons/debug.scss index 8106bc04e3..16fe3c648d 100644 --- a/ui/packages/consul-ui/app/styles/base/icons/debug.scss +++ b/ui/packages/consul-ui/app/styles/base/icons/debug.scss @@ -1,4 +1,3 @@ - .debug-with-activity-16-mask-before::before, .debug-with-activity-16-icon-before::before, .debug-with-activity-16-mask-after::after, @@ -898,6 +897,130 @@ background-image: var(--align-right-24-svg); } +.debug-with-amazon-eks-16-mask-before::before, +.debug-with-amazon-eks-16-icon-before::before, +.debug-with-amazon-eks-16-mask-after::after, +.debug-with-amazon-eks-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-amazon-eks-16-mask-before::before, +.debug-with-amazon-eks-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--amazon-eks-16-svg); + mask-image: var(--amazon-eks-16-svg); +} +.debug-with-amazon-eks-16-icon-before::before, +.debug-with-amazon-eks-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--amazon-eks-16-svg); +} + +.debug-with-amazon-eks-24-mask-before::before, +.debug-with-amazon-eks-24-icon-before::before, +.debug-with-amazon-eks-24-mask-after::after, +.debug-with-amazon-eks-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-amazon-eks-24-mask-before::before, +.debug-with-amazon-eks-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--amazon-eks-24-svg); + mask-image: var(--amazon-eks-24-svg); +} +.debug-with-amazon-eks-24-icon-before::before, +.debug-with-amazon-eks-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--amazon-eks-24-svg); +} + +.debug-with-amazon-eks-color-16-mask-before::before, +.debug-with-amazon-eks-color-16-icon-before::before, +.debug-with-amazon-eks-color-16-mask-after::after, +.debug-with-amazon-eks-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-amazon-eks-color-16-mask-before::before, +.debug-with-amazon-eks-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--amazon-eks-color-16-svg); + mask-image: var(--amazon-eks-color-16-svg); +} +.debug-with-amazon-eks-color-16-icon-before::before, +.debug-with-amazon-eks-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--amazon-eks-color-16-svg); +} + +.debug-with-amazon-eks-color-24-mask-before::before, +.debug-with-amazon-eks-color-24-icon-before::before, +.debug-with-amazon-eks-color-24-mask-after::after, +.debug-with-amazon-eks-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-amazon-eks-color-24-mask-before::before, +.debug-with-amazon-eks-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--amazon-eks-color-24-svg); + mask-image: var(--amazon-eks-color-24-svg); +} +.debug-with-amazon-eks-color-24-icon-before::before, +.debug-with-amazon-eks-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--amazon-eks-color-24-svg); +} + .debug-with-apple-16-mask-before::before, .debug-with-apple-16-icon-before::before, .debug-with-apple-16-mask-after::after, @@ -2386,6 +2509,130 @@ background-image: var(--aws-color-24-svg); } +.debug-with-aws-ec2-16-mask-before::before, +.debug-with-aws-ec2-16-icon-before::before, +.debug-with-aws-ec2-16-mask-after::after, +.debug-with-aws-ec2-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-aws-ec2-16-mask-before::before, +.debug-with-aws-ec2-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--aws-ec2-16-svg); + mask-image: var(--aws-ec2-16-svg); +} +.debug-with-aws-ec2-16-icon-before::before, +.debug-with-aws-ec2-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--aws-ec2-16-svg); +} + +.debug-with-aws-ec2-24-mask-before::before, +.debug-with-aws-ec2-24-icon-before::before, +.debug-with-aws-ec2-24-mask-after::after, +.debug-with-aws-ec2-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-aws-ec2-24-mask-before::before, +.debug-with-aws-ec2-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--aws-ec2-24-svg); + mask-image: var(--aws-ec2-24-svg); +} +.debug-with-aws-ec2-24-icon-before::before, +.debug-with-aws-ec2-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--aws-ec2-24-svg); +} + +.debug-with-aws-ec2-color-16-mask-before::before, +.debug-with-aws-ec2-color-16-icon-before::before, +.debug-with-aws-ec2-color-16-mask-after::after, +.debug-with-aws-ec2-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-aws-ec2-color-16-mask-before::before, +.debug-with-aws-ec2-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--aws-ec2-color-16-svg); + mask-image: var(--aws-ec2-color-16-svg); +} +.debug-with-aws-ec2-color-16-icon-before::before, +.debug-with-aws-ec2-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--aws-ec2-color-16-svg); +} + +.debug-with-aws-ec2-color-24-mask-before::before, +.debug-with-aws-ec2-color-24-icon-before::before, +.debug-with-aws-ec2-color-24-mask-after::after, +.debug-with-aws-ec2-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-aws-ec2-color-24-mask-before::before, +.debug-with-aws-ec2-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--aws-ec2-color-24-svg); + mask-image: var(--aws-ec2-color-24-svg); +} +.debug-with-aws-ec2-color-24-icon-before::before, +.debug-with-aws-ec2-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--aws-ec2-color-24-svg); +} + .debug-with-azure-16-mask-before::before, .debug-with-azure-16-icon-before::before, .debug-with-azure-16-mask-after::after, @@ -2634,6 +2881,68 @@ background-image: var(--azure-devops-color-24-svg); } +.debug-with-bank-vault-16-mask-before::before, +.debug-with-bank-vault-16-icon-before::before, +.debug-with-bank-vault-16-mask-after::after, +.debug-with-bank-vault-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-bank-vault-16-mask-before::before, +.debug-with-bank-vault-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--bank-vault-16-svg); + mask-image: var(--bank-vault-16-svg); +} +.debug-with-bank-vault-16-icon-before::before, +.debug-with-bank-vault-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--bank-vault-16-svg); +} + +.debug-with-bank-vault-24-mask-before::before, +.debug-with-bank-vault-24-icon-before::before, +.debug-with-bank-vault-24-mask-after::after, +.debug-with-bank-vault-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-bank-vault-24-mask-before::before, +.debug-with-bank-vault-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--bank-vault-24-svg); + mask-image: var(--bank-vault-24-svg); +} +.debug-with-bank-vault-24-icon-before::before, +.debug-with-bank-vault-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--bank-vault-24-svg); +} + .debug-with-bar-chart-16-mask-before::before, .debug-with-bar-chart-16-icon-before::before, .debug-with-bar-chart-16-mask-after::after, @@ -3781,6 +4090,130 @@ background-image: var(--bottom-24-svg); } +.debug-with-boundary-16-mask-before::before, +.debug-with-boundary-16-icon-before::before, +.debug-with-boundary-16-mask-after::after, +.debug-with-boundary-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-boundary-16-mask-before::before, +.debug-with-boundary-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--boundary-16-svg); + mask-image: var(--boundary-16-svg); +} +.debug-with-boundary-16-icon-before::before, +.debug-with-boundary-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--boundary-16-svg); +} + +.debug-with-boundary-24-mask-before::before, +.debug-with-boundary-24-icon-before::before, +.debug-with-boundary-24-mask-after::after, +.debug-with-boundary-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-boundary-24-mask-before::before, +.debug-with-boundary-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--boundary-24-svg); + mask-image: var(--boundary-24-svg); +} +.debug-with-boundary-24-icon-before::before, +.debug-with-boundary-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--boundary-24-svg); +} + +.debug-with-boundary-color-16-mask-before::before, +.debug-with-boundary-color-16-icon-before::before, +.debug-with-boundary-color-16-mask-after::after, +.debug-with-boundary-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-boundary-color-16-mask-before::before, +.debug-with-boundary-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--boundary-color-16-svg); + mask-image: var(--boundary-color-16-svg); +} +.debug-with-boundary-color-16-icon-before::before, +.debug-with-boundary-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--boundary-color-16-svg); +} + +.debug-with-boundary-color-24-mask-before::before, +.debug-with-boundary-color-24-icon-before::before, +.debug-with-boundary-color-24-mask-after::after, +.debug-with-boundary-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-boundary-color-24-mask-before::before, +.debug-with-boundary-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--boundary-color-24-svg); + mask-image: var(--boundary-color-24-svg); +} +.debug-with-boundary-color-24-icon-before::before, +.debug-with-boundary-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--boundary-color-24-svg); +} + .debug-with-box-16-mask-before::before, .debug-with-box-16-icon-before::before, .debug-with-box-16-mask-after::after, @@ -7408,6 +7841,130 @@ background-image: var(--code-svg); } +.debug-with-codepen-16-mask-before::before, +.debug-with-codepen-16-icon-before::before, +.debug-with-codepen-16-mask-after::after, +.debug-with-codepen-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-codepen-16-mask-before::before, +.debug-with-codepen-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--codepen-16-svg); + mask-image: var(--codepen-16-svg); +} +.debug-with-codepen-16-icon-before::before, +.debug-with-codepen-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--codepen-16-svg); +} + +.debug-with-codepen-24-mask-before::before, +.debug-with-codepen-24-icon-before::before, +.debug-with-codepen-24-mask-after::after, +.debug-with-codepen-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-codepen-24-mask-before::before, +.debug-with-codepen-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--codepen-24-svg); + mask-image: var(--codepen-24-svg); +} +.debug-with-codepen-24-icon-before::before, +.debug-with-codepen-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--codepen-24-svg); +} + +.debug-with-codepen-color-16-mask-before::before, +.debug-with-codepen-color-16-icon-before::before, +.debug-with-codepen-color-16-mask-after::after, +.debug-with-codepen-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-codepen-color-16-mask-before::before, +.debug-with-codepen-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--codepen-color-16-svg); + mask-image: var(--codepen-color-16-svg); +} +.debug-with-codepen-color-16-icon-before::before, +.debug-with-codepen-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--codepen-color-16-svg); +} + +.debug-with-codepen-color-24-mask-before::before, +.debug-with-codepen-color-24-icon-before::before, +.debug-with-codepen-color-24-mask-after::after, +.debug-with-codepen-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-codepen-color-24-mask-before::before, +.debug-with-codepen-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--codepen-color-24-svg); + mask-image: var(--codepen-color-24-svg); +} +.debug-with-codepen-color-24-icon-before::before, +.debug-with-codepen-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--codepen-color-24-svg); +} + .debug-with-collections-16-mask-before::before, .debug-with-collections-16-icon-before::before, .debug-with-collections-16-mask-after::after, @@ -7749,6 +8306,130 @@ background-image: var(--console-svg); } +.debug-with-consul-16-mask-before::before, +.debug-with-consul-16-icon-before::before, +.debug-with-consul-16-mask-after::after, +.debug-with-consul-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-consul-16-mask-before::before, +.debug-with-consul-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--consul-16-svg); + mask-image: var(--consul-16-svg); +} +.debug-with-consul-16-icon-before::before, +.debug-with-consul-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--consul-16-svg); +} + +.debug-with-consul-24-mask-before::before, +.debug-with-consul-24-icon-before::before, +.debug-with-consul-24-mask-after::after, +.debug-with-consul-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-consul-24-mask-before::before, +.debug-with-consul-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--consul-24-svg); + mask-image: var(--consul-24-svg); +} +.debug-with-consul-24-icon-before::before, +.debug-with-consul-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--consul-24-svg); +} + +.debug-with-consul-color-16-mask-before::before, +.debug-with-consul-color-16-icon-before::before, +.debug-with-consul-color-16-mask-after::after, +.debug-with-consul-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-consul-color-16-mask-before::before, +.debug-with-consul-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--consul-color-16-svg); + mask-image: var(--consul-color-16-svg); +} +.debug-with-consul-color-16-icon-before::before, +.debug-with-consul-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--consul-color-16-svg); +} + +.debug-with-consul-color-24-mask-before::before, +.debug-with-consul-color-24-icon-before::before, +.debug-with-consul-color-24-mask-after::after, +.debug-with-consul-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-consul-color-24-mask-before::before, +.debug-with-consul-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--consul-color-24-svg); + mask-image: var(--consul-color-24-svg); +} +.debug-with-consul-color-24-icon-before::before, +.debug-with-consul-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--consul-color-24-svg); +} + .debug-with-copy-action-mask-before::before, .debug-with-copy-action-icon-before::before, .debug-with-copy-action-mask-after::after, @@ -10849,6 +11530,130 @@ background-image: var(--f5-color-24-svg); } +.debug-with-facebook-16-mask-before::before, +.debug-with-facebook-16-icon-before::before, +.debug-with-facebook-16-mask-after::after, +.debug-with-facebook-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-facebook-16-mask-before::before, +.debug-with-facebook-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--facebook-16-svg); + mask-image: var(--facebook-16-svg); +} +.debug-with-facebook-16-icon-before::before, +.debug-with-facebook-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--facebook-16-svg); +} + +.debug-with-facebook-24-mask-before::before, +.debug-with-facebook-24-icon-before::before, +.debug-with-facebook-24-mask-after::after, +.debug-with-facebook-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-facebook-24-mask-before::before, +.debug-with-facebook-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--facebook-24-svg); + mask-image: var(--facebook-24-svg); +} +.debug-with-facebook-24-icon-before::before, +.debug-with-facebook-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--facebook-24-svg); +} + +.debug-with-facebook-color-16-mask-before::before, +.debug-with-facebook-color-16-icon-before::before, +.debug-with-facebook-color-16-mask-after::after, +.debug-with-facebook-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-facebook-color-16-mask-before::before, +.debug-with-facebook-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--facebook-color-16-svg); + mask-image: var(--facebook-color-16-svg); +} +.debug-with-facebook-color-16-icon-before::before, +.debug-with-facebook-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--facebook-color-16-svg); +} + +.debug-with-facebook-color-24-mask-before::before, +.debug-with-facebook-color-24-icon-before::before, +.debug-with-facebook-color-24-mask-after::after, +.debug-with-facebook-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-facebook-color-24-mask-before::before, +.debug-with-facebook-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--facebook-color-24-svg); + mask-image: var(--facebook-color-24-svg); +} +.debug-with-facebook-color-24-icon-before::before, +.debug-with-facebook-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--facebook-color-24-svg); +} + .debug-with-fast-forward-16-mask-before::before, .debug-with-fast-forward-16-icon-before::before, .debug-with-fast-forward-16-mask-after::after, @@ -14259,6 +15064,68 @@ background-image: var(--hammer-24-svg); } +.debug-with-handshake-16-mask-before::before, +.debug-with-handshake-16-icon-before::before, +.debug-with-handshake-16-mask-after::after, +.debug-with-handshake-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-handshake-16-mask-before::before, +.debug-with-handshake-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--handshake-16-svg); + mask-image: var(--handshake-16-svg); +} +.debug-with-handshake-16-icon-before::before, +.debug-with-handshake-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--handshake-16-svg); +} + +.debug-with-handshake-24-mask-before::before, +.debug-with-handshake-24-icon-before::before, +.debug-with-handshake-24-mask-after::after, +.debug-with-handshake-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-handshake-24-mask-before::before, +.debug-with-handshake-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--handshake-24-svg); + mask-image: var(--handshake-24-svg); +} +.debug-with-handshake-24-icon-before::before, +.debug-with-handshake-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--handshake-24-svg); +} + .debug-with-hard-drive-16-mask-before::before, .debug-with-hard-drive-16-icon-before::before, .debug-with-hard-drive-16-mask-after::after, @@ -14383,6 +15250,254 @@ background-image: var(--hash-24-svg); } +.debug-with-hashicorp-16-mask-before::before, +.debug-with-hashicorp-16-icon-before::before, +.debug-with-hashicorp-16-mask-after::after, +.debug-with-hashicorp-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hashicorp-16-mask-before::before, +.debug-with-hashicorp-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hashicorp-16-svg); + mask-image: var(--hashicorp-16-svg); +} +.debug-with-hashicorp-16-icon-before::before, +.debug-with-hashicorp-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hashicorp-16-svg); +} + +.debug-with-hashicorp-24-mask-before::before, +.debug-with-hashicorp-24-icon-before::before, +.debug-with-hashicorp-24-mask-after::after, +.debug-with-hashicorp-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hashicorp-24-mask-before::before, +.debug-with-hashicorp-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hashicorp-24-svg); + mask-image: var(--hashicorp-24-svg); +} +.debug-with-hashicorp-24-icon-before::before, +.debug-with-hashicorp-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hashicorp-24-svg); +} + +.debug-with-hashicorp-color-16-mask-before::before, +.debug-with-hashicorp-color-16-icon-before::before, +.debug-with-hashicorp-color-16-mask-after::after, +.debug-with-hashicorp-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hashicorp-color-16-mask-before::before, +.debug-with-hashicorp-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hashicorp-color-16-svg); + mask-image: var(--hashicorp-color-16-svg); +} +.debug-with-hashicorp-color-16-icon-before::before, +.debug-with-hashicorp-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hashicorp-color-16-svg); +} + +.debug-with-hashicorp-color-24-mask-before::before, +.debug-with-hashicorp-color-24-icon-before::before, +.debug-with-hashicorp-color-24-mask-after::after, +.debug-with-hashicorp-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hashicorp-color-24-mask-before::before, +.debug-with-hashicorp-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hashicorp-color-24-svg); + mask-image: var(--hashicorp-color-24-svg); +} +.debug-with-hashicorp-color-24-icon-before::before, +.debug-with-hashicorp-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hashicorp-color-24-svg); +} + +.debug-with-hcp-16-mask-before::before, +.debug-with-hcp-16-icon-before::before, +.debug-with-hcp-16-mask-after::after, +.debug-with-hcp-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hcp-16-mask-before::before, +.debug-with-hcp-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hcp-16-svg); + mask-image: var(--hcp-16-svg); +} +.debug-with-hcp-16-icon-before::before, +.debug-with-hcp-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hcp-16-svg); +} + +.debug-with-hcp-24-mask-before::before, +.debug-with-hcp-24-icon-before::before, +.debug-with-hcp-24-mask-after::after, +.debug-with-hcp-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hcp-24-mask-before::before, +.debug-with-hcp-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hcp-24-svg); + mask-image: var(--hcp-24-svg); +} +.debug-with-hcp-24-icon-before::before, +.debug-with-hcp-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hcp-24-svg); +} + +.debug-with-hcp-color-16-mask-before::before, +.debug-with-hcp-color-16-icon-before::before, +.debug-with-hcp-color-16-mask-after::after, +.debug-with-hcp-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hcp-color-16-mask-before::before, +.debug-with-hcp-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hcp-color-16-svg); + mask-image: var(--hcp-color-16-svg); +} +.debug-with-hcp-color-16-icon-before::before, +.debug-with-hcp-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hcp-color-16-svg); +} + +.debug-with-hcp-color-24-mask-before::before, +.debug-with-hcp-color-24-icon-before::before, +.debug-with-hcp-color-24-mask-after::after, +.debug-with-hcp-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-hcp-color-24-mask-before::before, +.debug-with-hcp-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--hcp-color-24-svg); + mask-image: var(--hcp-color-24-svg); +} +.debug-with-hcp-color-24-icon-before::before, +.debug-with-hcp-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--hcp-color-24-svg); +} + .debug-with-headphones-16-mask-before::before, .debug-with-headphones-16-icon-before::before, .debug-with-headphones-16-mask-after::after, @@ -15716,6 +16831,68 @@ background-image: var(--key-svg); } +.debug-with-keychain-16-mask-before::before, +.debug-with-keychain-16-icon-before::before, +.debug-with-keychain-16-mask-after::after, +.debug-with-keychain-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-keychain-16-mask-before::before, +.debug-with-keychain-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--keychain-16-svg); + mask-image: var(--keychain-16-svg); +} +.debug-with-keychain-16-icon-before::before, +.debug-with-keychain-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--keychain-16-svg); +} + +.debug-with-keychain-24-mask-before::before, +.debug-with-keychain-24-icon-before::before, +.debug-with-keychain-24-mask-after::after, +.debug-with-keychain-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-keychain-24-mask-before::before, +.debug-with-keychain-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--keychain-24-svg); + mask-image: var(--keychain-24-svg); +} +.debug-with-keychain-24-icon-before::before, +.debug-with-keychain-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--keychain-24-svg); +} + .debug-with-kubernetes-16-mask-before::before, .debug-with-kubernetes-16-icon-before::before, .debug-with-kubernetes-16-mask-after::after, @@ -16429,6 +17606,130 @@ background-image: var(--link-svg); } +.debug-with-linkedin-16-mask-before::before, +.debug-with-linkedin-16-icon-before::before, +.debug-with-linkedin-16-mask-after::after, +.debug-with-linkedin-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-linkedin-16-mask-before::before, +.debug-with-linkedin-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--linkedin-16-svg); + mask-image: var(--linkedin-16-svg); +} +.debug-with-linkedin-16-icon-before::before, +.debug-with-linkedin-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--linkedin-16-svg); +} + +.debug-with-linkedin-24-mask-before::before, +.debug-with-linkedin-24-icon-before::before, +.debug-with-linkedin-24-mask-after::after, +.debug-with-linkedin-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-linkedin-24-mask-before::before, +.debug-with-linkedin-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--linkedin-24-svg); + mask-image: var(--linkedin-24-svg); +} +.debug-with-linkedin-24-icon-before::before, +.debug-with-linkedin-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--linkedin-24-svg); +} + +.debug-with-linkedin-color-16-mask-before::before, +.debug-with-linkedin-color-16-icon-before::before, +.debug-with-linkedin-color-16-mask-after::after, +.debug-with-linkedin-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-linkedin-color-16-mask-before::before, +.debug-with-linkedin-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--linkedin-color-16-svg); + mask-image: var(--linkedin-color-16-svg); +} +.debug-with-linkedin-color-16-icon-before::before, +.debug-with-linkedin-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--linkedin-color-16-svg); +} + +.debug-with-linkedin-color-24-mask-before::before, +.debug-with-linkedin-color-24-icon-before::before, +.debug-with-linkedin-color-24-mask-after::after, +.debug-with-linkedin-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-linkedin-color-24-mask-before::before, +.debug-with-linkedin-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--linkedin-color-24-svg); + mask-image: var(--linkedin-color-24-svg); +} +.debug-with-linkedin-color-24-icon-before::before, +.debug-with-linkedin-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--linkedin-color-24-svg); +} + .debug-with-list-16-mask-before::before, .debug-with-list-16-icon-before::before, .debug-with-list-16-mask-after::after, @@ -16491,6 +17792,68 @@ background-image: var(--list-24-svg); } +.debug-with-load-balancer-16-mask-before::before, +.debug-with-load-balancer-16-icon-before::before, +.debug-with-load-balancer-16-mask-after::after, +.debug-with-load-balancer-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-load-balancer-16-mask-before::before, +.debug-with-load-balancer-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--load-balancer-16-svg); + mask-image: var(--load-balancer-16-svg); +} +.debug-with-load-balancer-16-icon-before::before, +.debug-with-load-balancer-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--load-balancer-16-svg); +} + +.debug-with-load-balancer-24-mask-before::before, +.debug-with-load-balancer-24-icon-before::before, +.debug-with-load-balancer-24-mask-after::after, +.debug-with-load-balancer-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-load-balancer-24-mask-before::before, +.debug-with-load-balancer-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--load-balancer-24-svg); + mask-image: var(--load-balancer-24-svg); +} +.debug-with-load-balancer-24-icon-before::before, +.debug-with-load-balancer-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--load-balancer-24-svg); +} + .debug-with-loading-mask-before::before, .debug-with-loading-icon-before::before, .debug-with-loading-mask-after::after, @@ -18165,6 +19528,68 @@ background-image: var(--mail-open-24-svg); } +.debug-with-mainframe-16-mask-before::before, +.debug-with-mainframe-16-icon-before::before, +.debug-with-mainframe-16-mask-after::after, +.debug-with-mainframe-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-mainframe-16-mask-before::before, +.debug-with-mainframe-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--mainframe-16-svg); + mask-image: var(--mainframe-16-svg); +} +.debug-with-mainframe-16-icon-before::before, +.debug-with-mainframe-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--mainframe-16-svg); +} + +.debug-with-mainframe-24-mask-before::before, +.debug-with-mainframe-24-icon-before::before, +.debug-with-mainframe-24-mask-after::after, +.debug-with-mainframe-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-mainframe-24-mask-before::before, +.debug-with-mainframe-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--mainframe-24-svg); + mask-image: var(--mainframe-24-svg); +} +.debug-with-mainframe-24-icon-before::before, +.debug-with-mainframe-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--mainframe-24-svg); +} + .debug-with-map-16-mask-before::before, .debug-with-map-16-icon-before::before, .debug-with-map-16-mask-after::after, @@ -20831,6 +22256,130 @@ background-image: var(--node-24-svg); } +.debug-with-nomad-16-mask-before::before, +.debug-with-nomad-16-icon-before::before, +.debug-with-nomad-16-mask-after::after, +.debug-with-nomad-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-nomad-16-mask-before::before, +.debug-with-nomad-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--nomad-16-svg); + mask-image: var(--nomad-16-svg); +} +.debug-with-nomad-16-icon-before::before, +.debug-with-nomad-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--nomad-16-svg); +} + +.debug-with-nomad-24-mask-before::before, +.debug-with-nomad-24-icon-before::before, +.debug-with-nomad-24-mask-after::after, +.debug-with-nomad-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-nomad-24-mask-before::before, +.debug-with-nomad-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--nomad-24-svg); + mask-image: var(--nomad-24-svg); +} +.debug-with-nomad-24-icon-before::before, +.debug-with-nomad-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--nomad-24-svg); +} + +.debug-with-nomad-color-16-mask-before::before, +.debug-with-nomad-color-16-icon-before::before, +.debug-with-nomad-color-16-mask-after::after, +.debug-with-nomad-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-nomad-color-16-mask-before::before, +.debug-with-nomad-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--nomad-color-16-svg); + mask-image: var(--nomad-color-16-svg); +} +.debug-with-nomad-color-16-icon-before::before, +.debug-with-nomad-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--nomad-color-16-svg); +} + +.debug-with-nomad-color-24-mask-before::before, +.debug-with-nomad-color-24-icon-before::before, +.debug-with-nomad-color-24-mask-after::after, +.debug-with-nomad-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-nomad-color-24-mask-before::before, +.debug-with-nomad-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--nomad-color-24-svg); + mask-image: var(--nomad-color-24-svg); +} +.debug-with-nomad-color-24-icon-before::before, +.debug-with-nomad-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--nomad-color-24-svg); +} + .debug-with-notification-disabled-mask-before::before, .debug-with-notification-disabled-icon-before::before, .debug-with-notification-disabled-mask-after::after, @@ -21389,6 +22938,130 @@ background-image: var(--outline-svg); } +.debug-with-pack-16-mask-before::before, +.debug-with-pack-16-icon-before::before, +.debug-with-pack-16-mask-after::after, +.debug-with-pack-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-pack-16-mask-before::before, +.debug-with-pack-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--pack-16-svg); + mask-image: var(--pack-16-svg); +} +.debug-with-pack-16-icon-before::before, +.debug-with-pack-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--pack-16-svg); +} + +.debug-with-pack-24-mask-before::before, +.debug-with-pack-24-icon-before::before, +.debug-with-pack-24-mask-after::after, +.debug-with-pack-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-pack-24-mask-before::before, +.debug-with-pack-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--pack-24-svg); + mask-image: var(--pack-24-svg); +} +.debug-with-pack-24-icon-before::before, +.debug-with-pack-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--pack-24-svg); +} + +.debug-with-pack-color-16-mask-before::before, +.debug-with-pack-color-16-icon-before::before, +.debug-with-pack-color-16-mask-after::after, +.debug-with-pack-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-pack-color-16-mask-before::before, +.debug-with-pack-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--pack-color-16-svg); + mask-image: var(--pack-color-16-svg); +} +.debug-with-pack-color-16-icon-before::before, +.debug-with-pack-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--pack-color-16-svg); +} + +.debug-with-pack-color-24-mask-before::before, +.debug-with-pack-color-24-icon-before::before, +.debug-with-pack-color-24-mask-after::after, +.debug-with-pack-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-pack-color-24-mask-before::before, +.debug-with-pack-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--pack-color-24-svg); + mask-image: var(--pack-color-24-svg); +} +.debug-with-pack-color-24-icon-before::before, +.debug-with-pack-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--pack-color-24-svg); +} + .debug-with-package-16-mask-before::before, .debug-with-package-16-icon-before::before, .debug-with-package-16-mask-after::after, @@ -21451,6 +23124,130 @@ background-image: var(--package-24-svg); } +.debug-with-packer-16-mask-before::before, +.debug-with-packer-16-icon-before::before, +.debug-with-packer-16-mask-after::after, +.debug-with-packer-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-packer-16-mask-before::before, +.debug-with-packer-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--packer-16-svg); + mask-image: var(--packer-16-svg); +} +.debug-with-packer-16-icon-before::before, +.debug-with-packer-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--packer-16-svg); +} + +.debug-with-packer-24-mask-before::before, +.debug-with-packer-24-icon-before::before, +.debug-with-packer-24-mask-after::after, +.debug-with-packer-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-packer-24-mask-before::before, +.debug-with-packer-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--packer-24-svg); + mask-image: var(--packer-24-svg); +} +.debug-with-packer-24-icon-before::before, +.debug-with-packer-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--packer-24-svg); +} + +.debug-with-packer-color-16-mask-before::before, +.debug-with-packer-color-16-icon-before::before, +.debug-with-packer-color-16-mask-after::after, +.debug-with-packer-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-packer-color-16-mask-before::before, +.debug-with-packer-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--packer-color-16-svg); + mask-image: var(--packer-color-16-svg); +} +.debug-with-packer-color-16-icon-before::before, +.debug-with-packer-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--packer-color-16-svg); +} + +.debug-with-packer-color-24-mask-before::before, +.debug-with-packer-color-24-icon-before::before, +.debug-with-packer-color-24-mask-after::after, +.debug-with-packer-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-packer-color-24-mask-before::before, +.debug-with-packer-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--packer-color-24-svg); + mask-image: var(--packer-color-24-svg); +} +.debug-with-packer-color-24-icon-before::before, +.debug-with-packer-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--packer-color-24-svg); +} + .debug-with-page-outline-mask-before::before, .debug-with-page-outline-icon-before::before, .debug-with-page-outline-mask-after::after, @@ -28116,6 +29913,130 @@ background-image: var(--terminal-screen-24-svg); } +.debug-with-terraform-16-mask-before::before, +.debug-with-terraform-16-icon-before::before, +.debug-with-terraform-16-mask-after::after, +.debug-with-terraform-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-terraform-16-mask-before::before, +.debug-with-terraform-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--terraform-16-svg); + mask-image: var(--terraform-16-svg); +} +.debug-with-terraform-16-icon-before::before, +.debug-with-terraform-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--terraform-16-svg); +} + +.debug-with-terraform-24-mask-before::before, +.debug-with-terraform-24-icon-before::before, +.debug-with-terraform-24-mask-after::after, +.debug-with-terraform-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-terraform-24-mask-before::before, +.debug-with-terraform-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--terraform-24-svg); + mask-image: var(--terraform-24-svg); +} +.debug-with-terraform-24-icon-before::before, +.debug-with-terraform-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--terraform-24-svg); +} + +.debug-with-terraform-color-16-mask-before::before, +.debug-with-terraform-color-16-icon-before::before, +.debug-with-terraform-color-16-mask-after::after, +.debug-with-terraform-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-terraform-color-16-mask-before::before, +.debug-with-terraform-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--terraform-color-16-svg); + mask-image: var(--terraform-color-16-svg); +} +.debug-with-terraform-color-16-icon-before::before, +.debug-with-terraform-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--terraform-color-16-svg); +} + +.debug-with-terraform-color-24-mask-before::before, +.debug-with-terraform-color-24-icon-before::before, +.debug-with-terraform-color-24-mask-after::after, +.debug-with-terraform-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-terraform-color-24-mask-before::before, +.debug-with-terraform-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--terraform-color-24-svg); + mask-image: var(--terraform-color-24-svg); +} +.debug-with-terraform-color-24-icon-before::before, +.debug-with-terraform-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--terraform-color-24-svg); +} + .debug-with-thumbs-down-16-mask-before::before, .debug-with-thumbs-down-16-icon-before::before, .debug-with-thumbs-down-16-mask-after::after, @@ -29046,6 +30967,254 @@ background-image: var(--tv-24-svg); } +.debug-with-twitch-16-mask-before::before, +.debug-with-twitch-16-icon-before::before, +.debug-with-twitch-16-mask-after::after, +.debug-with-twitch-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitch-16-mask-before::before, +.debug-with-twitch-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitch-16-svg); + mask-image: var(--twitch-16-svg); +} +.debug-with-twitch-16-icon-before::before, +.debug-with-twitch-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitch-16-svg); +} + +.debug-with-twitch-24-mask-before::before, +.debug-with-twitch-24-icon-before::before, +.debug-with-twitch-24-mask-after::after, +.debug-with-twitch-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitch-24-mask-before::before, +.debug-with-twitch-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitch-24-svg); + mask-image: var(--twitch-24-svg); +} +.debug-with-twitch-24-icon-before::before, +.debug-with-twitch-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitch-24-svg); +} + +.debug-with-twitch-color-16-mask-before::before, +.debug-with-twitch-color-16-icon-before::before, +.debug-with-twitch-color-16-mask-after::after, +.debug-with-twitch-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitch-color-16-mask-before::before, +.debug-with-twitch-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitch-color-16-svg); + mask-image: var(--twitch-color-16-svg); +} +.debug-with-twitch-color-16-icon-before::before, +.debug-with-twitch-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitch-color-16-svg); +} + +.debug-with-twitch-color-24-mask-before::before, +.debug-with-twitch-color-24-icon-before::before, +.debug-with-twitch-color-24-mask-after::after, +.debug-with-twitch-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitch-color-24-mask-before::before, +.debug-with-twitch-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitch-color-24-svg); + mask-image: var(--twitch-color-24-svg); +} +.debug-with-twitch-color-24-icon-before::before, +.debug-with-twitch-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitch-color-24-svg); +} + +.debug-with-twitter-16-mask-before::before, +.debug-with-twitter-16-icon-before::before, +.debug-with-twitter-16-mask-after::after, +.debug-with-twitter-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitter-16-mask-before::before, +.debug-with-twitter-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitter-16-svg); + mask-image: var(--twitter-16-svg); +} +.debug-with-twitter-16-icon-before::before, +.debug-with-twitter-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitter-16-svg); +} + +.debug-with-twitter-24-mask-before::before, +.debug-with-twitter-24-icon-before::before, +.debug-with-twitter-24-mask-after::after, +.debug-with-twitter-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitter-24-mask-before::before, +.debug-with-twitter-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitter-24-svg); + mask-image: var(--twitter-24-svg); +} +.debug-with-twitter-24-icon-before::before, +.debug-with-twitter-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitter-24-svg); +} + +.debug-with-twitter-color-16-mask-before::before, +.debug-with-twitter-color-16-icon-before::before, +.debug-with-twitter-color-16-mask-after::after, +.debug-with-twitter-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitter-color-16-mask-before::before, +.debug-with-twitter-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitter-color-16-svg); + mask-image: var(--twitter-color-16-svg); +} +.debug-with-twitter-color-16-icon-before::before, +.debug-with-twitter-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitter-color-16-svg); +} + +.debug-with-twitter-color-24-mask-before::before, +.debug-with-twitter-color-24-icon-before::before, +.debug-with-twitter-color-24-mask-after::after, +.debug-with-twitter-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-twitter-color-24-mask-before::before, +.debug-with-twitter-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--twitter-color-24-svg); + mask-image: var(--twitter-color-24-svg); +} +.debug-with-twitter-color-24-icon-before::before, +.debug-with-twitter-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--twitter-color-24-svg); +} + .debug-with-type-16-mask-before::before, .debug-with-type-16-icon-before::before, .debug-with-type-16-mask-after::after, @@ -29294,6 +31463,37 @@ background-image: var(--unfold-open-24-svg); } +.debug-with-union-mask-before::before, +.debug-with-union-icon-before::before, +.debug-with-union-mask-after::after, +.debug-with-union-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-union-mask-before::before, +.debug-with-union-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--union-svg); + mask-image: var(--union-svg); +} +.debug-with-union-icon-before::before, +.debug-with-union-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--union-svg); +} + .debug-with-unlock-16-mask-before::before, .debug-with-unlock-16-icon-before::before, .debug-with-unlock-16-mask-after::after, @@ -30131,6 +32331,130 @@ background-image: var(--users-24-svg); } +.debug-with-vagrant-16-mask-before::before, +.debug-with-vagrant-16-icon-before::before, +.debug-with-vagrant-16-mask-after::after, +.debug-with-vagrant-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vagrant-16-mask-before::before, +.debug-with-vagrant-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vagrant-16-svg); + mask-image: var(--vagrant-16-svg); +} +.debug-with-vagrant-16-icon-before::before, +.debug-with-vagrant-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vagrant-16-svg); +} + +.debug-with-vagrant-24-mask-before::before, +.debug-with-vagrant-24-icon-before::before, +.debug-with-vagrant-24-mask-after::after, +.debug-with-vagrant-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vagrant-24-mask-before::before, +.debug-with-vagrant-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vagrant-24-svg); + mask-image: var(--vagrant-24-svg); +} +.debug-with-vagrant-24-icon-before::before, +.debug-with-vagrant-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vagrant-24-svg); +} + +.debug-with-vagrant-color-16-mask-before::before, +.debug-with-vagrant-color-16-icon-before::before, +.debug-with-vagrant-color-16-mask-after::after, +.debug-with-vagrant-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vagrant-color-16-mask-before::before, +.debug-with-vagrant-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vagrant-color-16-svg); + mask-image: var(--vagrant-color-16-svg); +} +.debug-with-vagrant-color-16-icon-before::before, +.debug-with-vagrant-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vagrant-color-16-svg); +} + +.debug-with-vagrant-color-24-mask-before::before, +.debug-with-vagrant-color-24-icon-before::before, +.debug-with-vagrant-color-24-mask-after::after, +.debug-with-vagrant-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vagrant-color-24-mask-before::before, +.debug-with-vagrant-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vagrant-color-24-svg); + mask-image: var(--vagrant-color-24-svg); +} +.debug-with-vagrant-color-24-icon-before::before, +.debug-with-vagrant-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vagrant-color-24-svg); +} + .debug-with-vault-16-mask-before::before, .debug-with-vault-16-icon-before::before, .debug-with-vault-16-mask-after::after, @@ -30193,6 +32517,68 @@ background-image: var(--vault-24-svg); } +.debug-with-vault-color-16-mask-before::before, +.debug-with-vault-color-16-icon-before::before, +.debug-with-vault-color-16-mask-after::after, +.debug-with-vault-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vault-color-16-mask-before::before, +.debug-with-vault-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vault-color-16-svg); + mask-image: var(--vault-color-16-svg); +} +.debug-with-vault-color-16-icon-before::before, +.debug-with-vault-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vault-color-16-svg); +} + +.debug-with-vault-color-24-mask-before::before, +.debug-with-vault-color-24-icon-before::before, +.debug-with-vault-color-24-mask-after::after, +.debug-with-vault-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-vault-color-24-mask-before::before, +.debug-with-vault-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--vault-color-24-svg); + mask-image: var(--vault-color-24-svg); +} +.debug-with-vault-color-24-icon-before::before, +.debug-with-vault-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--vault-color-24-svg); +} + .debug-with-verified-16-mask-before::before, .debug-with-verified-16-icon-before::before, .debug-with-verified-16-mask-after::after, @@ -30937,6 +33323,130 @@ background-image: var(--watch-24-svg); } +.debug-with-waypoint-16-mask-before::before, +.debug-with-waypoint-16-icon-before::before, +.debug-with-waypoint-16-mask-after::after, +.debug-with-waypoint-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-waypoint-16-mask-before::before, +.debug-with-waypoint-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--waypoint-16-svg); + mask-image: var(--waypoint-16-svg); +} +.debug-with-waypoint-16-icon-before::before, +.debug-with-waypoint-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--waypoint-16-svg); +} + +.debug-with-waypoint-24-mask-before::before, +.debug-with-waypoint-24-icon-before::before, +.debug-with-waypoint-24-mask-after::after, +.debug-with-waypoint-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-waypoint-24-mask-before::before, +.debug-with-waypoint-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--waypoint-24-svg); + mask-image: var(--waypoint-24-svg); +} +.debug-with-waypoint-24-icon-before::before, +.debug-with-waypoint-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--waypoint-24-svg); +} + +.debug-with-waypoint-color-16-mask-before::before, +.debug-with-waypoint-color-16-icon-before::before, +.debug-with-waypoint-color-16-mask-after::after, +.debug-with-waypoint-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-waypoint-color-16-mask-before::before, +.debug-with-waypoint-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--waypoint-color-16-svg); + mask-image: var(--waypoint-color-16-svg); +} +.debug-with-waypoint-color-16-icon-before::before, +.debug-with-waypoint-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--waypoint-color-16-svg); +} + +.debug-with-waypoint-color-24-mask-before::before, +.debug-with-waypoint-color-24-icon-before::before, +.debug-with-waypoint-color-24-mask-after::after, +.debug-with-waypoint-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-waypoint-color-24-mask-before::before, +.debug-with-waypoint-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--waypoint-color-24-svg); + mask-image: var(--waypoint-color-24-svg); +} +.debug-with-waypoint-color-24-icon-before::before, +.debug-with-waypoint-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--waypoint-color-24-svg); +} + .debug-with-webhook-16-mask-before::before, .debug-with-webhook-16-icon-before::before, .debug-with-webhook-16-mask-after::after, @@ -31774,6 +34284,130 @@ background-image: var(--x-square-fill-24-svg); } +.debug-with-youtube-16-mask-before::before, +.debug-with-youtube-16-icon-before::before, +.debug-with-youtube-16-mask-after::after, +.debug-with-youtube-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-youtube-16-mask-before::before, +.debug-with-youtube-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--youtube-16-svg); + mask-image: var(--youtube-16-svg); +} +.debug-with-youtube-16-icon-before::before, +.debug-with-youtube-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--youtube-16-svg); +} + +.debug-with-youtube-24-mask-before::before, +.debug-with-youtube-24-icon-before::before, +.debug-with-youtube-24-mask-after::after, +.debug-with-youtube-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-youtube-24-mask-before::before, +.debug-with-youtube-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--youtube-24-svg); + mask-image: var(--youtube-24-svg); +} +.debug-with-youtube-24-icon-before::before, +.debug-with-youtube-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--youtube-24-svg); +} + +.debug-with-youtube-color-16-mask-before::before, +.debug-with-youtube-color-16-icon-before::before, +.debug-with-youtube-color-16-mask-after::after, +.debug-with-youtube-color-16-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-youtube-color-16-mask-before::before, +.debug-with-youtube-color-16-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--youtube-color-16-svg); + mask-image: var(--youtube-color-16-svg); +} +.debug-with-youtube-color-16-icon-before::before, +.debug-with-youtube-color-16-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--youtube-color-16-svg); +} + +.debug-with-youtube-color-24-mask-before::before, +.debug-with-youtube-color-24-icon-before::before, +.debug-with-youtube-color-24-mask-after::after, +.debug-with-youtube-color-24-icon-after::after { + display: inline-block; + content: ''; + visibility: visible; + background-size: contain; + width: 1.2em; + height: 1.2em; + vertical-align: text-top; +} +.debug-with-youtube-color-24-mask-before::before, +.debug-with-youtube-color-24-mask-after::after { + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-repeat: no-repeat; + mask-position: center; + background-color: currentColor; + + -webkit-mask-image: var(--youtube-color-24-svg); + mask-image: var(--youtube-color-24-svg); +} +.debug-with-youtube-color-24-icon-before::before, +.debug-with-youtube-color-24-icon-after::after { + background-repeat: no-repeat; + background-position: center; + + background-image: var(--youtube-color-24-svg); +} + .debug-with-zap-16-mask-before::before, .debug-with-zap-16-icon-before::before, .debug-with-zap-16-mask-after::after, @@ -32021,2072 +34655,1904 @@ background-image: var(--zoom-out-24-svg); } - :root { - ---activity-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---activity-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-octagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-octagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alert-triangle-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alibaba-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alibaba-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alibaba-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---alibaba-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-center-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-center-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-justify-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-justify-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---align-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---apple-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---apple-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---apple-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---apple-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---archive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---archive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-down-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-left-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-left-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-left-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-right-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-right-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-right-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---arrow-up-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---at-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---at-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auth0-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auth0-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auth0-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auth0-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auto-apply-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---auto-apply-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---award-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---award-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---aws-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---aws-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---aws-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---aws-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-devops-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-devops-24-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-devops-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); - ---azure-devops-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); +:root { + --activity-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bar-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --activity-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bar-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bar-chart-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bar-chart-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---battery-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---battery-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---battery-charging-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---battery-charging-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---beaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-octagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---beaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-active-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alert-triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-active-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-active-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-active-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --alibaba-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bell-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-center-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bitbucket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-center-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bitbucket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-justify-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bitbucket-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-justify-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bitbucket-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bolt-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --align-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-add-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --amazon-eks-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-add-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --amazon-eks-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-add-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --amazon-eks-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-add-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --amazon-eks-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-remove-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-remove-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --apple-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-remove-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --archive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bookmark-remove-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --archive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bottom-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bottom-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---box-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---box-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---box-check-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---box-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---briefcase-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---briefcase-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---broadcast-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bug-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bug-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---bug-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-left-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---build-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---build-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---calendar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---calendar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-right-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---calendar-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---camera-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---camera-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---camera-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---camera-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cancel-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cancel-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cancel-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --arrow-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cancel-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --at-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cancel-square-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --at-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---caret-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---caret-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---caret-down-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---caret-up-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auth0-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cast-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auto-apply-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cast-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --auto-apply-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---certificate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --award-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---certificate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --award-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-ec2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---change-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-ec2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-ec2-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --aws-ec2-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --azure-devops-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bank-vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bank-vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bar-chart-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-charging-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --battery-charging-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---check-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --beaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --beaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-down-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-left-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-active-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-right-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bell-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevron-up-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bitbucket-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-add-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---chevrons-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bookmark-remove-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bottom-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bottom-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---circle-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --boundary-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --boundary-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --boundary-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-checked-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --boundary-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-checked-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --box-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-copy-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --box-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clipboard-copy-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --briefcase-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --briefcase-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bug-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clock-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --bug-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---clock-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --build-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --build-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --calendar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --calendar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-cross-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --camera-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-lightning-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --caret-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-lightning-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --caret-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cast-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cast-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --certificate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --certificate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cloud-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---code-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---code-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --change-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---code-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---collections-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---collections-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---command-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---command-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---compass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---compass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---connection-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---connection-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---connection-gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---connection-gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---console-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---copy-action-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---copy-success-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --check-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-left-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-left-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-left-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-left-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-right-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-right-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-right-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-right-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevron-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---corner-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cpu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---cpu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---credit-card-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---credit-card-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --chevrons-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---crop-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---crop-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---crosshair-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---crosshair-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dashboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dashboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---database-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---database-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --circle-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---database-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---delay-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---delay-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-checked-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---delay-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-checked-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---delete-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-copy-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---delete-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clipboard-copy-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---deny-alt-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---deny-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --clock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---deny-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-cross-svg: url('data:image/svg+xml;charset=UTF-8,'); ---disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---disc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---disc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lightning-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---discussion-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lightning-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---discussion-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---discussion-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---discussion-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docker-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docker-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cloud-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --code-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --code-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --codepen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --codepen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --codepen-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---docs-svg: url('data:image/svg+xml;charset=UTF-8,'); + --codepen-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dollar-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --collections-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dollar-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --collections-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --command-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --command-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dot-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --compass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---dot-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --compass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---download-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---droplet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --connection-gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---droplet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --consul-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---duplicate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --consul-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---duplicate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --consul-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---edit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --consul-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---edit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---edit-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---entry-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---entry-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-down-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---envelope-sealed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---envelope-sealed-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---envelope-unsealed--outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---envelope-unsealed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-left-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---event-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---event-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---exit-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---exit-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-right-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---exit-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---expand-less-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---expand-more-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---external-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --corner-up-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---external-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cpu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---eye-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --cpu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---eye-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --credit-card-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---eye-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --credit-card-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---eye-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crop-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---f5-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crop-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---f5-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crosshair-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---f5-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --crosshair-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---f5-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dashboard-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---fast-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dashboard-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---fast-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --database-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --database-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delay-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delay-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delete-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --delete-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --deny-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-diff-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-diff-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --disc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --disc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-source-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-source-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --discussion-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-text-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-text-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---file-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docker-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---files-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---files-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---film-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---film-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --docs-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dollar-sign-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dollar-sign-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---filter-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-half-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---fingerprint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --dot-half-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---fingerprint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --download-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---flag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --download-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---flag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --droplet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---flag-svg: url('data:image/svg+xml;charset=UTF-8,'); + --droplet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --duplicate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --duplicate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --edit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --edit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --entry-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --entry-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --event-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-minus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --event-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-minus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --exit-point-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --exit-point-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --external-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --external-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-plus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-plus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --eye-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---folder-users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---frown-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---frown-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --f5-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --facebook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --facebook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gateway-svg: url('data:image/svg+xml;charset=UTF-8,'); + --facebook-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --facebook-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fast-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fast-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gift-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gift-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-change-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gift-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-change-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gift-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-branch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-branch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-diff-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-branch-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-diff-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-commit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-commit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-commit-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-merge-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-merge-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-source-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-pull-request-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-source-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-pull-request-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-text-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-pull-request-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-text-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-repo-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-repo-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --file-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---git-repository-svg: url('data:image/svg+xml;charset=UTF-8,'); + --files-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---github-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --files-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---github-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --film-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---github-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --film-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---github-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gitlab-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gitlab-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gitlab-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---gitlab-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---globe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --filter-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---globe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fingerprint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---globe-private-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --fingerprint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---globe-private-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --flag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---google-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --flag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---google-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---google-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---google-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---grid-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---grid-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---grid-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---grid-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---guide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-minus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---guide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---guide-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---guide-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---guide-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-plus-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hammer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hammer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hard-drive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hard-drive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --folder-users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --frown-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --frown-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---headphones-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gateway-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---headphones-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gateway-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---health-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gift-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gift-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---heart-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-branch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---help-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-branch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---help-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-commit-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---help-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-commit-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---help-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-merge-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-merge-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-pull-request-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-pull-request-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-repo-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---history-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --git-repo-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---history-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---history-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---home-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---home-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --github-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hourglass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---hourglass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---identity-service-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---identity-service-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --gitlab-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---identity-user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---identity-user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---image-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-private-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---image-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --globe-private-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---inbox-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---inbox-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---info-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---info-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --google-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---info-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---info-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---jump-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---jump-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --grid-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---key-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---key-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---key-values-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---key-values-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --guide-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---key-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hammer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---kubernetes-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hammer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---kubernetes-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --handshake-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---kubernetes-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --handshake-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---kubernetes-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hard-drive-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---labyrinth-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hard-drive-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---labyrinth-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---layers-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---layers-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hashicorp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---layers-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hashicorp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---layout-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hashicorp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---layout-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hashicorp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---learn-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hcp-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---learn-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hcp-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---learn-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hcp-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---learn-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hcp-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---learn-svg: url('data:image/svg+xml;charset=UTF-8,'); + --headphones-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---line-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --headphones-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---line-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---line-chart-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---line-chart-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---link-svg: url('data:image/svg+xml;charset=UTF-8,'); + --heart-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---list-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --help-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---list-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --help-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---loading-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-closed-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-closed-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --history-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-closed-svg: url('data:image/svg+xml;charset=UTF-8,'); + --history-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + --home-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --home-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hourglass-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --hourglass-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-service-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---lock-open-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-service-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-alicloud-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-alicloud-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --identity-user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-auth0-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --image-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-aws-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --image-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-aws-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --inbox-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-azure-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --inbox-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-azure-dev-ops-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --info-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-azure-dev-ops-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --info-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-azure-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --jump-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-bitbucket-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --jump-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-bitbucket-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-consul-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-ember-circle-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-values-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-gcp-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --key-values-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-gcp-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --keychain-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-github-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --keychain-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-github-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-gitlab-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-gitlab-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-glimmer-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --kubernetes-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-google-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --labyrinth-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-google-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --labyrinth-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-hashicorp-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layers-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-jwt-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layers-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-kubernetes-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layout-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-kubernetes-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --layout-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-microsoft-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-nomad-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-oidc-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-okta-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --learn-link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-oracle-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-oracle-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-slack-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-slack-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --line-chart-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-terraform-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --link-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-vault-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --link-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-vmware-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --linkedin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---logo-vmware-monochrome-svg: url('data:image/svg+xml;charset=UTF-8,'); + --linkedin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mail-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --linkedin-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mail-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --linkedin-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mail-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --list-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mail-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --list-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---map-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --load-balancer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---map-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --load-balancer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---map-pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --loading-svg: url('data:image/svg+xml;charset=UTF-8,'); ---map-pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---maximize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---maximize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---maximize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---maximize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---meh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --lock-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---meh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-consul-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---menu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-ember-circle-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---menu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-glimmer-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---menu-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-hashicorp-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mesh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-jwt-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mesh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-nomad-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mesh-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-oidc-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-terraform-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --logo-vault-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mail-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mainframe-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mainframe-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---message-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mic-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mic-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mic-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --map-pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mic-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---microsoft-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---microsoft-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---microsoft-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --maximize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---microsoft-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --meh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---migrate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --meh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---migrate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --menu-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minimize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --menu-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minimize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mesh-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minimize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mesh-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minimize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --message-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mic-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --microsoft-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---minus-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --migrate-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---module-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --migrate-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---module-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---module-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---monitor-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---monitor-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minimize-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---moon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---moon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-horizontal-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---more-vertical-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mouse-pointer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---mouse-pointer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---move-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---move-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --minus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---music-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --module-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---music-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --module-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---navigation-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --monitor-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---navigation-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --monitor-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---navigation-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --moon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---navigation-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --moon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---network-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---network-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---network-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---network-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --more-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---newspaper-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mouse-pointer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---newspaper-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --mouse-pointer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---node-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --move-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---node-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --move-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---notification-disabled-svg: url('data:image/svg+xml;charset=UTF-8,'); + --music-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---notification-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --music-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---notification-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---okta-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --navigation-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---okta-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---okta-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---okta-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-alt-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---oracle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --network-alt-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---oracle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --newspaper-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---oracle-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --newspaper-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---oracle-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --node-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---org-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --node-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---org-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --nomad-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---outline-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --nomad-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---outline-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --nomad-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --nomad-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---package-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --octagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---package-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --octagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---page-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---paperclip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---paperclip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---partner-svg: url('data:image/svg+xml;charset=UTF-8,'); + --okta-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---path-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---path-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---path-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pause-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --oracle-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pause-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --org-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pause-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --org-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pause-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --outline-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pen-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --outline-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pen-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pencil-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pencil-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --package-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-call-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --package-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-call-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --packer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --packer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---phone-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --packer-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pie-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --packer-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pie-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --paperclip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --paperclip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --path-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --path-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pause-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pen-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---play-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pen-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pencil-tool-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pencil-tool-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-circle-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-call-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-circle-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-call-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --phone-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pie-chart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---plus-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pie-chart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---port-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pin-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---power-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --pin-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---power-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---printer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---printer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---protocol-svg: url('data:image/svg+xml;charset=UTF-8,'); + --play-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---provider-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---provider-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---provider-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---public-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---public-locked-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---queue-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --plus-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---queue-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --port-svg: url('data:image/svg+xml;charset=UTF-8,'); ---queue-svg: url('data:image/svg+xml;charset=UTF-8,'); + --power-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---radio-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --power-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---radio-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --printer-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---radio-button-checked-svg: url('data:image/svg+xml;charset=UTF-8,'); + --printer-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---radio-button-unchecked-svg: url('data:image/svg+xml;charset=UTF-8,'); + --protocol-svg: url('data:image/svg+xml;charset=UTF-8,'); ---random-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --provider-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---random-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --provider-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---random-svg: url('data:image/svg+xml;charset=UTF-8,'); + --queue-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---redirect-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --queue-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---redirect-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --radio-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---redirect-svg: url('data:image/svg+xml;charset=UTF-8,'); + --radio-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---refresh-alert-svg: url('data:image/svg+xml;charset=UTF-8,'); + --random-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---refresh-default-svg: url('data:image/svg+xml;charset=UTF-8,'); + --random-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---reload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --redirect-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---reload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --redirect-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---remix-svg: url('data:image/svg+xml;charset=UTF-8,'); + --reload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---repeat-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --reload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---repeat-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --repeat-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---replication-direct-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --repeat-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---replication-direct-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-direct-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---replication-perf-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-direct-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---replication-perf-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-perf-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rewind-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --replication-perf-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rewind-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rewind-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---ribbon-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rewind-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rocket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rocket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rocket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rocket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rotate-ccw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-ccw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rotate-ccw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-ccw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rotate-cw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-cw-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rotate-cw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rotate-cw-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rss-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rss-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---rss-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --rss-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---run-svg: url('data:image/svg+xml;charset=UTF-8,'); + --run-svg: url('data:image/svg+xml;charset=UTF-8,'); ---save-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --save-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---save-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --save-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---scissors-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --scissors-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---scissors-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --scissors-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---search-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --search-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---search-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --search-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---search-color-svg: url('data:image/svg+xml;charset=UTF-8,'); + --search-color-svg: url('data:image/svg+xml;charset=UTF-8,'); ---search-svg: url('data:image/svg+xml;charset=UTF-8,'); + --send-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---send-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --send-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---send-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---server-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---server-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-cluster-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---server-cluster-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --server-cluster-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---server-cluster-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --serverless-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---serverless-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --serverless-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---serverless-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --settings-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---settings-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --settings-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---settings-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --share-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---settings-svg: url('data:image/svg+xml;charset=UTF-8,'); + --share-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---share-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---share-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shield-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-bag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shield-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-bag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shopping-bag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-cart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shopping-bag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shopping-cart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shopping-cart-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shuffle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shopping-cart-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --shuffle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shuffle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---shuffle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-hide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-hide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-hide-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-show-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-hide-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sidebar-show-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-show-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sidebar-show-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sign-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sign-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sign-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sign-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sign-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-back-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-back-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-back-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-back-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --skip-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-forward-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---skip-forward-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slack-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slack-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slack-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slack-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --slash-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slash-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sliders-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---slash-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sliders-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sliders-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smartphone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sliders-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smartphone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---smartphone-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smile-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---smartphone-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --smile-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---smile-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --socket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---smile-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --socket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---socket-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --socket-svg: url('data:image/svg+xml;charset=UTF-8,'); ---socket-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-asc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---socket-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-asc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sort-asc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-desc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sort-asc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sort-desc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sort-desc-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --speaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sort-desc-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --speaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sort-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---source-file-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---speaker-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---speaker-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --star-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --stop-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --stop-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sun-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sun-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --support-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---star-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --support-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---stop-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---stop-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sub-left-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sub-right-svg: url('data:image/svg+xml;charset=UTF-8,'); + --swap-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sun-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --switcher-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sun-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --switcher-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---support-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---support-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---support-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-horizontal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-horizontal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-reverse-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-horizontal-svg: url('data:image/svg+xml;charset=UTF-8,'); + --sync-reverse-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-vertical-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tablet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-vertical-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tablet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---swap-vertical-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---switcher-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---switcher-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --target-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --target-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-alert-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-alert-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-screen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-reverse-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terminal-screen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---sync-reverse-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terraform-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tablet-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terraform-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tablet-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terraform-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tag-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --terraform-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tag-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tag-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---target-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---target-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --thumbs-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---terminal-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---terminal-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---terminal-screen-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---terminal-screen-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --toggle-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---thumbs-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --token-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---thumbs-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --token-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---thumbs-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tools-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---thumbs-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tools-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---toggle-left-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --top-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---toggle-left-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --top-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---toggle-right-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---toggle-right-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---token-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---token-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tools-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tools-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --trend-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---top-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---top-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trash-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trash-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trash-svg: url('data:image/svg+xml;charset=UTF-8,'); + --truck-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trend-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --truck-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trend-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tv-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trend-up-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --tv-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---trend-up-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---triangle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---triangle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitch-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---triangle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitch-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---triangle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitter-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---truck-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitter-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---truck-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitter-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tune-svg: url('data:image/svg+xml;charset=UTF-8,'); + --twitter-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tv-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --type-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---tv-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --type-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---type-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-close-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---type-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-close-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-close-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-close-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unfold-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-less-svg: url('data:image/svg+xml;charset=UTF-8,'); + --union-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-more-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unlock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-open-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --unlock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unfold-open-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unlock-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---unlock-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---upload-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---upload-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---upload-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-add-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-check-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-check-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-minus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --user-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-minus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-organization-svg: url('data:image/svg+xml;charset=UTF-8,'); + --users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-plain-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vagrant-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-plus-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vagrant-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-plus-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vagrant-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-square-fill-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vagrant-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-square-outline-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-team-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---user-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vault-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---users-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --verified-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---users-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --verified-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vault-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vault-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---verified-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---verified-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --video-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---video-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---video-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---video-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---video-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --vmware-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---visibility-hide-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---visibility-show-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vmware-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vmware-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vmware-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---vmware-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-2-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --volume-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-2-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wall-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wall-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-down-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --watch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-down-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --watch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --waypoint-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---volume-x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --waypoint-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wall-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --waypoint-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wall-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --waypoint-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---watch-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --webhook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---watch-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --webhook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---webhook-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---webhook-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---webhook-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wifi-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wifi-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wifi-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wrench-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wifi-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --wrench-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wifi-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wrench-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---wrench-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-circle-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-circle-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-circle-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-circle-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-diamond-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-diamond-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-diamond-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-diamond-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-hexagon-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-hexagon-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-hexagon-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-hexagon-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-square-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --x-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-square-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --youtube-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-square-fill-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --youtube-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---x-square-fill-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --youtube-color-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zap-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --youtube-color-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zap-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zap-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zap-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-off-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zoom-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zap-off-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zoom-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-in-16-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zoom-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-in-24-svg: url('data:image/svg+xml;charset=UTF-8,'); ---zoom-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-out-16-svg: url('data:image/svg+xml;charset=UTF-8,'); + --zoom-out-24-svg: url('data:image/svg+xml;charset=UTF-8,'); } diff --git a/ui/packages/consul-ui/app/styles/base/icons/icon-placeholders.scss b/ui/packages/consul-ui/app/styles/base/icons/icon-placeholders.scss index 9669a0450b..6bbfd486b3 100644 --- a/ui/packages/consul-ui/app/styles/base/icons/icon-placeholders.scss +++ b/ui/packages/consul-ui/app/styles/base/icons/icon-placeholders.scss @@ -59,23 +59,23 @@ } %with-alert-circle-fill-icon { - @extend %with-icon, %alert-circle-fill-svg-prop; - background-image: var(--alert-circle-fill-svg); + @extend %with-icon, %alert-circle-16-svg-prop; + background-image: var(--alert-circle-16-svg); } %with-alert-circle-fill-mask { - @extend %with-mask, %alert-circle-fill-svg-prop; - -webkit-mask-image: var(--alert-circle-fill-svg); - mask-image: var(--alert-circle-fill-svg); + @extend %with-mask, %alert-circle-16-svg-prop; + -webkit-mask-image: var(--alert-circle-16-svg); + mask-image: var(--alert-circle-16-svg); } %with-alert-circle-outline-icon { - @extend %with-icon, %alert-circle-outline-svg-prop; - background-image: var(--alert-circle-outline-svg); + @extend %with-icon, %alert-circle-16-svg-prop; + background-image: var(--alert-circle-16-svg); } %with-alert-circle-outline-mask { - @extend %with-mask, %alert-circle-outline-svg-prop; - -webkit-mask-image: var(--alert-circle-outline-svg); - mask-image: var(--alert-circle-outline-svg); + @extend %with-mask, %alert-circle-16-svg-prop; + -webkit-mask-image: var(--alert-circle-16-svg); + mask-image: var(--alert-circle-16-svg); } %with-alert-octagon-16-icon { @@ -159,13 +159,13 @@ } %with-alert-triangle-icon { - @extend %with-icon, %alert-triangle-svg-prop; - background-image: var(--alert-triangle-svg); + @extend %with-icon, %alert-triangle-16-svg-prop; + background-image: var(--alert-triangle-16-svg); } %with-alert-triangle-mask { - @extend %with-mask, %alert-triangle-svg-prop; - -webkit-mask-image: var(--alert-triangle-svg); - mask-image: var(--alert-triangle-svg); + @extend %with-mask, %alert-triangle-16-svg-prop; + -webkit-mask-image: var(--alert-triangle-16-svg); + mask-image: var(--alert-triangle-16-svg); } %with-alibaba-16-icon { @@ -288,6 +288,46 @@ mask-image: var(--align-right-24-svg); } +%with-amazon-eks-16-icon { + @extend %with-icon, %amazon-eks-16-svg-prop; + background-image: var(--amazon-eks-16-svg); +} +%with-amazon-eks-16-mask { + @extend %with-mask, %amazon-eks-16-svg-prop; + -webkit-mask-image: var(--amazon-eks-16-svg); + mask-image: var(--amazon-eks-16-svg); +} + +%with-amazon-eks-24-icon { + @extend %with-icon, %amazon-eks-24-svg-prop; + background-image: var(--amazon-eks-24-svg); +} +%with-amazon-eks-24-mask { + @extend %with-mask, %amazon-eks-24-svg-prop; + -webkit-mask-image: var(--amazon-eks-24-svg); + mask-image: var(--amazon-eks-24-svg); +} + +%with-amazon-eks-color-16-icon { + @extend %with-icon, %amazon-eks-color-16-svg-prop; + background-image: var(--amazon-eks-color-16-svg); +} +%with-amazon-eks-color-16-mask { + @extend %with-mask, %amazon-eks-color-16-svg-prop; + -webkit-mask-image: var(--amazon-eks-color-16-svg); + mask-image: var(--amazon-eks-color-16-svg); +} + +%with-amazon-eks-color-24-icon { + @extend %with-icon, %amazon-eks-color-24-svg-prop; + background-image: var(--amazon-eks-color-24-svg); +} +%with-amazon-eks-color-24-mask { + @extend %with-mask, %amazon-eks-color-24-svg-prop; + -webkit-mask-image: var(--amazon-eks-color-24-svg); + mask-image: var(--amazon-eks-color-24-svg); +} + %with-apple-16-icon { @extend %with-icon, %apple-16-svg-prop; background-image: var(--apple-16-svg); @@ -429,13 +469,13 @@ } %with-arrow-down-icon { - @extend %with-icon, %arrow-down-svg-prop; - background-image: var(--arrow-down-svg); + @extend %with-icon, %arrow-down-16-svg-prop; + background-image: var(--arrow-down-16-svg); } %with-arrow-down-mask { - @extend %with-mask, %arrow-down-svg-prop; - -webkit-mask-image: var(--arrow-down-svg); - mask-image: var(--arrow-down-svg); + @extend %with-mask, %arrow-down-16-svg-prop; + -webkit-mask-image: var(--arrow-down-16-svg); + mask-image: var(--arrow-down-16-svg); } %with-arrow-left-16-icon { @@ -479,13 +519,13 @@ } %with-arrow-left-icon { - @extend %with-icon, %arrow-left-svg-prop; - background-image: var(--arrow-left-svg); + @extend %with-icon, %arrow-left-16-svg-prop; + background-image: var(--arrow-left-16-svg); } %with-arrow-left-mask { - @extend %with-mask, %arrow-left-svg-prop; - -webkit-mask-image: var(--arrow-left-svg); - mask-image: var(--arrow-left-svg); + @extend %with-mask, %arrow-left-16-svg-prop; + -webkit-mask-image: var(--arrow-left-16-svg); + mask-image: var(--arrow-left-16-svg); } %with-arrow-right-16-icon { @@ -529,13 +569,13 @@ } %with-arrow-right-icon { - @extend %with-icon, %arrow-right-svg-prop; - background-image: var(--arrow-right-svg); + @extend %with-icon, %arrow-right-16-svg-prop; + background-image: var(--arrow-right-16-svg); } %with-arrow-right-mask { - @extend %with-mask, %arrow-right-svg-prop; - -webkit-mask-image: var(--arrow-right-svg); - mask-image: var(--arrow-right-svg); + @extend %with-mask, %arrow-right-16-svg-prop; + -webkit-mask-image: var(--arrow-right-16-svg); + mask-image: var(--arrow-right-16-svg); } %with-arrow-up-16-icon { @@ -619,13 +659,13 @@ } %with-arrow-up-icon { - @extend %with-icon, %arrow-up-svg-prop; - background-image: var(--arrow-up-svg); + @extend %with-icon, %arrow-up-16-svg-prop; + background-image: var(--arrow-up-16-svg); } %with-arrow-up-mask { - @extend %with-mask, %arrow-up-svg-prop; - -webkit-mask-image: var(--arrow-up-svg); - mask-image: var(--arrow-up-svg); + @extend %with-mask, %arrow-up-16-svg-prop; + -webkit-mask-image: var(--arrow-up-16-svg); + mask-image: var(--arrow-up-16-svg); } %with-at-sign-16-icon { @@ -768,6 +808,46 @@ mask-image: var(--aws-color-24-svg); } +%with-aws-ec2-16-icon { + @extend %with-icon, %aws-ec2-16-svg-prop; + background-image: var(--aws-ec2-16-svg); +} +%with-aws-ec2-16-mask { + @extend %with-mask, %aws-ec2-16-svg-prop; + -webkit-mask-image: var(--aws-ec2-16-svg); + mask-image: var(--aws-ec2-16-svg); +} + +%with-aws-ec2-24-icon { + @extend %with-icon, %aws-ec2-24-svg-prop; + background-image: var(--aws-ec2-24-svg); +} +%with-aws-ec2-24-mask { + @extend %with-mask, %aws-ec2-24-svg-prop; + -webkit-mask-image: var(--aws-ec2-24-svg); + mask-image: var(--aws-ec2-24-svg); +} + +%with-aws-ec2-color-16-icon { + @extend %with-icon, %aws-ec2-color-16-svg-prop; + background-image: var(--aws-ec2-color-16-svg); +} +%with-aws-ec2-color-16-mask { + @extend %with-mask, %aws-ec2-color-16-svg-prop; + -webkit-mask-image: var(--aws-ec2-color-16-svg); + mask-image: var(--aws-ec2-color-16-svg); +} + +%with-aws-ec2-color-24-icon { + @extend %with-icon, %aws-ec2-color-24-svg-prop; + background-image: var(--aws-ec2-color-24-svg); +} +%with-aws-ec2-color-24-mask { + @extend %with-mask, %aws-ec2-color-24-svg-prop; + -webkit-mask-image: var(--aws-ec2-color-24-svg); + mask-image: var(--aws-ec2-color-24-svg); +} + %with-azure-16-icon { @extend %with-icon, %azure-16-svg-prop; background-image: var(--azure-16-svg); @@ -848,6 +928,26 @@ mask-image: var(--azure-devops-color-24-svg); } +%with-bank-vault-16-icon { + @extend %with-icon, %bank-vault-16-svg-prop; + background-image: var(--bank-vault-16-svg); +} +%with-bank-vault-16-mask { + @extend %with-mask, %bank-vault-16-svg-prop; + -webkit-mask-image: var(--bank-vault-16-svg); + mask-image: var(--bank-vault-16-svg); +} + +%with-bank-vault-24-icon { + @extend %with-icon, %bank-vault-24-svg-prop; + background-image: var(--bank-vault-24-svg); +} +%with-bank-vault-24-mask { + @extend %with-mask, %bank-vault-24-svg-prop; + -webkit-mask-image: var(--bank-vault-24-svg); + mask-image: var(--bank-vault-24-svg); +} + %with-bar-chart-16-icon { @extend %with-icon, %bar-chart-16-svg-prop; background-image: var(--bar-chart-16-svg); @@ -1069,13 +1169,13 @@ } %with-bolt-icon { - @extend %with-icon, %bolt-svg-prop; - background-image: var(--bolt-svg); + @extend %with-icon, %zap-16-svg-prop; + background-image: var(--zap-16-svg); } %with-bolt-mask { - @extend %with-mask, %bolt-svg-prop; - -webkit-mask-image: var(--bolt-svg); - mask-image: var(--bolt-svg); + @extend %with-mask, %zap-16-svg-prop; + -webkit-mask-image: var(--zap-16-svg); + mask-image: var(--zap-16-svg); } %with-bookmark-16-icon { @@ -1218,6 +1318,46 @@ mask-image: var(--bottom-24-svg); } +%with-boundary-16-icon { + @extend %with-icon, %boundary-16-svg-prop; + background-image: var(--boundary-16-svg); +} +%with-boundary-16-mask { + @extend %with-mask, %boundary-16-svg-prop; + -webkit-mask-image: var(--boundary-16-svg); + mask-image: var(--boundary-16-svg); +} + +%with-boundary-24-icon { + @extend %with-icon, %boundary-24-svg-prop; + background-image: var(--boundary-24-svg); +} +%with-boundary-24-mask { + @extend %with-mask, %boundary-24-svg-prop; + -webkit-mask-image: var(--boundary-24-svg); + mask-image: var(--boundary-24-svg); +} + +%with-boundary-color-16-icon { + @extend %with-icon, %boundary-color-16-svg-prop; + background-image: var(--boundary-color-16-svg); +} +%with-boundary-color-16-mask { + @extend %with-mask, %boundary-color-16-svg-prop; + -webkit-mask-image: var(--boundary-color-16-svg); + mask-image: var(--boundary-color-16-svg); +} + +%with-boundary-color-24-icon { + @extend %with-icon, %boundary-color-24-svg-prop; + background-image: var(--boundary-color-24-svg); +} +%with-boundary-color-24-mask { + @extend %with-mask, %boundary-color-24-svg-prop; + -webkit-mask-image: var(--boundary-color-24-svg); + mask-image: var(--boundary-color-24-svg); +} + %with-box-16-icon { @extend %with-icon, %box-16-svg-prop; background-image: var(--box-16-svg); @@ -1239,23 +1379,23 @@ } %with-box-check-fill-icon { - @extend %with-icon, %box-check-fill-svg-prop; - background-image: var(--box-check-fill-svg); + @extend %with-icon, %check-square-fill-16-svg-prop; + background-image: var(--check-square-fill-16-svg); } %with-box-check-fill-mask { - @extend %with-mask, %box-check-fill-svg-prop; - -webkit-mask-image: var(--box-check-fill-svg); - mask-image: var(--box-check-fill-svg); + @extend %with-mask, %check-square-fill-16-svg-prop; + -webkit-mask-image: var(--check-square-fill-16-svg); + mask-image: var(--check-square-fill-16-svg); } %with-box-outline-icon { - @extend %with-icon, %box-outline-svg-prop; - background-image: var(--box-outline-svg); + @extend %with-icon, %square-16-svg-prop; + background-image: var(--square-16-svg); } %with-box-outline-mask { - @extend %with-mask, %box-outline-svg-prop; - -webkit-mask-image: var(--box-outline-svg); - mask-image: var(--box-outline-svg); + @extend %with-mask, %square-16-svg-prop; + -webkit-mask-image: var(--square-16-svg); + mask-image: var(--square-16-svg); } %with-briefcase-16-icon { @@ -1279,13 +1419,13 @@ } %with-broadcast-icon { - @extend %with-icon, %broadcast-svg-prop; - background-image: var(--broadcast-svg); + @extend %with-icon, %radio-16-svg-prop; + background-image: var(--radio-16-svg); } %with-broadcast-mask { - @extend %with-mask, %broadcast-svg-prop; - -webkit-mask-image: var(--broadcast-svg); - mask-image: var(--broadcast-svg); + @extend %with-mask, %radio-16-svg-prop; + -webkit-mask-image: var(--radio-16-svg); + mask-image: var(--radio-16-svg); } %with-bug-16-icon { @@ -1309,13 +1449,13 @@ } %with-bug-icon { - @extend %with-icon, %bug-svg-prop; - background-image: var(--bug-svg); + @extend %with-icon, %bug-16-svg-prop; + background-image: var(--bug-16-svg); } %with-bug-mask { - @extend %with-mask, %bug-svg-prop; - -webkit-mask-image: var(--bug-svg); - mask-image: var(--bug-svg); + @extend %with-mask, %bug-16-svg-prop; + -webkit-mask-image: var(--bug-16-svg); + mask-image: var(--bug-16-svg); } %with-build-16-icon { @@ -1359,13 +1499,13 @@ } %with-calendar-icon { - @extend %with-icon, %calendar-svg-prop; - background-image: var(--calendar-svg); + @extend %with-icon, %calendar-16-svg-prop; + background-image: var(--calendar-16-svg); } %with-calendar-mask { - @extend %with-mask, %calendar-svg-prop; - -webkit-mask-image: var(--calendar-svg); - mask-image: var(--calendar-svg); + @extend %with-mask, %calendar-16-svg-prop; + -webkit-mask-image: var(--calendar-16-svg); + mask-image: var(--calendar-16-svg); } %with-camera-16-icon { @@ -1409,53 +1549,53 @@ } %with-cancel-circle-fill-icon { - @extend %with-icon, %cancel-circle-fill-svg-prop; - background-image: var(--cancel-circle-fill-svg); + @extend %with-icon, %x-circle-fill-16-svg-prop; + background-image: var(--x-circle-fill-16-svg); } %with-cancel-circle-fill-mask { - @extend %with-mask, %cancel-circle-fill-svg-prop; - -webkit-mask-image: var(--cancel-circle-fill-svg); - mask-image: var(--cancel-circle-fill-svg); + @extend %with-mask, %x-circle-fill-16-svg-prop; + -webkit-mask-image: var(--x-circle-fill-16-svg); + mask-image: var(--x-circle-fill-16-svg); } %with-cancel-circle-outline-icon { - @extend %with-icon, %cancel-circle-outline-svg-prop; - background-image: var(--cancel-circle-outline-svg); + @extend %with-icon, %x-circle-16-svg-prop; + background-image: var(--x-circle-16-svg); } %with-cancel-circle-outline-mask { - @extend %with-mask, %cancel-circle-outline-svg-prop; - -webkit-mask-image: var(--cancel-circle-outline-svg); - mask-image: var(--cancel-circle-outline-svg); + @extend %with-mask, %x-circle-16-svg-prop; + -webkit-mask-image: var(--x-circle-16-svg); + mask-image: var(--x-circle-16-svg); } %with-cancel-plain-icon { - @extend %with-icon, %cancel-plain-svg-prop; - background-image: var(--cancel-plain-svg); + @extend %with-icon, %x-16-svg-prop; + background-image: var(--x-16-svg); } %with-cancel-plain-mask { - @extend %with-mask, %cancel-plain-svg-prop; - -webkit-mask-image: var(--cancel-plain-svg); - mask-image: var(--cancel-plain-svg); + @extend %with-mask, %x-16-svg-prop; + -webkit-mask-image: var(--x-16-svg); + mask-image: var(--x-16-svg); } %with-cancel-square-fill-icon { - @extend %with-icon, %cancel-square-fill-svg-prop; - background-image: var(--cancel-square-fill-svg); + @extend %with-icon, %x-square-fill-16-svg-prop; + background-image: var(--x-square-fill-16-svg); } %with-cancel-square-fill-mask { - @extend %with-mask, %cancel-square-fill-svg-prop; - -webkit-mask-image: var(--cancel-square-fill-svg); - mask-image: var(--cancel-square-fill-svg); + @extend %with-mask, %x-square-fill-16-svg-prop; + -webkit-mask-image: var(--x-square-fill-16-svg); + mask-image: var(--x-square-fill-16-svg); } %with-cancel-square-outline-icon { - @extend %with-icon, %cancel-square-outline-svg-prop; - background-image: var(--cancel-square-outline-svg); + @extend %with-icon, %x-square-16-svg-prop; + background-image: var(--x-square-16-svg); } %with-cancel-square-outline-mask { - @extend %with-mask, %cancel-square-outline-svg-prop; - -webkit-mask-image: var(--cancel-square-outline-svg); - mask-image: var(--cancel-square-outline-svg); + @extend %with-mask, %x-square-16-svg-prop; + -webkit-mask-image: var(--x-square-16-svg); + mask-image: var(--x-square-16-svg); } %with-caret-16-icon { @@ -1479,23 +1619,23 @@ } %with-caret-down-icon { - @extend %with-icon, %caret-down-svg-prop; - background-image: var(--caret-down-svg); + @extend %with-icon, %caret-16-svg-prop; + background-image: var(--caret-16-svg); } %with-caret-down-mask { - @extend %with-mask, %caret-down-svg-prop; - -webkit-mask-image: var(--caret-down-svg); - mask-image: var(--caret-down-svg); + @extend %with-mask, %caret-16-svg-prop; + -webkit-mask-image: var(--caret-16-svg); + mask-image: var(--caret-16-svg); } %with-caret-up-icon { - @extend %with-icon, %caret-up-svg-prop; - background-image: var(--caret-up-svg); + @extend %with-icon, %chevron-up-16-svg-prop; + background-image: var(--chevron-up-16-svg); } %with-caret-up-mask { - @extend %with-mask, %caret-up-svg-prop; - -webkit-mask-image: var(--caret-up-svg); - mask-image: var(--caret-up-svg); + @extend %with-mask, %chevron-up-16-svg-prop; + -webkit-mask-image: var(--chevron-up-16-svg); + mask-image: var(--chevron-up-16-svg); } %with-cast-16-icon { @@ -1659,23 +1799,23 @@ } %with-check-circle-fill-icon { - @extend %with-icon, %check-circle-fill-svg-prop; - background-image: var(--check-circle-fill-svg); + @extend %with-icon, %check-circle-fill-16-svg-prop; + background-image: var(--check-circle-fill-16-svg); } %with-check-circle-fill-mask { - @extend %with-mask, %check-circle-fill-svg-prop; - -webkit-mask-image: var(--check-circle-fill-svg); - mask-image: var(--check-circle-fill-svg); + @extend %with-mask, %check-circle-fill-16-svg-prop; + -webkit-mask-image: var(--check-circle-fill-16-svg); + mask-image: var(--check-circle-fill-16-svg); } %with-check-circle-outline-icon { - @extend %with-icon, %check-circle-outline-svg-prop; - background-image: var(--check-circle-outline-svg); + @extend %with-icon, %check-circle-16-svg-prop; + background-image: var(--check-circle-16-svg); } %with-check-circle-outline-mask { - @extend %with-mask, %check-circle-outline-svg-prop; - -webkit-mask-image: var(--check-circle-outline-svg); - mask-image: var(--check-circle-outline-svg); + @extend %with-mask, %check-circle-16-svg-prop; + -webkit-mask-image: var(--check-circle-16-svg); + mask-image: var(--check-circle-16-svg); } %with-check-diamond-16-icon { @@ -1759,13 +1899,13 @@ } %with-check-plain-icon { - @extend %with-icon, %check-plain-svg-prop; - background-image: var(--check-plain-svg); + @extend %with-icon, %check-16-svg-prop; + background-image: var(--check-16-svg); } %with-check-plain-mask { - @extend %with-mask, %check-plain-svg-prop; - -webkit-mask-image: var(--check-plain-svg); - mask-image: var(--check-plain-svg); + @extend %with-mask, %check-16-svg-prop; + -webkit-mask-image: var(--check-16-svg); + mask-image: var(--check-16-svg); } %with-check-square-16-icon { @@ -1829,13 +1969,13 @@ } %with-chevron-down-icon { - @extend %with-icon, %chevron-down-svg-prop; - background-image: var(--chevron-down-svg); + @extend %with-icon, %chevron-down-16-svg-prop; + background-image: var(--chevron-down-16-svg); } %with-chevron-down-mask { - @extend %with-mask, %chevron-down-svg-prop; - -webkit-mask-image: var(--chevron-down-svg); - mask-image: var(--chevron-down-svg); + @extend %with-mask, %chevron-down-16-svg-prop; + -webkit-mask-image: var(--chevron-down-16-svg); + mask-image: var(--chevron-down-16-svg); } %with-chevron-left-16-icon { @@ -1859,13 +1999,13 @@ } %with-chevron-left-icon { - @extend %with-icon, %chevron-left-svg-prop; - background-image: var(--chevron-left-svg); + @extend %with-icon, %chevron-left-16-svg-prop; + background-image: var(--chevron-left-16-svg); } %with-chevron-left-mask { - @extend %with-mask, %chevron-left-svg-prop; - -webkit-mask-image: var(--chevron-left-svg); - mask-image: var(--chevron-left-svg); + @extend %with-mask, %chevron-left-16-svg-prop; + -webkit-mask-image: var(--chevron-left-16-svg); + mask-image: var(--chevron-left-16-svg); } %with-chevron-right-16-icon { @@ -1889,13 +2029,13 @@ } %with-chevron-right-icon { - @extend %with-icon, %chevron-right-svg-prop; - background-image: var(--chevron-right-svg); + @extend %with-icon, %chevron-right-16-svg-prop; + background-image: var(--chevron-right-16-svg); } %with-chevron-right-mask { - @extend %with-mask, %chevron-right-svg-prop; - -webkit-mask-image: var(--chevron-right-svg); - mask-image: var(--chevron-right-svg); + @extend %with-mask, %chevron-right-16-svg-prop; + -webkit-mask-image: var(--chevron-right-16-svg); + mask-image: var(--chevron-right-16-svg); } %with-chevron-up-16-icon { @@ -1919,13 +2059,13 @@ } %with-chevron-up-icon { - @extend %with-icon, %chevron-up-svg-prop; - background-image: var(--chevron-up-svg); + @extend %with-icon, %chevron-up-16-svg-prop; + background-image: var(--chevron-up-16-svg); } %with-chevron-up-mask { - @extend %with-mask, %chevron-up-svg-prop; - -webkit-mask-image: var(--chevron-up-svg); - mask-image: var(--chevron-up-svg); + @extend %with-mask, %chevron-up-16-svg-prop; + -webkit-mask-image: var(--chevron-up-16-svg); + mask-image: var(--chevron-up-16-svg); } %with-chevrons-down-16-icon { @@ -2169,23 +2309,23 @@ } %with-clock-fill-icon { - @extend %with-icon, %clock-fill-svg-prop; - background-image: var(--clock-fill-svg); + @extend %with-icon, %clock-16-svg-prop; + background-image: var(--clock-16-svg); } %with-clock-fill-mask { - @extend %with-mask, %clock-fill-svg-prop; - -webkit-mask-image: var(--clock-fill-svg); - mask-image: var(--clock-fill-svg); + @extend %with-mask, %clock-16-svg-prop; + -webkit-mask-image: var(--clock-16-svg); + mask-image: var(--clock-16-svg); } %with-clock-outline-icon { - @extend %with-icon, %clock-outline-svg-prop; - background-image: var(--clock-outline-svg); + @extend %with-icon, %clock-16-svg-prop; + background-image: var(--clock-16-svg); } %with-clock-outline-mask { - @extend %with-mask, %clock-outline-svg-prop; - -webkit-mask-image: var(--clock-outline-svg); - mask-image: var(--clock-outline-svg); + @extend %with-mask, %clock-16-svg-prop; + -webkit-mask-image: var(--clock-16-svg); + mask-image: var(--clock-16-svg); } %with-cloud-16-icon { @@ -2379,13 +2519,53 @@ } %with-code-icon { - @extend %with-icon, %code-svg-prop; - background-image: var(--code-svg); + @extend %with-icon, %code-16-svg-prop; + background-image: var(--code-16-svg); } %with-code-mask { - @extend %with-mask, %code-svg-prop; - -webkit-mask-image: var(--code-svg); - mask-image: var(--code-svg); + @extend %with-mask, %code-16-svg-prop; + -webkit-mask-image: var(--code-16-svg); + mask-image: var(--code-16-svg); +} + +%with-codepen-16-icon { + @extend %with-icon, %codepen-16-svg-prop; + background-image: var(--codepen-16-svg); +} +%with-codepen-16-mask { + @extend %with-mask, %codepen-16-svg-prop; + -webkit-mask-image: var(--codepen-16-svg); + mask-image: var(--codepen-16-svg); +} + +%with-codepen-24-icon { + @extend %with-icon, %codepen-24-svg-prop; + background-image: var(--codepen-24-svg); +} +%with-codepen-24-mask { + @extend %with-mask, %codepen-24-svg-prop; + -webkit-mask-image: var(--codepen-24-svg); + mask-image: var(--codepen-24-svg); +} + +%with-codepen-color-16-icon { + @extend %with-icon, %codepen-color-16-svg-prop; + background-image: var(--codepen-color-16-svg); +} +%with-codepen-color-16-mask { + @extend %with-mask, %codepen-color-16-svg-prop; + -webkit-mask-image: var(--codepen-color-16-svg); + mask-image: var(--codepen-color-16-svg); +} + +%with-codepen-color-24-icon { + @extend %with-icon, %codepen-color-24-svg-prop; + background-image: var(--codepen-color-24-svg); +} +%with-codepen-color-24-mask { + @extend %with-mask, %codepen-color-24-svg-prop; + -webkit-mask-image: var(--codepen-color-24-svg); + mask-image: var(--codepen-color-24-svg); } %with-collections-16-icon { @@ -2489,33 +2669,73 @@ } %with-console-icon { - @extend %with-icon, %console-svg-prop; - background-image: var(--console-svg); + @extend %with-icon, %terminal-16-svg-prop; + background-image: var(--terminal-16-svg); } %with-console-mask { - @extend %with-mask, %console-svg-prop; - -webkit-mask-image: var(--console-svg); - mask-image: var(--console-svg); + @extend %with-mask, %terminal-16-svg-prop; + -webkit-mask-image: var(--terminal-16-svg); + mask-image: var(--terminal-16-svg); +} + +%with-consul-16-icon { + @extend %with-icon, %consul-16-svg-prop; + background-image: var(--consul-16-svg); +} +%with-consul-16-mask { + @extend %with-mask, %consul-16-svg-prop; + -webkit-mask-image: var(--consul-16-svg); + mask-image: var(--consul-16-svg); +} + +%with-consul-24-icon { + @extend %with-icon, %consul-24-svg-prop; + background-image: var(--consul-24-svg); +} +%with-consul-24-mask { + @extend %with-mask, %consul-24-svg-prop; + -webkit-mask-image: var(--consul-24-svg); + mask-image: var(--consul-24-svg); +} + +%with-consul-color-16-icon { + @extend %with-icon, %consul-color-16-svg-prop; + background-image: var(--consul-color-16-svg); +} +%with-consul-color-16-mask { + @extend %with-mask, %consul-color-16-svg-prop; + -webkit-mask-image: var(--consul-color-16-svg); + mask-image: var(--consul-color-16-svg); +} + +%with-consul-color-24-icon { + @extend %with-icon, %consul-color-24-svg-prop; + background-image: var(--consul-color-24-svg); +} +%with-consul-color-24-mask { + @extend %with-mask, %consul-color-24-svg-prop; + -webkit-mask-image: var(--consul-color-24-svg); + mask-image: var(--consul-color-24-svg); } %with-copy-action-icon { - @extend %with-icon, %copy-action-svg-prop; - background-image: var(--copy-action-svg); + @extend %with-icon, %clipboard-copy-16-svg-prop; + background-image: var(--clipboard-copy-16-svg); } %with-copy-action-mask { - @extend %with-mask, %copy-action-svg-prop; - -webkit-mask-image: var(--copy-action-svg); - mask-image: var(--copy-action-svg); + @extend %with-mask, %clipboard-copy-16-svg-prop; + -webkit-mask-image: var(--clipboard-copy-16-svg); + mask-image: var(--clipboard-copy-16-svg); } %with-copy-success-icon { - @extend %with-icon, %copy-success-svg-prop; - background-image: var(--copy-success-svg); + @extend %with-icon, %clipboard-checked-16-svg-prop; + background-image: var(--clipboard-checked-16-svg); } %with-copy-success-mask { - @extend %with-mask, %copy-success-svg-prop; - -webkit-mask-image: var(--copy-success-svg); - mask-image: var(--copy-success-svg); + @extend %with-mask, %clipboard-checked-16-svg-prop; + -webkit-mask-image: var(--clipboard-checked-16-svg); + mask-image: var(--clipboard-checked-16-svg); } %with-corner-down-left-16-icon { @@ -2799,13 +3019,13 @@ } %with-database-icon { - @extend %with-icon, %database-svg-prop; - background-image: var(--database-svg); + @extend %with-icon, %database-16-svg-prop; + background-image: var(--database-16-svg); } %with-database-mask { - @extend %with-mask, %database-svg-prop; - -webkit-mask-image: var(--database-svg); - mask-image: var(--database-svg); + @extend %with-mask, %database-16-svg-prop; + -webkit-mask-image: var(--database-16-svg); + mask-image: var(--database-16-svg); } %with-delay-16-icon { @@ -2829,13 +3049,13 @@ } %with-delay-icon { - @extend %with-icon, %delay-svg-prop; - background-image: var(--delay-svg); + @extend %with-icon, %delay-16-svg-prop; + background-image: var(--delay-16-svg); } %with-delay-mask { - @extend %with-mask, %delay-svg-prop; - -webkit-mask-image: var(--delay-svg); - mask-image: var(--delay-svg); + @extend %with-mask, %delay-16-svg-prop; + -webkit-mask-image: var(--delay-16-svg); + mask-image: var(--delay-16-svg); } %with-delete-16-icon { @@ -2859,13 +3079,13 @@ } %with-deny-alt-icon { - @extend %with-icon, %deny-alt-svg-prop; - background-image: var(--deny-alt-svg); + @extend %with-icon, %skip-16-svg-prop; + background-image: var(--skip-16-svg); } %with-deny-alt-mask { - @extend %with-mask, %deny-alt-svg-prop; - -webkit-mask-image: var(--deny-alt-svg); - mask-image: var(--deny-alt-svg); + @extend %with-mask, %skip-16-svg-prop; + -webkit-mask-image: var(--skip-16-svg); + mask-image: var(--skip-16-svg); } %with-deny-color-icon { @@ -2879,13 +3099,13 @@ } %with-deny-default-icon { - @extend %with-icon, %deny-default-svg-prop; - background-image: var(--deny-default-svg); + @extend %with-icon, %skip-16-svg-prop; + background-image: var(--skip-16-svg); } %with-deny-default-mask { - @extend %with-mask, %deny-default-svg-prop; - -webkit-mask-image: var(--deny-default-svg); - mask-image: var(--deny-default-svg); + @extend %with-mask, %skip-16-svg-prop; + -webkit-mask-image: var(--skip-16-svg); + mask-image: var(--skip-16-svg); } %with-diamond-16-icon { @@ -2929,13 +3149,13 @@ } %with-disabled-icon { - @extend %with-icon, %disabled-svg-prop; - background-image: var(--disabled-svg); + @extend %with-icon, %skip-16-svg-prop; + background-image: var(--skip-16-svg); } %with-disabled-mask { - @extend %with-mask, %disabled-svg-prop; - -webkit-mask-image: var(--disabled-svg); - mask-image: var(--disabled-svg); + @extend %with-mask, %skip-16-svg-prop; + -webkit-mask-image: var(--skip-16-svg); + mask-image: var(--skip-16-svg); } %with-disc-16-icon { @@ -3099,13 +3319,13 @@ } %with-docs-icon { - @extend %with-icon, %docs-svg-prop; - background-image: var(--docs-svg); + @extend %with-icon, %docs-link-16-svg-prop; + background-image: var(--docs-link-16-svg); } %with-docs-mask { - @extend %with-mask, %docs-svg-prop; - -webkit-mask-image: var(--docs-svg); - mask-image: var(--docs-svg); + @extend %with-mask, %docs-link-16-svg-prop; + -webkit-mask-image: var(--docs-link-16-svg); + mask-image: var(--docs-link-16-svg); } %with-dollar-sign-16-icon { @@ -3189,13 +3409,13 @@ } %with-download-icon { - @extend %with-icon, %download-svg-prop; - background-image: var(--download-svg); + @extend %with-icon, %download-16-svg-prop; + background-image: var(--download-16-svg); } %with-download-mask { - @extend %with-mask, %download-svg-prop; - -webkit-mask-image: var(--download-svg); - mask-image: var(--download-svg); + @extend %with-mask, %download-16-svg-prop; + -webkit-mask-image: var(--download-16-svg); + mask-image: var(--download-16-svg); } %with-droplet-16-icon { @@ -3259,13 +3479,13 @@ } %with-edit-icon { - @extend %with-icon, %edit-svg-prop; - background-image: var(--edit-svg); + @extend %with-icon, %edit-16-svg-prop; + background-image: var(--edit-16-svg); } %with-edit-mask { - @extend %with-mask, %edit-svg-prop; - -webkit-mask-image: var(--edit-svg); - mask-image: var(--edit-svg); + @extend %with-mask, %edit-16-svg-prop; + -webkit-mask-image: var(--edit-16-svg); + mask-image: var(--edit-16-svg); } %with-entry-point-16-icon { @@ -3289,43 +3509,43 @@ } %with-envelope-sealed-fill-icon { - @extend %with-icon, %envelope-sealed-fill-svg-prop; - background-image: var(--envelope-sealed-fill-svg); + @extend %with-icon, %mail-16-svg-prop; + background-image: var(--mail-16-svg); } %with-envelope-sealed-fill-mask { - @extend %with-mask, %envelope-sealed-fill-svg-prop; - -webkit-mask-image: var(--envelope-sealed-fill-svg); - mask-image: var(--envelope-sealed-fill-svg); + @extend %with-mask, %mail-16-svg-prop; + -webkit-mask-image: var(--mail-16-svg); + mask-image: var(--mail-16-svg); } %with-envelope-sealed-outline-icon { - @extend %with-icon, %envelope-sealed-outline-svg-prop; - background-image: var(--envelope-sealed-outline-svg); + @extend %with-icon, %mail-16-svg-prop; + background-image: var(--mail-16-svg); } %with-envelope-sealed-outline-mask { - @extend %with-mask, %envelope-sealed-outline-svg-prop; - -webkit-mask-image: var(--envelope-sealed-outline-svg); - mask-image: var(--envelope-sealed-outline-svg); + @extend %with-mask, %mail-16-svg-prop; + -webkit-mask-image: var(--mail-16-svg); + mask-image: var(--mail-16-svg); } %with-envelope-unsealed--outline-icon { - @extend %with-icon, %envelope-unsealed--outline-svg-prop; - background-image: var(--envelope-unsealed--outline-svg); + @extend %with-icon, %mail-open-16-svg-prop; + background-image: var(--mail-open-16-svg); } %with-envelope-unsealed--outline-mask { - @extend %with-mask, %envelope-unsealed--outline-svg-prop; - -webkit-mask-image: var(--envelope-unsealed--outline-svg); - mask-image: var(--envelope-unsealed--outline-svg); + @extend %with-mask, %mail-open-16-svg-prop; + -webkit-mask-image: var(--mail-open-16-svg); + mask-image: var(--mail-open-16-svg); } %with-envelope-unsealed-fill-icon { - @extend %with-icon, %envelope-unsealed-fill-svg-prop; - background-image: var(--envelope-unsealed-fill-svg); + @extend %with-icon, %mail-open-16-svg-prop; + background-image: var(--mail-open-16-svg); } %with-envelope-unsealed-fill-mask { - @extend %with-mask, %envelope-unsealed-fill-svg-prop; - -webkit-mask-image: var(--envelope-unsealed-fill-svg); - mask-image: var(--envelope-unsealed-fill-svg); + @extend %with-mask, %mail-open-16-svg-prop; + -webkit-mask-image: var(--mail-open-16-svg); + mask-image: var(--mail-open-16-svg); } %with-event-16-icon { @@ -3369,33 +3589,33 @@ } %with-exit-icon { - @extend %with-icon, %exit-svg-prop; - background-image: var(--exit-svg); + @extend %with-icon, %external-link-16-svg-prop; + background-image: var(--external-link-16-svg); } %with-exit-mask { - @extend %with-mask, %exit-svg-prop; - -webkit-mask-image: var(--exit-svg); - mask-image: var(--exit-svg); + @extend %with-mask, %external-link-16-svg-prop; + -webkit-mask-image: var(--external-link-16-svg); + mask-image: var(--external-link-16-svg); } %with-expand-less-icon { - @extend %with-icon, %expand-less-svg-prop; - background-image: var(--expand-less-svg); + @extend %with-icon, %minimize-16-svg-prop; + background-image: var(--minimize-16-svg); } %with-expand-less-mask { - @extend %with-mask, %expand-less-svg-prop; - -webkit-mask-image: var(--expand-less-svg); - mask-image: var(--expand-less-svg); + @extend %with-mask, %minimize-16-svg-prop; + -webkit-mask-image: var(--minimize-16-svg); + mask-image: var(--minimize-16-svg); } %with-expand-more-icon { - @extend %with-icon, %expand-more-svg-prop; - background-image: var(--expand-more-svg); + @extend %with-icon, %maximize-16-svg-prop; + background-image: var(--maximize-16-svg); } %with-expand-more-mask { - @extend %with-mask, %expand-more-svg-prop; - -webkit-mask-image: var(--expand-more-svg); - mask-image: var(--expand-more-svg); + @extend %with-mask, %maximize-16-svg-prop; + -webkit-mask-image: var(--maximize-16-svg); + mask-image: var(--maximize-16-svg); } %with-external-link-16-icon { @@ -3498,6 +3718,46 @@ mask-image: var(--f5-color-24-svg); } +%with-facebook-16-icon { + @extend %with-icon, %facebook-16-svg-prop; + background-image: var(--facebook-16-svg); +} +%with-facebook-16-mask { + @extend %with-mask, %facebook-16-svg-prop; + -webkit-mask-image: var(--facebook-16-svg); + mask-image: var(--facebook-16-svg); +} + +%with-facebook-24-icon { + @extend %with-icon, %facebook-24-svg-prop; + background-image: var(--facebook-24-svg); +} +%with-facebook-24-mask { + @extend %with-mask, %facebook-24-svg-prop; + -webkit-mask-image: var(--facebook-24-svg); + mask-image: var(--facebook-24-svg); +} + +%with-facebook-color-16-icon { + @extend %with-icon, %facebook-color-16-svg-prop; + background-image: var(--facebook-color-16-svg); +} +%with-facebook-color-16-mask { + @extend %with-mask, %facebook-color-16-svg-prop; + -webkit-mask-image: var(--facebook-color-16-svg); + mask-image: var(--facebook-color-16-svg); +} + +%with-facebook-color-24-icon { + @extend %with-icon, %facebook-color-24-svg-prop; + background-image: var(--facebook-color-24-svg); +} +%with-facebook-color-24-mask { + @extend %with-mask, %facebook-color-24-svg-prop; + -webkit-mask-image: var(--facebook-color-24-svg); + mask-image: var(--facebook-color-24-svg); +} + %with-fast-forward-16-icon { @extend %with-icon, %fast-forward-16-svg-prop; background-image: var(--fast-forward-16-svg); @@ -3599,13 +3859,13 @@ } %with-file-fill-icon { - @extend %with-icon, %file-fill-svg-prop; - background-image: var(--file-fill-svg); + @extend %with-icon, %file-16-svg-prop; + background-image: var(--file-16-svg); } %with-file-fill-mask { - @extend %with-mask, %file-fill-svg-prop; - -webkit-mask-image: var(--file-fill-svg); - mask-image: var(--file-fill-svg); + @extend %with-mask, %file-16-svg-prop; + -webkit-mask-image: var(--file-16-svg); + mask-image: var(--file-16-svg); } %with-file-minus-16-icon { @@ -3629,13 +3889,13 @@ } %with-file-outline-icon { - @extend %with-icon, %file-outline-svg-prop; - background-image: var(--file-outline-svg); + @extend %with-icon, %file-16-svg-prop; + background-image: var(--file-16-svg); } %with-file-outline-mask { - @extend %with-mask, %file-outline-svg-prop; - -webkit-mask-image: var(--file-outline-svg); - mask-image: var(--file-outline-svg); + @extend %with-mask, %file-16-svg-prop; + -webkit-mask-image: var(--file-16-svg); + mask-image: var(--file-16-svg); } %with-file-plus-16-icon { @@ -3819,13 +4079,13 @@ } %with-filter-icon { - @extend %with-icon, %filter-svg-prop; - background-image: var(--filter-svg); + @extend %with-icon, %filter-16-svg-prop; + background-image: var(--filter-16-svg); } %with-filter-mask { - @extend %with-mask, %filter-svg-prop; - -webkit-mask-image: var(--filter-svg); - mask-image: var(--filter-svg); + @extend %with-mask, %filter-16-svg-prop; + -webkit-mask-image: var(--filter-16-svg); + mask-image: var(--filter-16-svg); } %with-fingerprint-16-icon { @@ -3869,13 +4129,13 @@ } %with-flag-icon { - @extend %with-icon, %flag-svg-prop; - background-image: var(--flag-svg); + @extend %with-icon, %flag-16-svg-prop; + background-image: var(--flag-16-svg); } %with-flag-mask { - @extend %with-mask, %flag-svg-prop; - -webkit-mask-image: var(--flag-svg); - mask-image: var(--flag-svg); + @extend %with-mask, %flag-16-svg-prop; + -webkit-mask-image: var(--flag-16-svg); + mask-image: var(--flag-16-svg); } %with-folder-16-icon { @@ -3919,13 +4179,13 @@ } %with-folder-fill-icon { - @extend %with-icon, %folder-fill-svg-prop; - background-image: var(--folder-fill-svg); + @extend %with-icon, %folder-fill-16-svg-prop; + background-image: var(--folder-fill-16-svg); } %with-folder-fill-mask { - @extend %with-mask, %folder-fill-svg-prop; - -webkit-mask-image: var(--folder-fill-svg); - mask-image: var(--folder-fill-svg); + @extend %with-mask, %folder-fill-16-svg-prop; + -webkit-mask-image: var(--folder-fill-16-svg); + mask-image: var(--folder-fill-16-svg); } %with-folder-minus-16-icon { @@ -3969,13 +4229,13 @@ } %with-folder-outline-icon { - @extend %with-icon, %folder-outline-svg-prop; - background-image: var(--folder-outline-svg); + @extend %with-icon, %folder-16-svg-prop; + background-image: var(--folder-16-svg); } %with-folder-outline-mask { - @extend %with-mask, %folder-outline-svg-prop; - -webkit-mask-image: var(--folder-outline-svg); - mask-image: var(--folder-outline-svg); + @extend %with-mask, %folder-16-svg-prop; + -webkit-mask-image: var(--folder-16-svg); + mask-image: var(--folder-16-svg); } %with-folder-plus-16-icon { @@ -4099,13 +4359,13 @@ } %with-gateway-icon { - @extend %with-icon, %gateway-svg-prop; - background-image: var(--gateway-svg); + @extend %with-icon, %gateway-16-svg-prop; + background-image: var(--gateway-16-svg); } %with-gateway-mask { - @extend %with-mask, %gateway-svg-prop; - -webkit-mask-image: var(--gateway-svg); - mask-image: var(--gateway-svg); + @extend %with-mask, %gateway-16-svg-prop; + -webkit-mask-image: var(--gateway-16-svg); + mask-image: var(--gateway-16-svg); } %with-gcp-16-icon { @@ -4169,23 +4429,23 @@ } %with-gift-fill-icon { - @extend %with-icon, %gift-fill-svg-prop; - background-image: var(--gift-fill-svg); + @extend %with-icon, %gift-16-svg-prop; + background-image: var(--gift-16-svg); } %with-gift-fill-mask { - @extend %with-mask, %gift-fill-svg-prop; - -webkit-mask-image: var(--gift-fill-svg); - mask-image: var(--gift-fill-svg); + @extend %with-mask, %gift-16-svg-prop; + -webkit-mask-image: var(--gift-16-svg); + mask-image: var(--gift-16-svg); } %with-gift-outline-icon { - @extend %with-icon, %gift-outline-svg-prop; - background-image: var(--gift-outline-svg); + @extend %with-icon, %gift-16-svg-prop; + background-image: var(--gift-16-svg); } %with-gift-outline-mask { - @extend %with-mask, %gift-outline-svg-prop; - -webkit-mask-image: var(--gift-outline-svg); - mask-image: var(--gift-outline-svg); + @extend %with-mask, %gift-16-svg-prop; + -webkit-mask-image: var(--gift-16-svg); + mask-image: var(--gift-16-svg); } %with-git-branch-16-icon { @@ -4209,13 +4469,13 @@ } %with-git-branch-icon { - @extend %with-icon, %git-branch-svg-prop; - background-image: var(--git-branch-svg); + @extend %with-icon, %git-branch-16-svg-prop; + background-image: var(--git-branch-16-svg); } %with-git-branch-mask { - @extend %with-mask, %git-branch-svg-prop; - -webkit-mask-image: var(--git-branch-svg); - mask-image: var(--git-branch-svg); + @extend %with-mask, %git-branch-16-svg-prop; + -webkit-mask-image: var(--git-branch-16-svg); + mask-image: var(--git-branch-16-svg); } %with-git-commit-16-icon { @@ -4239,13 +4499,13 @@ } %with-git-commit-icon { - @extend %with-icon, %git-commit-svg-prop; - background-image: var(--git-commit-svg); + @extend %with-icon, %git-commit-16-svg-prop; + background-image: var(--git-commit-16-svg); } %with-git-commit-mask { - @extend %with-mask, %git-commit-svg-prop; - -webkit-mask-image: var(--git-commit-svg); - mask-image: var(--git-commit-svg); + @extend %with-mask, %git-commit-16-svg-prop; + -webkit-mask-image: var(--git-commit-16-svg); + mask-image: var(--git-commit-16-svg); } %with-git-merge-16-icon { @@ -4289,13 +4549,13 @@ } %with-git-pull-request-icon { - @extend %with-icon, %git-pull-request-svg-prop; - background-image: var(--git-pull-request-svg); + @extend %with-icon, %git-pull-request-16-svg-prop; + background-image: var(--git-pull-request-16-svg); } %with-git-pull-request-mask { - @extend %with-mask, %git-pull-request-svg-prop; - -webkit-mask-image: var(--git-pull-request-svg); - mask-image: var(--git-pull-request-svg); + @extend %with-mask, %git-pull-request-16-svg-prop; + -webkit-mask-image: var(--git-pull-request-16-svg); + mask-image: var(--git-pull-request-16-svg); } %with-git-repo-16-icon { @@ -4319,13 +4579,13 @@ } %with-git-repository-icon { - @extend %with-icon, %git-repository-svg-prop; - background-image: var(--git-repository-svg); + @extend %with-icon, %git-repo-16-svg-prop; + background-image: var(--git-repo-16-svg); } %with-git-repository-mask { - @extend %with-mask, %git-repository-svg-prop; - -webkit-mask-image: var(--git-repository-svg); - mask-image: var(--git-repository-svg); + @extend %with-mask, %git-repo-16-svg-prop; + -webkit-mask-image: var(--git-repo-16-svg); + mask-image: var(--git-repo-16-svg); } %with-github-16-icon { @@ -4569,13 +4829,13 @@ } %with-guide-icon { - @extend %with-icon, %guide-svg-prop; - background-image: var(--guide-svg); + @extend %with-icon, %guide-16-svg-prop; + background-image: var(--guide-16-svg); } %with-guide-mask { - @extend %with-mask, %guide-svg-prop; - -webkit-mask-image: var(--guide-svg); - mask-image: var(--guide-svg); + @extend %with-mask, %guide-16-svg-prop; + -webkit-mask-image: var(--guide-16-svg); + mask-image: var(--guide-16-svg); } %with-hammer-16-icon { @@ -4598,6 +4858,26 @@ mask-image: var(--hammer-24-svg); } +%with-handshake-16-icon { + @extend %with-icon, %handshake-16-svg-prop; + background-image: var(--handshake-16-svg); +} +%with-handshake-16-mask { + @extend %with-mask, %handshake-16-svg-prop; + -webkit-mask-image: var(--handshake-16-svg); + mask-image: var(--handshake-16-svg); +} + +%with-handshake-24-icon { + @extend %with-icon, %handshake-24-svg-prop; + background-image: var(--handshake-24-svg); +} +%with-handshake-24-mask { + @extend %with-mask, %handshake-24-svg-prop; + -webkit-mask-image: var(--handshake-24-svg); + mask-image: var(--handshake-24-svg); +} + %with-hard-drive-16-icon { @extend %with-icon, %hard-drive-16-svg-prop; background-image: var(--hard-drive-16-svg); @@ -4638,6 +4918,86 @@ mask-image: var(--hash-24-svg); } +%with-hashicorp-16-icon { + @extend %with-icon, %hashicorp-16-svg-prop; + background-image: var(--hashicorp-16-svg); +} +%with-hashicorp-16-mask { + @extend %with-mask, %hashicorp-16-svg-prop; + -webkit-mask-image: var(--hashicorp-16-svg); + mask-image: var(--hashicorp-16-svg); +} + +%with-hashicorp-24-icon { + @extend %with-icon, %hashicorp-24-svg-prop; + background-image: var(--hashicorp-24-svg); +} +%with-hashicorp-24-mask { + @extend %with-mask, %hashicorp-24-svg-prop; + -webkit-mask-image: var(--hashicorp-24-svg); + mask-image: var(--hashicorp-24-svg); +} + +%with-hashicorp-color-16-icon { + @extend %with-icon, %hashicorp-color-16-svg-prop; + background-image: var(--hashicorp-color-16-svg); +} +%with-hashicorp-color-16-mask { + @extend %with-mask, %hashicorp-color-16-svg-prop; + -webkit-mask-image: var(--hashicorp-color-16-svg); + mask-image: var(--hashicorp-color-16-svg); +} + +%with-hashicorp-color-24-icon { + @extend %with-icon, %hashicorp-color-24-svg-prop; + background-image: var(--hashicorp-color-24-svg); +} +%with-hashicorp-color-24-mask { + @extend %with-mask, %hashicorp-color-24-svg-prop; + -webkit-mask-image: var(--hashicorp-color-24-svg); + mask-image: var(--hashicorp-color-24-svg); +} + +%with-hcp-16-icon { + @extend %with-icon, %hcp-16-svg-prop; + background-image: var(--hcp-16-svg); +} +%with-hcp-16-mask { + @extend %with-mask, %hcp-16-svg-prop; + -webkit-mask-image: var(--hcp-16-svg); + mask-image: var(--hcp-16-svg); +} + +%with-hcp-24-icon { + @extend %with-icon, %hcp-24-svg-prop; + background-image: var(--hcp-24-svg); +} +%with-hcp-24-mask { + @extend %with-mask, %hcp-24-svg-prop; + -webkit-mask-image: var(--hcp-24-svg); + mask-image: var(--hcp-24-svg); +} + +%with-hcp-color-16-icon { + @extend %with-icon, %hcp-color-16-svg-prop; + background-image: var(--hcp-color-16-svg); +} +%with-hcp-color-16-mask { + @extend %with-mask, %hcp-color-16-svg-prop; + -webkit-mask-image: var(--hcp-color-16-svg); + mask-image: var(--hcp-color-16-svg); +} + +%with-hcp-color-24-icon { + @extend %with-icon, %hcp-color-24-svg-prop; + background-image: var(--hcp-color-24-svg); +} +%with-hcp-color-24-mask { + @extend %with-mask, %hcp-color-24-svg-prop; + -webkit-mask-image: var(--hcp-color-24-svg); + mask-image: var(--hcp-color-24-svg); +} + %with-headphones-16-icon { @extend %with-icon, %headphones-16-svg-prop; background-image: var(--headphones-16-svg); @@ -4659,13 +5019,13 @@ } %with-health-icon { - @extend %with-icon, %health-svg-prop; - background-image: var(--health-svg); + @extend %with-icon, %activity-16-svg-prop; + background-image: var(--activity-16-svg); } %with-health-mask { - @extend %with-mask, %health-svg-prop; - -webkit-mask-image: var(--health-svg); - mask-image: var(--health-svg); + @extend %with-mask, %activity-16-svg-prop; + -webkit-mask-image: var(--activity-16-svg); + mask-image: var(--activity-16-svg); } %with-heart-16-icon { @@ -4749,23 +5109,23 @@ } %with-help-circle-fill-icon { - @extend %with-icon, %help-circle-fill-svg-prop; - background-image: var(--help-circle-fill-svg); + @extend %with-icon, %help-16-svg-prop; + background-image: var(--help-16-svg); } %with-help-circle-fill-mask { - @extend %with-mask, %help-circle-fill-svg-prop; - -webkit-mask-image: var(--help-circle-fill-svg); - mask-image: var(--help-circle-fill-svg); + @extend %with-mask, %help-16-svg-prop; + -webkit-mask-image: var(--help-16-svg); + mask-image: var(--help-16-svg); } %with-help-circle-outline-icon { - @extend %with-icon, %help-circle-outline-svg-prop; - background-image: var(--help-circle-outline-svg); + @extend %with-icon, %help-16-svg-prop; + background-image: var(--help-16-svg); } %with-help-circle-outline-mask { - @extend %with-mask, %help-circle-outline-svg-prop; - -webkit-mask-image: var(--help-circle-outline-svg); - mask-image: var(--help-circle-outline-svg); + @extend %with-mask, %help-16-svg-prop; + -webkit-mask-image: var(--help-16-svg); + mask-image: var(--help-16-svg); } %with-hexagon-16-icon { @@ -4829,13 +5189,13 @@ } %with-history-icon { - @extend %with-icon, %history-svg-prop; - background-image: var(--history-svg); + @extend %with-icon, %history-16-svg-prop; + background-image: var(--history-16-svg); } %with-history-mask { - @extend %with-mask, %history-svg-prop; - -webkit-mask-image: var(--history-svg); - mask-image: var(--history-svg); + @extend %with-mask, %history-16-svg-prop; + -webkit-mask-image: var(--history-16-svg); + mask-image: var(--history-16-svg); } %with-home-16-icon { @@ -4979,23 +5339,23 @@ } %with-info-circle-fill-icon { - @extend %with-icon, %info-circle-fill-svg-prop; - background-image: var(--info-circle-fill-svg); + @extend %with-icon, %info-16-svg-prop; + background-image: var(--info-16-svg); } %with-info-circle-fill-mask { - @extend %with-mask, %info-circle-fill-svg-prop; - -webkit-mask-image: var(--info-circle-fill-svg); - mask-image: var(--info-circle-fill-svg); + @extend %with-mask, %info-16-svg-prop; + -webkit-mask-image: var(--info-16-svg); + mask-image: var(--info-16-svg); } %with-info-circle-outline-icon { - @extend %with-icon, %info-circle-outline-svg-prop; - background-image: var(--info-circle-outline-svg); + @extend %with-icon, %info-16-svg-prop; + background-image: var(--info-16-svg); } %with-info-circle-outline-mask { - @extend %with-mask, %info-circle-outline-svg-prop; - -webkit-mask-image: var(--info-circle-outline-svg); - mask-image: var(--info-circle-outline-svg); + @extend %with-mask, %info-16-svg-prop; + -webkit-mask-image: var(--info-16-svg); + mask-image: var(--info-16-svg); } %with-jump-link-16-icon { @@ -5059,13 +5419,33 @@ } %with-key-icon { - @extend %with-icon, %key-svg-prop; - background-image: var(--key-svg); + @extend %with-icon, %key-16-svg-prop; + background-image: var(--key-16-svg); } %with-key-mask { - @extend %with-mask, %key-svg-prop; - -webkit-mask-image: var(--key-svg); - mask-image: var(--key-svg); + @extend %with-mask, %key-16-svg-prop; + -webkit-mask-image: var(--key-16-svg); + mask-image: var(--key-16-svg); +} + +%with-keychain-16-icon { + @extend %with-icon, %keychain-16-svg-prop; + background-image: var(--keychain-16-svg); +} +%with-keychain-16-mask { + @extend %with-mask, %keychain-16-svg-prop; + -webkit-mask-image: var(--keychain-16-svg); + mask-image: var(--keychain-16-svg); +} + +%with-keychain-24-icon { + @extend %with-icon, %keychain-24-svg-prop; + background-image: var(--keychain-24-svg); +} +%with-keychain-24-mask { + @extend %with-mask, %keychain-24-svg-prop; + -webkit-mask-image: var(--keychain-24-svg); + mask-image: var(--keychain-24-svg); } %with-kubernetes-16-icon { @@ -5149,13 +5529,13 @@ } %with-layers-icon { - @extend %with-icon, %layers-svg-prop; - background-image: var(--layers-svg); + @extend %with-icon, %layers-16-svg-prop; + background-image: var(--layers-16-svg); } %with-layers-mask { - @extend %with-mask, %layers-svg-prop; - -webkit-mask-image: var(--layers-svg); - mask-image: var(--layers-svg); + @extend %with-mask, %layers-16-svg-prop; + -webkit-mask-image: var(--layers-16-svg); + mask-image: var(--layers-16-svg); } %with-layout-16-icon { @@ -5219,13 +5599,13 @@ } %with-learn-icon { - @extend %with-icon, %learn-svg-prop; - background-image: var(--learn-svg); + @extend %with-icon, %learn-16-svg-prop; + background-image: var(--learn-16-svg); } %with-learn-mask { - @extend %with-mask, %learn-svg-prop; - -webkit-mask-image: var(--learn-svg); - mask-image: var(--learn-svg); + @extend %with-mask, %learn-16-svg-prop; + -webkit-mask-image: var(--learn-16-svg); + mask-image: var(--learn-16-svg); } %with-line-chart-16-icon { @@ -5289,13 +5669,53 @@ } %with-link-icon { - @extend %with-icon, %link-svg-prop; - background-image: var(--link-svg); + @extend %with-icon, %link-16-svg-prop; + background-image: var(--link-16-svg); } %with-link-mask { - @extend %with-mask, %link-svg-prop; - -webkit-mask-image: var(--link-svg); - mask-image: var(--link-svg); + @extend %with-mask, %link-16-svg-prop; + -webkit-mask-image: var(--link-16-svg); + mask-image: var(--link-16-svg); +} + +%with-linkedin-16-icon { + @extend %with-icon, %linkedin-16-svg-prop; + background-image: var(--linkedin-16-svg); +} +%with-linkedin-16-mask { + @extend %with-mask, %linkedin-16-svg-prop; + -webkit-mask-image: var(--linkedin-16-svg); + mask-image: var(--linkedin-16-svg); +} + +%with-linkedin-24-icon { + @extend %with-icon, %linkedin-24-svg-prop; + background-image: var(--linkedin-24-svg); +} +%with-linkedin-24-mask { + @extend %with-mask, %linkedin-24-svg-prop; + -webkit-mask-image: var(--linkedin-24-svg); + mask-image: var(--linkedin-24-svg); +} + +%with-linkedin-color-16-icon { + @extend %with-icon, %linkedin-color-16-svg-prop; + background-image: var(--linkedin-color-16-svg); +} +%with-linkedin-color-16-mask { + @extend %with-mask, %linkedin-color-16-svg-prop; + -webkit-mask-image: var(--linkedin-color-16-svg); + mask-image: var(--linkedin-color-16-svg); +} + +%with-linkedin-color-24-icon { + @extend %with-icon, %linkedin-color-24-svg-prop; + background-image: var(--linkedin-color-24-svg); +} +%with-linkedin-color-24-mask { + @extend %with-mask, %linkedin-color-24-svg-prop; + -webkit-mask-image: var(--linkedin-color-24-svg); + mask-image: var(--linkedin-color-24-svg); } %with-list-16-icon { @@ -5318,6 +5738,26 @@ mask-image: var(--list-24-svg); } +%with-load-balancer-16-icon { + @extend %with-icon, %load-balancer-16-svg-prop; + background-image: var(--load-balancer-16-svg); +} +%with-load-balancer-16-mask { + @extend %with-mask, %load-balancer-16-svg-prop; + -webkit-mask-image: var(--load-balancer-16-svg); + mask-image: var(--load-balancer-16-svg); +} + +%with-load-balancer-24-icon { + @extend %with-icon, %load-balancer-24-svg-prop; + background-image: var(--load-balancer-24-svg); +} +%with-load-balancer-24-mask { + @extend %with-mask, %load-balancer-24-svg-prop; + -webkit-mask-image: var(--load-balancer-24-svg); + mask-image: var(--load-balancer-24-svg); +} + %with-loading-icon { @extend %with-icon, %loading-svg-prop; background-image: var(--loading-svg); @@ -5349,43 +5789,43 @@ } %with-lock-closed-fill-icon { - @extend %with-icon, %lock-closed-fill-svg-prop; - background-image: var(--lock-closed-fill-svg); + @extend %with-icon, %lock-fill-16-svg-prop; + background-image: var(--lock-fill-16-svg); } %with-lock-closed-fill-mask { - @extend %with-mask, %lock-closed-fill-svg-prop; - -webkit-mask-image: var(--lock-closed-fill-svg); - mask-image: var(--lock-closed-fill-svg); + @extend %with-mask, %lock-fill-16-svg-prop; + -webkit-mask-image: var(--lock-fill-16-svg); + mask-image: var(--lock-fill-16-svg); } %with-lock-closed-outline-icon { - @extend %with-icon, %lock-closed-outline-svg-prop; - background-image: var(--lock-closed-outline-svg); + @extend %with-icon, %lock-16-svg-prop; + background-image: var(--lock-16-svg); } %with-lock-closed-outline-mask { - @extend %with-mask, %lock-closed-outline-svg-prop; - -webkit-mask-image: var(--lock-closed-outline-svg); - mask-image: var(--lock-closed-outline-svg); + @extend %with-mask, %lock-16-svg-prop; + -webkit-mask-image: var(--lock-16-svg); + mask-image: var(--lock-16-svg); } %with-lock-closed-icon { - @extend %with-icon, %lock-closed-svg-prop; - background-image: var(--lock-closed-svg); + @extend %with-icon, %lock-fill-16-svg-prop; + background-image: var(--lock-fill-16-svg); } %with-lock-closed-mask { - @extend %with-mask, %lock-closed-svg-prop; - -webkit-mask-image: var(--lock-closed-svg); - mask-image: var(--lock-closed-svg); + @extend %with-mask, %lock-fill-16-svg-prop; + -webkit-mask-image: var(--lock-fill-16-svg); + mask-image: var(--lock-fill-16-svg); } %with-lock-disabled-icon { - @extend %with-icon, %lock-disabled-svg-prop; - background-image: var(--lock-disabled-svg); + @extend %with-icon, %lock-off-16-svg-prop; + background-image: var(--lock-off-16-svg); } %with-lock-disabled-mask { - @extend %with-mask, %lock-disabled-svg-prop; - -webkit-mask-image: var(--lock-disabled-svg); - mask-image: var(--lock-disabled-svg); + @extend %with-mask, %lock-off-16-svg-prop; + -webkit-mask-image: var(--lock-off-16-svg); + mask-image: var(--lock-off-16-svg); } %with-lock-fill-16-icon { @@ -5429,133 +5869,133 @@ } %with-lock-open-icon { - @extend %with-icon, %lock-open-svg-prop; - background-image: var(--lock-open-svg); + @extend %with-icon, %unlock-16-svg-prop; + background-image: var(--unlock-16-svg); } %with-lock-open-mask { - @extend %with-mask, %lock-open-svg-prop; - -webkit-mask-image: var(--lock-open-svg); - mask-image: var(--lock-open-svg); + @extend %with-mask, %unlock-16-svg-prop; + -webkit-mask-image: var(--unlock-16-svg); + mask-image: var(--unlock-16-svg); } %with-logo-alicloud-color-icon { - @extend %with-icon, %logo-alicloud-color-svg-prop; - background-image: var(--logo-alicloud-color-svg); + @extend %with-icon, %alibaba-color-16-svg-prop; + background-image: var(--alibaba-color-16-svg); } %with-logo-alicloud-color-mask { - @extend %with-mask, %logo-alicloud-color-svg-prop; - -webkit-mask-image: var(--logo-alicloud-color-svg); - mask-image: var(--logo-alicloud-color-svg); + @extend %with-mask, %alibaba-color-16-svg-prop; + -webkit-mask-image: var(--alibaba-color-16-svg); + mask-image: var(--alibaba-color-16-svg); } %with-logo-alicloud-monochrome-icon { - @extend %with-icon, %logo-alicloud-monochrome-svg-prop; - background-image: var(--logo-alicloud-monochrome-svg); + @extend %with-icon, %alibaba-16-svg-prop; + background-image: var(--alibaba-16-svg); } %with-logo-alicloud-monochrome-mask { - @extend %with-mask, %logo-alicloud-monochrome-svg-prop; - -webkit-mask-image: var(--logo-alicloud-monochrome-svg); - mask-image: var(--logo-alicloud-monochrome-svg); + @extend %with-mask, %alibaba-16-svg-prop; + -webkit-mask-image: var(--alibaba-16-svg); + mask-image: var(--alibaba-16-svg); } %with-logo-auth0-color-icon { - @extend %with-icon, %logo-auth0-color-svg-prop; - background-image: var(--logo-auth0-color-svg); + @extend %with-icon, %auth0-color-16-svg-prop; + background-image: var(--auth0-color-16-svg); } %with-logo-auth0-color-mask { - @extend %with-mask, %logo-auth0-color-svg-prop; - -webkit-mask-image: var(--logo-auth0-color-svg); - mask-image: var(--logo-auth0-color-svg); + @extend %with-mask, %auth0-color-16-svg-prop; + -webkit-mask-image: var(--auth0-color-16-svg); + mask-image: var(--auth0-color-16-svg); } %with-logo-aws-color-icon { - @extend %with-icon, %logo-aws-color-svg-prop; - background-image: var(--logo-aws-color-svg); + @extend %with-icon, %aws-color-16-svg-prop; + background-image: var(--aws-color-16-svg); } %with-logo-aws-color-mask { - @extend %with-mask, %logo-aws-color-svg-prop; - -webkit-mask-image: var(--logo-aws-color-svg); - mask-image: var(--logo-aws-color-svg); + @extend %with-mask, %aws-color-16-svg-prop; + -webkit-mask-image: var(--aws-color-16-svg); + mask-image: var(--aws-color-16-svg); } %with-logo-aws-monochrome-icon { - @extend %with-icon, %logo-aws-monochrome-svg-prop; - background-image: var(--logo-aws-monochrome-svg); + @extend %with-icon, %aws-16-svg-prop; + background-image: var(--aws-16-svg); } %with-logo-aws-monochrome-mask { - @extend %with-mask, %logo-aws-monochrome-svg-prop; - -webkit-mask-image: var(--logo-aws-monochrome-svg); - mask-image: var(--logo-aws-monochrome-svg); + @extend %with-mask, %aws-16-svg-prop; + -webkit-mask-image: var(--aws-16-svg); + mask-image: var(--aws-16-svg); } %with-logo-azure-color-icon { - @extend %with-icon, %logo-azure-color-svg-prop; - background-image: var(--logo-azure-color-svg); + @extend %with-icon, %azure-color-16-svg-prop; + background-image: var(--azure-color-16-svg); } %with-logo-azure-color-mask { - @extend %with-mask, %logo-azure-color-svg-prop; - -webkit-mask-image: var(--logo-azure-color-svg); - mask-image: var(--logo-azure-color-svg); + @extend %with-mask, %azure-color-16-svg-prop; + -webkit-mask-image: var(--azure-color-16-svg); + mask-image: var(--azure-color-16-svg); } %with-logo-azure-dev-ops-color-icon { - @extend %with-icon, %logo-azure-dev-ops-color-svg-prop; - background-image: var(--logo-azure-dev-ops-color-svg); + @extend %with-icon, %azure-devops-color-16-svg-prop; + background-image: var(--azure-devops-color-16-svg); } %with-logo-azure-dev-ops-color-mask { - @extend %with-mask, %logo-azure-dev-ops-color-svg-prop; - -webkit-mask-image: var(--logo-azure-dev-ops-color-svg); - mask-image: var(--logo-azure-dev-ops-color-svg); + @extend %with-mask, %azure-devops-color-16-svg-prop; + -webkit-mask-image: var(--azure-devops-color-16-svg); + mask-image: var(--azure-devops-color-16-svg); } %with-logo-azure-dev-ops-monochrome-icon { - @extend %with-icon, %logo-azure-dev-ops-monochrome-svg-prop; - background-image: var(--logo-azure-dev-ops-monochrome-svg); + @extend %with-icon, %azure-devops-16-svg-prop; + background-image: var(--azure-devops-16-svg); } %with-logo-azure-dev-ops-monochrome-mask { - @extend %with-mask, %logo-azure-dev-ops-monochrome-svg-prop; - -webkit-mask-image: var(--logo-azure-dev-ops-monochrome-svg); - mask-image: var(--logo-azure-dev-ops-monochrome-svg); + @extend %with-mask, %azure-devops-16-svg-prop; + -webkit-mask-image: var(--azure-devops-16-svg); + mask-image: var(--azure-devops-16-svg); } %with-logo-azure-monochrome-icon { - @extend %with-icon, %logo-azure-monochrome-svg-prop; - background-image: var(--logo-azure-monochrome-svg); + @extend %with-icon, %azure-16-svg-prop; + background-image: var(--azure-16-svg); } %with-logo-azure-monochrome-mask { - @extend %with-mask, %logo-azure-monochrome-svg-prop; - -webkit-mask-image: var(--logo-azure-monochrome-svg); - mask-image: var(--logo-azure-monochrome-svg); + @extend %with-mask, %azure-16-svg-prop; + -webkit-mask-image: var(--azure-16-svg); + mask-image: var(--azure-16-svg); } %with-logo-bitbucket-color-icon { - @extend %with-icon, %logo-bitbucket-color-svg-prop; - background-image: var(--logo-bitbucket-color-svg); + @extend %with-icon, %bitbucket-color-16-svg-prop; + background-image: var(--bitbucket-color-16-svg); } %with-logo-bitbucket-color-mask { - @extend %with-mask, %logo-bitbucket-color-svg-prop; - -webkit-mask-image: var(--logo-bitbucket-color-svg); - mask-image: var(--logo-bitbucket-color-svg); + @extend %with-mask, %bitbucket-color-16-svg-prop; + -webkit-mask-image: var(--bitbucket-color-16-svg); + mask-image: var(--bitbucket-color-16-svg); } %with-logo-bitbucket-monochrome-icon { - @extend %with-icon, %logo-bitbucket-monochrome-svg-prop; - background-image: var(--logo-bitbucket-monochrome-svg); + @extend %with-icon, %bitbucket-16-svg-prop; + background-image: var(--bitbucket-16-svg); } %with-logo-bitbucket-monochrome-mask { - @extend %with-mask, %logo-bitbucket-monochrome-svg-prop; - -webkit-mask-image: var(--logo-bitbucket-monochrome-svg); - mask-image: var(--logo-bitbucket-monochrome-svg); + @extend %with-mask, %bitbucket-16-svg-prop; + -webkit-mask-image: var(--bitbucket-16-svg); + mask-image: var(--bitbucket-16-svg); } %with-logo-consul-color-icon { - @extend %with-icon, %logo-consul-color-svg-prop; - background-image: var(--logo-consul-color-svg); + @extend %with-icon, %consul-color-16-svg-prop; + background-image: var(--consul-color-16-svg); } %with-logo-consul-color-mask { - @extend %with-mask, %logo-consul-color-svg-prop; - -webkit-mask-image: var(--logo-consul-color-svg); - mask-image: var(--logo-consul-color-svg); + @extend %with-mask, %consul-color-16-svg-prop; + -webkit-mask-image: var(--consul-color-16-svg); + mask-image: var(--consul-color-16-svg); } %with-logo-ember-circle-color-icon { @@ -5569,63 +6009,63 @@ } %with-logo-gcp-color-icon { - @extend %with-icon, %logo-gcp-color-svg-prop; - background-image: var(--logo-gcp-color-svg); + @extend %with-icon, %gcp-color-16-svg-prop; + background-image: var(--gcp-color-16-svg); } %with-logo-gcp-color-mask { - @extend %with-mask, %logo-gcp-color-svg-prop; - -webkit-mask-image: var(--logo-gcp-color-svg); - mask-image: var(--logo-gcp-color-svg); + @extend %with-mask, %gcp-color-16-svg-prop; + -webkit-mask-image: var(--gcp-color-16-svg); + mask-image: var(--gcp-color-16-svg); } %with-logo-gcp-monochrome-icon { - @extend %with-icon, %logo-gcp-monochrome-svg-prop; - background-image: var(--logo-gcp-monochrome-svg); + @extend %with-icon, %gcp-16-svg-prop; + background-image: var(--gcp-16-svg); } %with-logo-gcp-monochrome-mask { - @extend %with-mask, %logo-gcp-monochrome-svg-prop; - -webkit-mask-image: var(--logo-gcp-monochrome-svg); - mask-image: var(--logo-gcp-monochrome-svg); + @extend %with-mask, %gcp-16-svg-prop; + -webkit-mask-image: var(--gcp-16-svg); + mask-image: var(--gcp-16-svg); } %with-logo-github-color-icon { - @extend %with-icon, %logo-github-color-svg-prop; - background-image: var(--logo-github-color-svg); + @extend %with-icon, %github-color-16-svg-prop; + background-image: var(--github-color-16-svg); } %with-logo-github-color-mask { - @extend %with-mask, %logo-github-color-svg-prop; - -webkit-mask-image: var(--logo-github-color-svg); - mask-image: var(--logo-github-color-svg); + @extend %with-mask, %github-color-16-svg-prop; + -webkit-mask-image: var(--github-color-16-svg); + mask-image: var(--github-color-16-svg); } %with-logo-github-monochrome-icon { - @extend %with-icon, %logo-github-monochrome-svg-prop; - background-image: var(--logo-github-monochrome-svg); + @extend %with-icon, %github-16-svg-prop; + background-image: var(--github-16-svg); } %with-logo-github-monochrome-mask { - @extend %with-mask, %logo-github-monochrome-svg-prop; - -webkit-mask-image: var(--logo-github-monochrome-svg); - mask-image: var(--logo-github-monochrome-svg); + @extend %with-mask, %github-16-svg-prop; + -webkit-mask-image: var(--github-16-svg); + mask-image: var(--github-16-svg); } %with-logo-gitlab-color-icon { - @extend %with-icon, %logo-gitlab-color-svg-prop; - background-image: var(--logo-gitlab-color-svg); + @extend %with-icon, %gitlab-color-16-svg-prop; + background-image: var(--gitlab-color-16-svg); } %with-logo-gitlab-color-mask { - @extend %with-mask, %logo-gitlab-color-svg-prop; - -webkit-mask-image: var(--logo-gitlab-color-svg); - mask-image: var(--logo-gitlab-color-svg); + @extend %with-mask, %gitlab-color-16-svg-prop; + -webkit-mask-image: var(--gitlab-color-16-svg); + mask-image: var(--gitlab-color-16-svg); } %with-logo-gitlab-monochrome-icon { - @extend %with-icon, %logo-gitlab-monochrome-svg-prop; - background-image: var(--logo-gitlab-monochrome-svg); + @extend %with-icon, %gitlab-16-svg-prop; + background-image: var(--gitlab-16-svg); } %with-logo-gitlab-monochrome-mask { - @extend %with-mask, %logo-gitlab-monochrome-svg-prop; - -webkit-mask-image: var(--logo-gitlab-monochrome-svg); - mask-image: var(--logo-gitlab-monochrome-svg); + @extend %with-mask, %gitlab-16-svg-prop; + -webkit-mask-image: var(--gitlab-16-svg); + mask-image: var(--gitlab-16-svg); } %with-logo-glimmer-color-icon { @@ -5639,23 +6079,23 @@ } %with-logo-google-color-icon { - @extend %with-icon, %logo-google-color-svg-prop; - background-image: var(--logo-google-color-svg); + @extend %with-icon, %google-color-16-svg-prop; + background-image: var(--google-color-16-svg); } %with-logo-google-color-mask { - @extend %with-mask, %logo-google-color-svg-prop; - -webkit-mask-image: var(--logo-google-color-svg); - mask-image: var(--logo-google-color-svg); + @extend %with-mask, %google-color-16-svg-prop; + -webkit-mask-image: var(--google-color-16-svg); + mask-image: var(--google-color-16-svg); } %with-logo-google-monochrome-icon { - @extend %with-icon, %logo-google-monochrome-svg-prop; - background-image: var(--logo-google-monochrome-svg); + @extend %with-icon, %google-16-svg-prop; + background-image: var(--google-16-svg); } %with-logo-google-monochrome-mask { - @extend %with-mask, %logo-google-monochrome-svg-prop; - -webkit-mask-image: var(--logo-google-monochrome-svg); - mask-image: var(--logo-google-monochrome-svg); + @extend %with-mask, %google-16-svg-prop; + -webkit-mask-image: var(--google-16-svg); + mask-image: var(--google-16-svg); } %with-logo-hashicorp-color-icon { @@ -5679,43 +6119,43 @@ } %with-logo-kubernetes-color-icon { - @extend %with-icon, %logo-kubernetes-color-svg-prop; - background-image: var(--logo-kubernetes-color-svg); + @extend %with-icon, %kubernetes-color-16-svg-prop; + background-image: var(--kubernetes-color-16-svg); } %with-logo-kubernetes-color-mask { - @extend %with-mask, %logo-kubernetes-color-svg-prop; - -webkit-mask-image: var(--logo-kubernetes-color-svg); - mask-image: var(--logo-kubernetes-color-svg); + @extend %with-mask, %kubernetes-color-16-svg-prop; + -webkit-mask-image: var(--kubernetes-color-16-svg); + mask-image: var(--kubernetes-color-16-svg); } %with-logo-kubernetes-monochrome-icon { - @extend %with-icon, %logo-kubernetes-monochrome-svg-prop; - background-image: var(--logo-kubernetes-monochrome-svg); + @extend %with-icon, %kubernetes-16-svg-prop; + background-image: var(--kubernetes-16-svg); } %with-logo-kubernetes-monochrome-mask { - @extend %with-mask, %logo-kubernetes-monochrome-svg-prop; - -webkit-mask-image: var(--logo-kubernetes-monochrome-svg); - mask-image: var(--logo-kubernetes-monochrome-svg); + @extend %with-mask, %kubernetes-16-svg-prop; + -webkit-mask-image: var(--kubernetes-16-svg); + mask-image: var(--kubernetes-16-svg); } %with-logo-microsoft-color-icon { - @extend %with-icon, %logo-microsoft-color-svg-prop; - background-image: var(--logo-microsoft-color-svg); + @extend %with-icon, %microsoft-color-16-svg-prop; + background-image: var(--microsoft-color-16-svg); } %with-logo-microsoft-color-mask { - @extend %with-mask, %logo-microsoft-color-svg-prop; - -webkit-mask-image: var(--logo-microsoft-color-svg); - mask-image: var(--logo-microsoft-color-svg); + @extend %with-mask, %microsoft-color-16-svg-prop; + -webkit-mask-image: var(--microsoft-color-16-svg); + mask-image: var(--microsoft-color-16-svg); } %with-logo-nomad-color-icon { - @extend %with-icon, %logo-nomad-color-svg-prop; - background-image: var(--logo-nomad-color-svg); + @extend %with-icon, %nomad-color-16-svg-prop; + background-image: var(--nomad-color-16-svg); } %with-logo-nomad-color-mask { - @extend %with-mask, %logo-nomad-color-svg-prop; - -webkit-mask-image: var(--logo-nomad-color-svg); - mask-image: var(--logo-nomad-color-svg); + @extend %with-mask, %nomad-color-16-svg-prop; + -webkit-mask-image: var(--nomad-color-16-svg); + mask-image: var(--nomad-color-16-svg); } %with-logo-oidc-color-icon { @@ -5729,63 +6169,63 @@ } %with-logo-okta-color-icon { - @extend %with-icon, %logo-okta-color-svg-prop; - background-image: var(--logo-okta-color-svg); + @extend %with-icon, %okta-color-16-svg-prop; + background-image: var(--okta-color-16-svg); } %with-logo-okta-color-mask { - @extend %with-mask, %logo-okta-color-svg-prop; - -webkit-mask-image: var(--logo-okta-color-svg); - mask-image: var(--logo-okta-color-svg); + @extend %with-mask, %okta-color-16-svg-prop; + -webkit-mask-image: var(--okta-color-16-svg); + mask-image: var(--okta-color-16-svg); } %with-logo-oracle-color-icon { - @extend %with-icon, %logo-oracle-color-svg-prop; - background-image: var(--logo-oracle-color-svg); + @extend %with-icon, %oracle-color-16-svg-prop; + background-image: var(--oracle-color-16-svg); } %with-logo-oracle-color-mask { - @extend %with-mask, %logo-oracle-color-svg-prop; - -webkit-mask-image: var(--logo-oracle-color-svg); - mask-image: var(--logo-oracle-color-svg); + @extend %with-mask, %oracle-color-16-svg-prop; + -webkit-mask-image: var(--oracle-color-16-svg); + mask-image: var(--oracle-color-16-svg); } %with-logo-oracle-monochrome-icon { - @extend %with-icon, %logo-oracle-monochrome-svg-prop; - background-image: var(--logo-oracle-monochrome-svg); + @extend %with-icon, %oracle-16-svg-prop; + background-image: var(--oracle-16-svg); } %with-logo-oracle-monochrome-mask { - @extend %with-mask, %logo-oracle-monochrome-svg-prop; - -webkit-mask-image: var(--logo-oracle-monochrome-svg); - mask-image: var(--logo-oracle-monochrome-svg); + @extend %with-mask, %oracle-16-svg-prop; + -webkit-mask-image: var(--oracle-16-svg); + mask-image: var(--oracle-16-svg); } %with-logo-slack-color-icon { - @extend %with-icon, %logo-slack-color-svg-prop; - background-image: var(--logo-slack-color-svg); + @extend %with-icon, %slack-color-16-svg-prop; + background-image: var(--slack-color-16-svg); } %with-logo-slack-color-mask { - @extend %with-mask, %logo-slack-color-svg-prop; - -webkit-mask-image: var(--logo-slack-color-svg); - mask-image: var(--logo-slack-color-svg); + @extend %with-mask, %slack-color-16-svg-prop; + -webkit-mask-image: var(--slack-color-16-svg); + mask-image: var(--slack-color-16-svg); } %with-logo-slack-monochrome-icon { - @extend %with-icon, %logo-slack-monochrome-svg-prop; - background-image: var(--logo-slack-monochrome-svg); + @extend %with-icon, %slack-16-svg-prop; + background-image: var(--slack-16-svg); } %with-logo-slack-monochrome-mask { - @extend %with-mask, %logo-slack-monochrome-svg-prop; - -webkit-mask-image: var(--logo-slack-monochrome-svg); - mask-image: var(--logo-slack-monochrome-svg); + @extend %with-mask, %slack-16-svg-prop; + -webkit-mask-image: var(--slack-16-svg); + mask-image: var(--slack-16-svg); } %with-logo-terraform-color-icon { - @extend %with-icon, %logo-terraform-color-svg-prop; - background-image: var(--logo-terraform-color-svg); + @extend %with-icon, %terraform-color-16-svg-prop; + background-image: var(--terraform-color-16-svg); } %with-logo-terraform-color-mask { - @extend %with-mask, %logo-terraform-color-svg-prop; - -webkit-mask-image: var(--logo-terraform-color-svg); - mask-image: var(--logo-terraform-color-svg); + @extend %with-mask, %terraform-color-16-svg-prop; + -webkit-mask-image: var(--terraform-color-16-svg); + mask-image: var(--terraform-color-16-svg); } %with-logo-vault-color-icon { @@ -5799,23 +6239,23 @@ } %with-logo-vmware-color-icon { - @extend %with-icon, %logo-vmware-color-svg-prop; - background-image: var(--logo-vmware-color-svg); + @extend %with-icon, %vmware-color-16-svg-prop; + background-image: var(--vmware-color-16-svg); } %with-logo-vmware-color-mask { - @extend %with-mask, %logo-vmware-color-svg-prop; - -webkit-mask-image: var(--logo-vmware-color-svg); - mask-image: var(--logo-vmware-color-svg); + @extend %with-mask, %vmware-color-16-svg-prop; + -webkit-mask-image: var(--vmware-color-16-svg); + mask-image: var(--vmware-color-16-svg); } %with-logo-vmware-monochrome-icon { - @extend %with-icon, %logo-vmware-monochrome-svg-prop; - background-image: var(--logo-vmware-monochrome-svg); + @extend %with-icon, %vmware-16-svg-prop; + background-image: var(--vmware-16-svg); } %with-logo-vmware-monochrome-mask { - @extend %with-mask, %logo-vmware-monochrome-svg-prop; - -webkit-mask-image: var(--logo-vmware-monochrome-svg); - mask-image: var(--logo-vmware-monochrome-svg); + @extend %with-mask, %vmware-16-svg-prop; + -webkit-mask-image: var(--vmware-16-svg); + mask-image: var(--vmware-16-svg); } %with-mail-16-icon { @@ -5858,6 +6298,26 @@ mask-image: var(--mail-open-24-svg); } +%with-mainframe-16-icon { + @extend %with-icon, %mainframe-16-svg-prop; + background-image: var(--mainframe-16-svg); +} +%with-mainframe-16-mask { + @extend %with-mask, %mainframe-16-svg-prop; + -webkit-mask-image: var(--mainframe-16-svg); + mask-image: var(--mainframe-16-svg); +} + +%with-mainframe-24-icon { + @extend %with-icon, %mainframe-24-svg-prop; + background-image: var(--mainframe-24-svg); +} +%with-mainframe-24-mask { + @extend %with-mask, %mainframe-24-svg-prop; + -webkit-mask-image: var(--mainframe-24-svg); + mask-image: var(--mainframe-24-svg); +} + %with-map-16-icon { @extend %with-icon, %map-16-svg-prop; background-image: var(--map-16-svg); @@ -5979,13 +6439,13 @@ } %with-menu-icon { - @extend %with-icon, %menu-svg-prop; - background-image: var(--menu-svg); + @extend %with-icon, %menu-16-svg-prop; + background-image: var(--menu-16-svg); } %with-menu-mask { - @extend %with-mask, %menu-svg-prop; - -webkit-mask-image: var(--menu-svg); - mask-image: var(--menu-svg); + @extend %with-mask, %menu-16-svg-prop; + -webkit-mask-image: var(--menu-16-svg); + mask-image: var(--menu-16-svg); } %with-mesh-16-icon { @@ -6009,13 +6469,13 @@ } %with-mesh-icon { - @extend %with-icon, %mesh-svg-prop; - background-image: var(--mesh-svg); + @extend %with-icon, %mesh-16-svg-prop; + background-image: var(--mesh-16-svg); } %with-mesh-mask { - @extend %with-mask, %mesh-svg-prop; - -webkit-mask-image: var(--mesh-svg); - mask-image: var(--mesh-svg); + @extend %with-mask, %mesh-16-svg-prop; + -webkit-mask-image: var(--mesh-16-svg); + mask-image: var(--mesh-16-svg); } %with-message-circle-16-icon { @@ -6099,13 +6559,13 @@ } %with-message-icon { - @extend %with-icon, %message-svg-prop; - background-image: var(--message-svg); + @extend %with-icon, %message-square-fill-16-svg-prop; + background-image: var(--message-square-fill-16-svg); } %with-message-mask { - @extend %with-mask, %message-svg-prop; - -webkit-mask-image: var(--message-svg); - mask-image: var(--message-svg); + @extend %with-mask, %message-square-fill-16-svg-prop; + -webkit-mask-image: var(--message-square-fill-16-svg); + mask-image: var(--message-square-fill-16-svg); } %with-mic-16-icon { @@ -6289,33 +6749,33 @@ } %with-minus-circle-fill-icon { - @extend %with-icon, %minus-circle-fill-svg-prop; - background-image: var(--minus-circle-fill-svg); + @extend %with-icon, %minus-circle-16-svg-prop; + background-image: var(--minus-circle-16-svg); } %with-minus-circle-fill-mask { - @extend %with-mask, %minus-circle-fill-svg-prop; - -webkit-mask-image: var(--minus-circle-fill-svg); - mask-image: var(--minus-circle-fill-svg); + @extend %with-mask, %minus-circle-16-svg-prop; + -webkit-mask-image: var(--minus-circle-16-svg); + mask-image: var(--minus-circle-16-svg); } %with-minus-circle-outline-icon { - @extend %with-icon, %minus-circle-outline-svg-prop; - background-image: var(--minus-circle-outline-svg); + @extend %with-icon, %minus-circle-16-svg-prop; + background-image: var(--minus-circle-16-svg); } %with-minus-circle-outline-mask { - @extend %with-mask, %minus-circle-outline-svg-prop; - -webkit-mask-image: var(--minus-circle-outline-svg); - mask-image: var(--minus-circle-outline-svg); + @extend %with-mask, %minus-circle-16-svg-prop; + -webkit-mask-image: var(--minus-circle-16-svg); + mask-image: var(--minus-circle-16-svg); } %with-minus-plain-icon { - @extend %with-icon, %minus-plain-svg-prop; - background-image: var(--minus-plain-svg); + @extend %with-icon, %minus-16-svg-prop; + background-image: var(--minus-16-svg); } %with-minus-plain-mask { - @extend %with-mask, %minus-plain-svg-prop; - -webkit-mask-image: var(--minus-plain-svg); - mask-image: var(--minus-plain-svg); + @extend %with-mask, %minus-16-svg-prop; + -webkit-mask-image: var(--minus-16-svg); + mask-image: var(--minus-16-svg); } %with-minus-plus-16-icon { @@ -6399,13 +6859,13 @@ } %with-minus-square-fill-icon { - @extend %with-icon, %minus-square-fill-svg-prop; - background-image: var(--minus-square-fill-svg); + @extend %with-icon, %minus-square-16-svg-prop; + background-image: var(--minus-square-16-svg); } %with-minus-square-fill-mask { - @extend %with-mask, %minus-square-fill-svg-prop; - -webkit-mask-image: var(--minus-square-fill-svg); - mask-image: var(--minus-square-fill-svg); + @extend %with-mask, %minus-square-16-svg-prop; + -webkit-mask-image: var(--minus-square-16-svg); + mask-image: var(--minus-square-16-svg); } %with-module-16-icon { @@ -6429,13 +6889,13 @@ } %with-module-icon { - @extend %with-icon, %module-svg-prop; - background-image: var(--module-svg); + @extend %with-icon, %module-16-svg-prop; + background-image: var(--module-16-svg); } %with-module-mask { - @extend %with-mask, %module-svg-prop; - -webkit-mask-image: var(--module-svg); - mask-image: var(--module-svg); + @extend %with-mask, %module-16-svg-prop; + -webkit-mask-image: var(--module-16-svg); + mask-image: var(--module-16-svg); } %with-monitor-16-icon { @@ -6499,13 +6959,13 @@ } %with-more-horizontal-icon { - @extend %with-icon, %more-horizontal-svg-prop; - background-image: var(--more-horizontal-svg); + @extend %with-icon, %more-horizontal-16-svg-prop; + background-image: var(--more-horizontal-16-svg); } %with-more-horizontal-mask { - @extend %with-mask, %more-horizontal-svg-prop; - -webkit-mask-image: var(--more-horizontal-svg); - mask-image: var(--more-horizontal-svg); + @extend %with-mask, %more-horizontal-16-svg-prop; + -webkit-mask-image: var(--more-horizontal-16-svg); + mask-image: var(--more-horizontal-16-svg); } %with-more-vertical-16-icon { @@ -6529,13 +6989,13 @@ } %with-more-vertical-icon { - @extend %with-icon, %more-vertical-svg-prop; - background-image: var(--more-vertical-svg); + @extend %with-icon, %more-vertical-16-svg-prop; + background-image: var(--more-vertical-16-svg); } %with-more-vertical-mask { - @extend %with-mask, %more-vertical-svg-prop; - -webkit-mask-image: var(--more-vertical-svg); - mask-image: var(--more-vertical-svg); + @extend %with-mask, %more-vertical-16-svg-prop; + -webkit-mask-image: var(--more-vertical-16-svg); + mask-image: var(--more-vertical-16-svg); } %with-mouse-pointer-16-icon { @@ -6718,34 +7178,74 @@ mask-image: var(--node-24-svg); } +%with-nomad-16-icon { + @extend %with-icon, %nomad-16-svg-prop; + background-image: var(--nomad-16-svg); +} +%with-nomad-16-mask { + @extend %with-mask, %nomad-16-svg-prop; + -webkit-mask-image: var(--nomad-16-svg); + mask-image: var(--nomad-16-svg); +} + +%with-nomad-24-icon { + @extend %with-icon, %nomad-24-svg-prop; + background-image: var(--nomad-24-svg); +} +%with-nomad-24-mask { + @extend %with-mask, %nomad-24-svg-prop; + -webkit-mask-image: var(--nomad-24-svg); + mask-image: var(--nomad-24-svg); +} + +%with-nomad-color-16-icon { + @extend %with-icon, %nomad-color-16-svg-prop; + background-image: var(--nomad-color-16-svg); +} +%with-nomad-color-16-mask { + @extend %with-mask, %nomad-color-16-svg-prop; + -webkit-mask-image: var(--nomad-color-16-svg); + mask-image: var(--nomad-color-16-svg); +} + +%with-nomad-color-24-icon { + @extend %with-icon, %nomad-color-24-svg-prop; + background-image: var(--nomad-color-24-svg); +} +%with-nomad-color-24-mask { + @extend %with-mask, %nomad-color-24-svg-prop; + -webkit-mask-image: var(--nomad-color-24-svg); + mask-image: var(--nomad-color-24-svg); +} + %with-notification-disabled-icon { - @extend %with-icon, %notification-disabled-svg-prop; - background-image: var(--notification-disabled-svg); + @extend %with-icon, %bell-off-16-svg-prop; + background-image: var(--bell-off-16-svg); } %with-notification-disabled-mask { - @extend %with-mask, %notification-disabled-svg-prop; - -webkit-mask-image: var(--notification-disabled-svg); - mask-image: var(--notification-disabled-svg); + @extend %with-mask, %bell-off-16-svg-prop; + -webkit-mask-image: var(--bell-off-16-svg); + mask-image: var(--bell-off-16-svg); } %with-notification-fill-icon { - @extend %with-icon, %notification-fill-svg-prop; - background-image: var(--notification-fill-svg); + @extend %with-icon, %bell-active-fill-16-svg-prop; + background-image: var(--bell-active-fill-16-svg); } %with-notification-fill-mask { - @extend %with-mask, %notification-fill-svg-prop; - -webkit-mask-image: var(--notification-fill-svg); - mask-image: var(--notification-fill-svg); + @extend %with-mask, %bell-active-fill-16-svg-prop; + -webkit-mask-image: var(--bell-active-fill-16-svg); + mask-image: var(--bell-active-fill-16-svg); } %with-notification-outline-icon { - @extend %with-icon, %notification-outline-svg-prop; - background-image: var(--notification-outline-svg); + @extend %with-icon, %bell-16-svg-prop; + background-image: var(--bell-16-svg); } %with-notification-outline-mask { - @extend %with-mask, %notification-outline-svg-prop; - -webkit-mask-image: var(--notification-outline-svg); - mask-image: var(--notification-outline-svg); + @extend %with-mask, %bell-16-svg-prop; + -webkit-mask-image: var(--bell-16-svg); + mask-image: var(--bell-16-svg); } %with-octagon-16-icon { @@ -6889,13 +7389,53 @@ } %with-outline-icon { - @extend %with-icon, %outline-svg-prop; - background-image: var(--outline-svg); + @extend %with-icon, %outline-16-svg-prop; + background-image: var(--outline-16-svg); } %with-outline-mask { - @extend %with-mask, %outline-svg-prop; - -webkit-mask-image: var(--outline-svg); - mask-image: var(--outline-svg); + @extend %with-mask, %outline-16-svg-prop; + -webkit-mask-image: var(--outline-16-svg); + mask-image: var(--outline-16-svg); +} + +%with-pack-16-icon { + @extend %with-icon, %pack-16-svg-prop; + background-image: var(--pack-16-svg); +} +%with-pack-16-mask { + @extend %with-mask, %pack-16-svg-prop; + -webkit-mask-image: var(--pack-16-svg); + mask-image: var(--pack-16-svg); +} + +%with-pack-24-icon { + @extend %with-icon, %pack-24-svg-prop; + background-image: var(--pack-24-svg); +} +%with-pack-24-mask { + @extend %with-mask, %pack-24-svg-prop; + -webkit-mask-image: var(--pack-24-svg); + mask-image: var(--pack-24-svg); +} + +%with-pack-color-16-icon { + @extend %with-icon, %pack-color-16-svg-prop; + background-image: var(--pack-color-16-svg); +} +%with-pack-color-16-mask { + @extend %with-mask, %pack-color-16-svg-prop; + -webkit-mask-image: var(--pack-color-16-svg); + mask-image: var(--pack-color-16-svg); +} + +%with-pack-color-24-icon { + @extend %with-icon, %pack-color-24-svg-prop; + background-image: var(--pack-color-24-svg); +} +%with-pack-color-24-mask { + @extend %with-mask, %pack-color-24-svg-prop; + -webkit-mask-image: var(--pack-color-24-svg); + mask-image: var(--pack-color-24-svg); } %with-package-16-icon { @@ -6918,14 +7458,54 @@ mask-image: var(--package-24-svg); } +%with-packer-16-icon { + @extend %with-icon, %packer-16-svg-prop; + background-image: var(--packer-16-svg); +} +%with-packer-16-mask { + @extend %with-mask, %packer-16-svg-prop; + -webkit-mask-image: var(--packer-16-svg); + mask-image: var(--packer-16-svg); +} + +%with-packer-24-icon { + @extend %with-icon, %packer-24-svg-prop; + background-image: var(--packer-24-svg); +} +%with-packer-24-mask { + @extend %with-mask, %packer-24-svg-prop; + -webkit-mask-image: var(--packer-24-svg); + mask-image: var(--packer-24-svg); +} + +%with-packer-color-16-icon { + @extend %with-icon, %packer-color-16-svg-prop; + background-image: var(--packer-color-16-svg); +} +%with-packer-color-16-mask { + @extend %with-mask, %packer-color-16-svg-prop; + -webkit-mask-image: var(--packer-color-16-svg); + mask-image: var(--packer-color-16-svg); +} + +%with-packer-color-24-icon { + @extend %with-icon, %packer-color-24-svg-prop; + background-image: var(--packer-color-24-svg); +} +%with-packer-color-24-mask { + @extend %with-mask, %packer-color-24-svg-prop; + -webkit-mask-image: var(--packer-color-24-svg); + mask-image: var(--packer-color-24-svg); +} + %with-page-outline-icon { - @extend %with-icon, %page-outline-svg-prop; - background-image: var(--page-outline-svg); + @extend %with-icon, %outline-16-svg-prop; + background-image: var(--outline-16-svg); } %with-page-outline-mask { - @extend %with-mask, %page-outline-svg-prop; - -webkit-mask-image: var(--page-outline-svg); - mask-image: var(--page-outline-svg); + @extend %with-mask, %outline-16-svg-prop; + -webkit-mask-image: var(--outline-16-svg); + mask-image: var(--outline-16-svg); } %with-paperclip-16-icon { @@ -6949,13 +7529,13 @@ } %with-partner-icon { - @extend %with-icon, %partner-svg-prop; - background-image: var(--partner-svg); + @extend %with-icon, %users-16-svg-prop; + background-image: var(--users-16-svg); } %with-partner-mask { - @extend %with-mask, %partner-svg-prop; - -webkit-mask-image: var(--partner-svg); - mask-image: var(--partner-svg); + @extend %with-mask, %users-16-svg-prop; + -webkit-mask-image: var(--users-16-svg); + mask-image: var(--users-16-svg); } %with-path-16-icon { @@ -6979,13 +7559,13 @@ } %with-path-icon { - @extend %with-icon, %path-svg-prop; - background-image: var(--path-svg); + @extend %with-icon, %path-16-svg-prop; + background-image: var(--path-16-svg); } %with-path-mask { - @extend %with-mask, %path-svg-prop; - -webkit-mask-image: var(--path-svg); - mask-image: var(--path-svg); + @extend %with-mask, %path-16-svg-prop; + -webkit-mask-image: var(--path-16-svg); + mask-image: var(--path-16-svg); } %with-pause-16-icon { @@ -7209,33 +7789,33 @@ } %with-play-fill-icon { - @extend %with-icon, %play-fill-svg-prop; - background-image: var(--play-fill-svg); + @extend %with-icon, %play-circle-16-svg-prop; + background-image: var(--play-circle-16-svg); } %with-play-fill-mask { - @extend %with-mask, %play-fill-svg-prop; - -webkit-mask-image: var(--play-fill-svg); - mask-image: var(--play-fill-svg); + @extend %with-mask, %play-circle-16-svg-prop; + -webkit-mask-image: var(--play-circle-16-svg); + mask-image: var(--play-circle-16-svg); } %with-play-outline-icon { - @extend %with-icon, %play-outline-svg-prop; - background-image: var(--play-outline-svg); + @extend %with-icon, %play-circle-16-svg-prop; + background-image: var(--play-circle-16-svg); } %with-play-outline-mask { - @extend %with-mask, %play-outline-svg-prop; - -webkit-mask-image: var(--play-outline-svg); - mask-image: var(--play-outline-svg); + @extend %with-mask, %play-circle-16-svg-prop; + -webkit-mask-image: var(--play-circle-16-svg); + mask-image: var(--play-circle-16-svg); } %with-play-plain-icon { - @extend %with-icon, %play-plain-svg-prop; - background-image: var(--play-plain-svg); + @extend %with-icon, %play-16-svg-prop; + background-image: var(--play-16-svg); } %with-play-plain-mask { - @extend %with-mask, %play-plain-svg-prop; - -webkit-mask-image: var(--play-plain-svg); - mask-image: var(--play-plain-svg); + @extend %with-mask, %play-16-svg-prop; + -webkit-mask-image: var(--play-16-svg); + mask-image: var(--play-16-svg); } %with-plus-16-icon { @@ -7279,33 +7859,33 @@ } %with-plus-circle-fill-icon { - @extend %with-icon, %plus-circle-fill-svg-prop; - background-image: var(--plus-circle-fill-svg); + @extend %with-icon, %plus-circle-16-svg-prop; + background-image: var(--plus-circle-16-svg); } %with-plus-circle-fill-mask { - @extend %with-mask, %plus-circle-fill-svg-prop; - -webkit-mask-image: var(--plus-circle-fill-svg); - mask-image: var(--plus-circle-fill-svg); + @extend %with-mask, %plus-circle-16-svg-prop; + -webkit-mask-image: var(--plus-circle-16-svg); + mask-image: var(--plus-circle-16-svg); } %with-plus-circle-outline-icon { - @extend %with-icon, %plus-circle-outline-svg-prop; - background-image: var(--plus-circle-outline-svg); + @extend %with-icon, %plus-circle-16-svg-prop; + background-image: var(--plus-circle-16-svg); } %with-plus-circle-outline-mask { - @extend %with-mask, %plus-circle-outline-svg-prop; - -webkit-mask-image: var(--plus-circle-outline-svg); - mask-image: var(--plus-circle-outline-svg); + @extend %with-mask, %plus-circle-16-svg-prop; + -webkit-mask-image: var(--plus-circle-16-svg); + mask-image: var(--plus-circle-16-svg); } %with-plus-plain-icon { - @extend %with-icon, %plus-plain-svg-prop; - background-image: var(--plus-plain-svg); + @extend %with-icon, %plus-16-svg-prop; + background-image: var(--plus-16-svg); } %with-plus-plain-mask { - @extend %with-mask, %plus-plain-svg-prop; - -webkit-mask-image: var(--plus-plain-svg); - mask-image: var(--plus-plain-svg); + @extend %with-mask, %plus-16-svg-prop; + -webkit-mask-image: var(--plus-16-svg); + mask-image: var(--plus-16-svg); } %with-plus-square-16-icon { @@ -7329,13 +7909,13 @@ } %with-plus-square-fill-icon { - @extend %with-icon, %plus-square-fill-svg-prop; - background-image: var(--plus-square-fill-svg); + @extend %with-icon, %plus-square-16-svg-prop; + background-image: var(--plus-square-16-svg); } %with-plus-square-fill-mask { - @extend %with-mask, %plus-square-fill-svg-prop; - -webkit-mask-image: var(--plus-square-fill-svg); - mask-image: var(--plus-square-fill-svg); + @extend %with-mask, %plus-square-16-svg-prop; + -webkit-mask-image: var(--plus-square-16-svg); + mask-image: var(--plus-square-16-svg); } %with-port-icon { @@ -7419,33 +7999,33 @@ } %with-provider-icon { - @extend %with-icon, %provider-svg-prop; - background-image: var(--provider-svg); + @extend %with-icon, %provider-16-svg-prop; + background-image: var(--provider-16-svg); } %with-provider-mask { - @extend %with-mask, %provider-svg-prop; - -webkit-mask-image: var(--provider-svg); - mask-image: var(--provider-svg); + @extend %with-mask, %provider-16-svg-prop; + -webkit-mask-image: var(--provider-16-svg); + mask-image: var(--provider-16-svg); } %with-public-default-icon { - @extend %with-icon, %public-default-svg-prop; - background-image: var(--public-default-svg); + @extend %with-icon, %globe-16-svg-prop; + background-image: var(--globe-16-svg); } %with-public-default-mask { - @extend %with-mask, %public-default-svg-prop; - -webkit-mask-image: var(--public-default-svg); - mask-image: var(--public-default-svg); + @extend %with-mask, %globe-16-svg-prop; + -webkit-mask-image: var(--globe-16-svg); + mask-image: var(--globe-16-svg); } %with-public-locked-icon { - @extend %with-icon, %public-locked-svg-prop; - background-image: var(--public-locked-svg); + @extend %with-icon, %globe-private-16-svg-prop; + background-image: var(--globe-private-16-svg); } %with-public-locked-mask { - @extend %with-mask, %public-locked-svg-prop; - -webkit-mask-image: var(--public-locked-svg); - mask-image: var(--public-locked-svg); + @extend %with-mask, %globe-private-16-svg-prop; + -webkit-mask-image: var(--globe-private-16-svg); + mask-image: var(--globe-private-16-svg); } %with-queue-16-icon { @@ -7469,13 +8049,13 @@ } %with-queue-icon { - @extend %with-icon, %queue-svg-prop; - background-image: var(--queue-svg); + @extend %with-icon, %queue-16-svg-prop; + background-image: var(--queue-16-svg); } %with-queue-mask { - @extend %with-mask, %queue-svg-prop; - -webkit-mask-image: var(--queue-svg); - mask-image: var(--queue-svg); + @extend %with-mask, %queue-16-svg-prop; + -webkit-mask-image: var(--queue-16-svg); + mask-image: var(--queue-16-svg); } %with-radio-16-icon { @@ -7499,23 +8079,23 @@ } %with-radio-button-checked-icon { - @extend %with-icon, %radio-button-checked-svg-prop; - background-image: var(--radio-button-checked-svg); + @extend %with-icon, %circle-dot-16-svg-prop; + background-image: var(--circle-dot-16-svg); } %with-radio-button-checked-mask { - @extend %with-mask, %radio-button-checked-svg-prop; - -webkit-mask-image: var(--radio-button-checked-svg); - mask-image: var(--radio-button-checked-svg); + @extend %with-mask, %circle-dot-16-svg-prop; + -webkit-mask-image: var(--circle-dot-16-svg); + mask-image: var(--circle-dot-16-svg); } %with-radio-button-unchecked-icon { - @extend %with-icon, %radio-button-unchecked-svg-prop; - background-image: var(--radio-button-unchecked-svg); + @extend %with-icon, %circle-16-svg-prop; + background-image: var(--circle-16-svg); } %with-radio-button-unchecked-mask { - @extend %with-mask, %radio-button-unchecked-svg-prop; - -webkit-mask-image: var(--radio-button-unchecked-svg); - mask-image: var(--radio-button-unchecked-svg); + @extend %with-mask, %circle-16-svg-prop; + -webkit-mask-image: var(--circle-16-svg); + mask-image: var(--circle-16-svg); } %with-random-16-icon { @@ -7539,13 +8119,13 @@ } %with-random-icon { - @extend %with-icon, %random-svg-prop; - background-image: var(--random-svg); + @extend %with-icon, %random-16-svg-prop; + background-image: var(--random-16-svg); } %with-random-mask { - @extend %with-mask, %random-svg-prop; - -webkit-mask-image: var(--random-svg); - mask-image: var(--random-svg); + @extend %with-mask, %random-16-svg-prop; + -webkit-mask-image: var(--random-16-svg); + mask-image: var(--random-16-svg); } %with-redirect-16-icon { @@ -7569,33 +8149,33 @@ } %with-redirect-icon { - @extend %with-icon, %redirect-svg-prop; - background-image: var(--redirect-svg); + @extend %with-icon, %redirect-16-svg-prop; + background-image: var(--redirect-16-svg); } %with-redirect-mask { - @extend %with-mask, %redirect-svg-prop; - -webkit-mask-image: var(--redirect-svg); - mask-image: var(--redirect-svg); + @extend %with-mask, %redirect-16-svg-prop; + -webkit-mask-image: var(--redirect-16-svg); + mask-image: var(--redirect-16-svg); } %with-refresh-alert-icon { - @extend %with-icon, %refresh-alert-svg-prop; - background-image: var(--refresh-alert-svg); + @extend %with-icon, %sync-alert-16-svg-prop; + background-image: var(--sync-alert-16-svg); } %with-refresh-alert-mask { - @extend %with-mask, %refresh-alert-svg-prop; - -webkit-mask-image: var(--refresh-alert-svg); - mask-image: var(--refresh-alert-svg); + @extend %with-mask, %sync-alert-16-svg-prop; + -webkit-mask-image: var(--sync-alert-16-svg); + mask-image: var(--sync-alert-16-svg); } %with-refresh-default-icon { - @extend %with-icon, %refresh-default-svg-prop; - background-image: var(--refresh-default-svg); + @extend %with-icon, %sync-16-svg-prop; + background-image: var(--sync-16-svg); } %with-refresh-default-mask { - @extend %with-mask, %refresh-default-svg-prop; - -webkit-mask-image: var(--refresh-default-svg); - mask-image: var(--refresh-default-svg); + @extend %with-mask, %sync-16-svg-prop; + -webkit-mask-image: var(--sync-16-svg); + mask-image: var(--sync-16-svg); } %with-reload-16-icon { @@ -7619,13 +8199,13 @@ } %with-remix-icon { - @extend %with-icon, %remix-svg-prop; - background-image: var(--remix-svg); + @extend %with-icon, %shuffle-16-svg-prop; + background-image: var(--shuffle-16-svg); } %with-remix-mask { - @extend %with-mask, %remix-svg-prop; - -webkit-mask-image: var(--remix-svg); - mask-image: var(--remix-svg); + @extend %with-mask, %shuffle-16-svg-prop; + -webkit-mask-image: var(--shuffle-16-svg); + mask-image: var(--shuffle-16-svg); } %with-repeat-16-icon { @@ -7709,13 +8289,13 @@ } %with-ribbon-icon { - @extend %with-icon, %ribbon-svg-prop; - background-image: var(--ribbon-svg); + @extend %with-icon, %award-16-svg-prop; + background-image: var(--award-16-svg); } %with-ribbon-mask { - @extend %with-mask, %ribbon-svg-prop; - -webkit-mask-image: var(--ribbon-svg); - mask-image: var(--ribbon-svg); + @extend %with-mask, %award-16-svg-prop; + -webkit-mask-image: var(--award-16-svg); + mask-image: var(--award-16-svg); } %with-rocket-16-icon { @@ -7879,13 +8459,13 @@ } %with-search-icon { - @extend %with-icon, %search-svg-prop; - background-image: var(--search-svg); + @extend %with-icon, %search-16-svg-prop; + background-image: var(--search-16-svg); } %with-search-mask { - @extend %with-mask, %search-svg-prop; - -webkit-mask-image: var(--search-svg); - mask-image: var(--search-svg); + @extend %with-mask, %search-16-svg-prop; + -webkit-mask-image: var(--search-16-svg); + mask-image: var(--search-16-svg); } %with-send-16-icon { @@ -7989,13 +8569,13 @@ } %with-settings-icon { - @extend %with-icon, %settings-svg-prop; - background-image: var(--settings-svg); + @extend %with-icon, %settings-16-svg-prop; + background-image: var(--settings-16-svg); } %with-settings-mask { - @extend %with-mask, %settings-svg-prop; - -webkit-mask-image: var(--settings-svg); - mask-image: var(--settings-svg); + @extend %with-mask, %settings-16-svg-prop; + -webkit-mask-image: var(--settings-16-svg); + mask-image: var(--settings-16-svg); } %with-share-16-icon { @@ -8549,23 +9129,23 @@ } %with-sort-icon { - @extend %with-icon, %sort-svg-prop; - background-image: var(--sort-svg); + @extend %with-icon, %sort-desc-16-svg-prop; + background-image: var(--sort-desc-16-svg); } %with-sort-mask { - @extend %with-mask, %sort-svg-prop; - -webkit-mask-image: var(--sort-svg); - mask-image: var(--sort-svg); + @extend %with-mask, %sort-desc-16-svg-prop; + -webkit-mask-image: var(--sort-desc-16-svg); + mask-image: var(--sort-desc-16-svg); } %with-source-file-icon { - @extend %with-icon, %source-file-svg-prop; - background-image: var(--source-file-svg); + @extend %with-icon, %file-source-16-svg-prop; + background-image: var(--file-source-16-svg); } %with-source-file-mask { - @extend %with-mask, %source-file-svg-prop; - -webkit-mask-image: var(--source-file-svg); - mask-image: var(--source-file-svg); + @extend %with-mask, %file-source-16-svg-prop; + -webkit-mask-image: var(--file-source-16-svg); + mask-image: var(--file-source-16-svg); } %with-speaker-16-icon { @@ -8689,13 +9269,13 @@ } %with-star-fill-icon { - @extend %with-icon, %star-fill-svg-prop; - background-image: var(--star-fill-svg); + @extend %with-icon, %star-fill-16-svg-prop; + background-image: var(--star-fill-16-svg); } %with-star-fill-mask { - @extend %with-mask, %star-fill-svg-prop; - -webkit-mask-image: var(--star-fill-svg); - mask-image: var(--star-fill-svg); + @extend %with-mask, %star-fill-16-svg-prop; + -webkit-mask-image: var(--star-fill-16-svg); + mask-image: var(--star-fill-16-svg); } %with-star-off-16-icon { @@ -8719,13 +9299,13 @@ } %with-star-outline-icon { - @extend %with-icon, %star-outline-svg-prop; - background-image: var(--star-outline-svg); + @extend %with-icon, %star-16-svg-prop; + background-image: var(--star-16-svg); } %with-star-outline-mask { - @extend %with-mask, %star-outline-svg-prop; - -webkit-mask-image: var(--star-outline-svg); - mask-image: var(--star-outline-svg); + @extend %with-mask, %star-16-svg-prop; + -webkit-mask-image: var(--star-16-svg); + mask-image: var(--star-16-svg); } %with-stop-circle-16-icon { @@ -8749,23 +9329,23 @@ } %with-sub-left-icon { - @extend %with-icon, %sub-left-svg-prop; - background-image: var(--sub-left-svg); + @extend %with-icon, %corner-down-left-16-svg-prop; + background-image: var(--corner-down-left-16-svg); } %with-sub-left-mask { - @extend %with-mask, %sub-left-svg-prop; - -webkit-mask-image: var(--sub-left-svg); - mask-image: var(--sub-left-svg); + @extend %with-mask, %corner-down-left-16-svg-prop; + -webkit-mask-image: var(--corner-down-left-16-svg); + mask-image: var(--corner-down-left-16-svg); } %with-sub-right-icon { - @extend %with-icon, %sub-right-svg-prop; - background-image: var(--sub-right-svg); + @extend %with-icon, %corner-down-right-16-svg-prop; + background-image: var(--corner-down-right-16-svg); } %with-sub-right-mask { - @extend %with-mask, %sub-right-svg-prop; - -webkit-mask-image: var(--sub-right-svg); - mask-image: var(--sub-right-svg); + @extend %with-mask, %corner-down-right-16-svg-prop; + -webkit-mask-image: var(--corner-down-right-16-svg); + mask-image: var(--corner-down-right-16-svg); } %with-sun-16-icon { @@ -8809,13 +9389,13 @@ } %with-support-icon { - @extend %with-icon, %support-svg-prop; - background-image: var(--support-svg); + @extend %with-icon, %support-16-svg-prop; + background-image: var(--support-16-svg); } %with-support-mask { - @extend %with-mask, %support-svg-prop; - -webkit-mask-image: var(--support-svg); - mask-image: var(--support-svg); + @extend %with-mask, %support-16-svg-prop; + -webkit-mask-image: var(--support-16-svg); + mask-image: var(--support-16-svg); } %with-swap-horizontal-16-icon { @@ -8839,13 +9419,13 @@ } %with-swap-horizontal-icon { - @extend %with-icon, %swap-horizontal-svg-prop; - background-image: var(--swap-horizontal-svg); + @extend %with-icon, %swap-horizontal-16-svg-prop; + background-image: var(--swap-horizontal-16-svg); } %with-swap-horizontal-mask { - @extend %with-mask, %swap-horizontal-svg-prop; - -webkit-mask-image: var(--swap-horizontal-svg); - mask-image: var(--swap-horizontal-svg); + @extend %with-mask, %swap-horizontal-16-svg-prop; + -webkit-mask-image: var(--swap-horizontal-16-svg); + mask-image: var(--swap-horizontal-16-svg); } %with-swap-vertical-16-icon { @@ -8869,13 +9449,13 @@ } %with-swap-vertical-icon { - @extend %with-icon, %swap-vertical-svg-prop; - background-image: var(--swap-vertical-svg); + @extend %with-icon, %swap-vertical-16-svg-prop; + background-image: var(--swap-vertical-16-svg); } %with-swap-vertical-mask { - @extend %with-mask, %swap-vertical-svg-prop; - -webkit-mask-image: var(--swap-vertical-svg); - mask-image: var(--swap-vertical-svg); + @extend %with-mask, %swap-vertical-16-svg-prop; + -webkit-mask-image: var(--swap-vertical-16-svg); + mask-image: var(--swap-vertical-16-svg); } %with-switcher-16-icon { @@ -8999,13 +9579,13 @@ } %with-tag-icon { - @extend %with-icon, %tag-svg-prop; - background-image: var(--tag-svg); + @extend %with-icon, %tag-16-svg-prop; + background-image: var(--tag-16-svg); } %with-tag-mask { - @extend %with-mask, %tag-svg-prop; - -webkit-mask-image: var(--tag-svg); - mask-image: var(--tag-svg); + @extend %with-mask, %tag-16-svg-prop; + -webkit-mask-image: var(--tag-16-svg); + mask-image: var(--tag-16-svg); } %with-target-16-icon { @@ -9068,6 +9648,46 @@ mask-image: var(--terminal-screen-24-svg); } +%with-terraform-16-icon { + @extend %with-icon, %terraform-16-svg-prop; + background-image: var(--terraform-16-svg); +} +%with-terraform-16-mask { + @extend %with-mask, %terraform-16-svg-prop; + -webkit-mask-image: var(--terraform-16-svg); + mask-image: var(--terraform-16-svg); +} + +%with-terraform-24-icon { + @extend %with-icon, %terraform-24-svg-prop; + background-image: var(--terraform-24-svg); +} +%with-terraform-24-mask { + @extend %with-mask, %terraform-24-svg-prop; + -webkit-mask-image: var(--terraform-24-svg); + mask-image: var(--terraform-24-svg); +} + +%with-terraform-color-16-icon { + @extend %with-icon, %terraform-color-16-svg-prop; + background-image: var(--terraform-color-16-svg); +} +%with-terraform-color-16-mask { + @extend %with-mask, %terraform-color-16-svg-prop; + -webkit-mask-image: var(--terraform-color-16-svg); + mask-image: var(--terraform-color-16-svg); +} + +%with-terraform-color-24-icon { + @extend %with-icon, %terraform-color-24-svg-prop; + background-image: var(--terraform-color-24-svg); +} +%with-terraform-color-24-mask { + @extend %with-mask, %terraform-color-24-svg-prop; + -webkit-mask-image: var(--terraform-color-24-svg); + mask-image: var(--terraform-color-24-svg); +} + %with-thumbs-down-16-icon { @extend %with-icon, %thumbs-down-16-svg-prop; background-image: var(--thumbs-down-16-svg); @@ -9229,13 +9849,13 @@ } %with-trash-icon { - @extend %with-icon, %trash-svg-prop; - background-image: var(--trash-svg); + @extend %with-icon, %trash-16-svg-prop; + background-image: var(--trash-16-svg); } %with-trash-mask { - @extend %with-mask, %trash-svg-prop; - -webkit-mask-image: var(--trash-svg); - mask-image: var(--trash-svg); + @extend %with-mask, %trash-16-svg-prop; + -webkit-mask-image: var(--trash-16-svg); + mask-image: var(--trash-16-svg); } %with-trend-down-16-icon { @@ -9339,13 +9959,13 @@ } %with-tune-icon { - @extend %with-icon, %tune-svg-prop; - background-image: var(--tune-svg); + @extend %with-icon, %sliders-16-svg-prop; + background-image: var(--sliders-16-svg); } %with-tune-mask { - @extend %with-mask, %tune-svg-prop; - -webkit-mask-image: var(--tune-svg); - mask-image: var(--tune-svg); + @extend %with-mask, %sliders-16-svg-prop; + -webkit-mask-image: var(--sliders-16-svg); + mask-image: var(--sliders-16-svg); } %with-tv-16-icon { @@ -9368,6 +9988,86 @@ mask-image: var(--tv-24-svg); } +%with-twitch-16-icon { + @extend %with-icon, %twitch-16-svg-prop; + background-image: var(--twitch-16-svg); +} +%with-twitch-16-mask { + @extend %with-mask, %twitch-16-svg-prop; + -webkit-mask-image: var(--twitch-16-svg); + mask-image: var(--twitch-16-svg); +} + +%with-twitch-24-icon { + @extend %with-icon, %twitch-24-svg-prop; + background-image: var(--twitch-24-svg); +} +%with-twitch-24-mask { + @extend %with-mask, %twitch-24-svg-prop; + -webkit-mask-image: var(--twitch-24-svg); + mask-image: var(--twitch-24-svg); +} + +%with-twitch-color-16-icon { + @extend %with-icon, %twitch-color-16-svg-prop; + background-image: var(--twitch-color-16-svg); +} +%with-twitch-color-16-mask { + @extend %with-mask, %twitch-color-16-svg-prop; + -webkit-mask-image: var(--twitch-color-16-svg); + mask-image: var(--twitch-color-16-svg); +} + +%with-twitch-color-24-icon { + @extend %with-icon, %twitch-color-24-svg-prop; + background-image: var(--twitch-color-24-svg); +} +%with-twitch-color-24-mask { + @extend %with-mask, %twitch-color-24-svg-prop; + -webkit-mask-image: var(--twitch-color-24-svg); + mask-image: var(--twitch-color-24-svg); +} + +%with-twitter-16-icon { + @extend %with-icon, %twitter-16-svg-prop; + background-image: var(--twitter-16-svg); +} +%with-twitter-16-mask { + @extend %with-mask, %twitter-16-svg-prop; + -webkit-mask-image: var(--twitter-16-svg); + mask-image: var(--twitter-16-svg); +} + +%with-twitter-24-icon { + @extend %with-icon, %twitter-24-svg-prop; + background-image: var(--twitter-24-svg); +} +%with-twitter-24-mask { + @extend %with-mask, %twitter-24-svg-prop; + -webkit-mask-image: var(--twitter-24-svg); + mask-image: var(--twitter-24-svg); +} + +%with-twitter-color-16-icon { + @extend %with-icon, %twitter-color-16-svg-prop; + background-image: var(--twitter-color-16-svg); +} +%with-twitter-color-16-mask { + @extend %with-mask, %twitter-color-16-svg-prop; + -webkit-mask-image: var(--twitter-color-16-svg); + mask-image: var(--twitter-color-16-svg); +} + +%with-twitter-color-24-icon { + @extend %with-icon, %twitter-color-24-svg-prop; + background-image: var(--twitter-color-24-svg); +} +%with-twitter-color-24-mask { + @extend %with-mask, %twitter-color-24-svg-prop; + -webkit-mask-image: var(--twitter-color-24-svg); + mask-image: var(--twitter-color-24-svg); +} + %with-type-16-icon { @extend %with-icon, %type-16-svg-prop; background-image: var(--type-16-svg); @@ -9409,23 +10109,23 @@ } %with-unfold-less-icon { - @extend %with-icon, %unfold-less-svg-prop; - background-image: var(--unfold-less-svg); + @extend %with-icon, %unfold-close-16-svg-prop; + background-image: var(--unfold-close-16-svg); } %with-unfold-less-mask { - @extend %with-mask, %unfold-less-svg-prop; - -webkit-mask-image: var(--unfold-less-svg); - mask-image: var(--unfold-less-svg); + @extend %with-mask, %unfold-close-16-svg-prop; + -webkit-mask-image: var(--unfold-close-16-svg); + mask-image: var(--unfold-close-16-svg); } %with-unfold-more-icon { - @extend %with-icon, %unfold-more-svg-prop; - background-image: var(--unfold-more-svg); + @extend %with-icon, %unfold-open-16-svg-prop; + background-image: var(--unfold-open-16-svg); } %with-unfold-more-mask { - @extend %with-mask, %unfold-more-svg-prop; - -webkit-mask-image: var(--unfold-more-svg); - mask-image: var(--unfold-more-svg); + @extend %with-mask, %unfold-open-16-svg-prop; + -webkit-mask-image: var(--unfold-open-16-svg); + mask-image: var(--unfold-open-16-svg); } %with-unfold-open-16-icon { @@ -9449,11 +10149,11 @@ } %with-union-icon { - @extend %with-icon, %union-svg; + @extend %with-icon, %union-svg-prop; background-image: var(--union-svg); } %with-union-mask { - @extend %with-mask, %union-svg; + @extend %with-mask, %union-svg-prop; -webkit-mask-image: var(--union-svg); mask-image: var(--union-svg); } @@ -9499,13 +10199,13 @@ } %with-upload-icon { - @extend %with-icon, %upload-svg-prop; - background-image: var(--upload-svg); + @extend %with-icon, %upload-16-svg-prop; + background-image: var(--upload-16-svg); } %with-upload-mask { - @extend %with-mask, %upload-svg-prop; - -webkit-mask-image: var(--upload-svg); - mask-image: var(--upload-svg); + @extend %with-mask, %upload-16-svg-prop; + -webkit-mask-image: var(--upload-16-svg); + mask-image: var(--upload-16-svg); } %with-user-16-icon { @@ -9529,13 +10229,13 @@ } %with-user-add-icon { - @extend %with-icon, %user-add-svg-prop; - background-image: var(--user-add-svg); + @extend %with-icon, %user-plus-16-svg-prop; + background-image: var(--user-plus-16-svg); } %with-user-add-mask { - @extend %with-mask, %user-add-svg-prop; - -webkit-mask-image: var(--user-add-svg); - mask-image: var(--user-add-svg); + @extend %with-mask, %user-plus-16-svg-prop; + -webkit-mask-image: var(--user-plus-16-svg); + mask-image: var(--user-plus-16-svg); } %with-user-check-16-icon { @@ -9619,23 +10319,23 @@ } %with-user-organization-icon { - @extend %with-icon, %user-organization-svg-prop; - background-image: var(--user-organization-svg); + @extend %with-icon, %org-16-svg-prop; + background-image: var(--org-16-svg); } %with-user-organization-mask { - @extend %with-mask, %user-organization-svg-prop; - -webkit-mask-image: var(--user-organization-svg); - mask-image: var(--user-organization-svg); + @extend %with-mask, %org-16-svg-prop; + -webkit-mask-image: var(--org-16-svg); + mask-image: var(--org-16-svg); } %with-user-plain-icon { - @extend %with-icon, %user-plain-svg-prop; - background-image: var(--user-plain-svg); + @extend %with-icon, %user-16-svg-prop; + background-image: var(--user-16-svg); } %with-user-plain-mask { - @extend %with-mask, %user-plain-svg-prop; - -webkit-mask-image: var(--user-plain-svg); - mask-image: var(--user-plain-svg); + @extend %with-mask, %user-16-svg-prop; + -webkit-mask-image: var(--user-16-svg); + mask-image: var(--user-16-svg); } %with-user-plus-16-icon { @@ -9659,33 +10359,33 @@ } %with-user-square-fill-icon { - @extend %with-icon, %user-square-fill-svg-prop; - background-image: var(--user-square-fill-svg); + @extend %with-icon, %user-circle-fill-16-svg-prop; + background-image: var(--user-circle-fill-16-svg); } %with-user-square-fill-mask { - @extend %with-mask, %user-square-fill-svg-prop; - -webkit-mask-image: var(--user-square-fill-svg); - mask-image: var(--user-square-fill-svg); + @extend %with-mask, %user-circle-fill-16-svg-prop; + -webkit-mask-image: var(--user-circle-fill-16-svg); + mask-image: var(--user-circle-fill-16-svg); } %with-user-square-outline-icon { - @extend %with-icon, %user-square-outline-svg-prop; - background-image: var(--user-square-outline-svg); + @extend %with-icon, %user-circle-16-svg-prop; + background-image: var(--user-circle-16-svg); } %with-user-square-outline-mask { - @extend %with-mask, %user-square-outline-svg-prop; - -webkit-mask-image: var(--user-square-outline-svg); - mask-image: var(--user-square-outline-svg); + @extend %with-mask, %user-circle-16-svg-prop; + -webkit-mask-image: var(--user-circle-16-svg); + mask-image: var(--user-circle-16-svg); } %with-user-team-icon { - @extend %with-icon, %user-team-svg-prop; - background-image: var(--user-team-svg); + @extend %with-icon, %users-16-svg-prop; + background-image: var(--users-16-svg); } %with-user-team-mask { - @extend %with-mask, %user-team-svg-prop; - -webkit-mask-image: var(--user-team-svg); - mask-image: var(--user-team-svg); + @extend %with-mask, %users-16-svg-prop; + -webkit-mask-image: var(--users-16-svg); + mask-image: var(--users-16-svg); } %with-user-x-16-icon { @@ -9728,6 +10428,46 @@ mask-image: var(--users-24-svg); } +%with-vagrant-16-icon { + @extend %with-icon, %vagrant-16-svg-prop; + background-image: var(--vagrant-16-svg); +} +%with-vagrant-16-mask { + @extend %with-mask, %vagrant-16-svg-prop; + -webkit-mask-image: var(--vagrant-16-svg); + mask-image: var(--vagrant-16-svg); +} + +%with-vagrant-24-icon { + @extend %with-icon, %vagrant-24-svg-prop; + background-image: var(--vagrant-24-svg); +} +%with-vagrant-24-mask { + @extend %with-mask, %vagrant-24-svg-prop; + -webkit-mask-image: var(--vagrant-24-svg); + mask-image: var(--vagrant-24-svg); +} + +%with-vagrant-color-16-icon { + @extend %with-icon, %vagrant-color-16-svg-prop; + background-image: var(--vagrant-color-16-svg); +} +%with-vagrant-color-16-mask { + @extend %with-mask, %vagrant-color-16-svg-prop; + -webkit-mask-image: var(--vagrant-color-16-svg); + mask-image: var(--vagrant-color-16-svg); +} + +%with-vagrant-color-24-icon { + @extend %with-icon, %vagrant-color-24-svg-prop; + background-image: var(--vagrant-color-24-svg); +} +%with-vagrant-color-24-mask { + @extend %with-mask, %vagrant-color-24-svg-prop; + -webkit-mask-image: var(--vagrant-color-24-svg); + mask-image: var(--vagrant-color-24-svg); +} + %with-vault-16-icon { @extend %with-icon, %vault-16-svg-prop; background-image: var(--vault-16-svg); @@ -9748,6 +10488,26 @@ mask-image: var(--vault-24-svg); } +%with-vault-color-16-icon { + @extend %with-icon, %vault-color-16-svg-prop; + background-image: var(--vault-color-16-svg); +} +%with-vault-color-16-mask { + @extend %with-mask, %vault-color-16-svg-prop; + -webkit-mask-image: var(--vault-color-16-svg); + mask-image: var(--vault-color-16-svg); +} + +%with-vault-color-24-icon { + @extend %with-icon, %vault-color-24-svg-prop; + background-image: var(--vault-color-24-svg); +} +%with-vault-color-24-mask { + @extend %with-mask, %vault-color-24-svg-prop; + -webkit-mask-image: var(--vault-color-24-svg); + mask-image: var(--vault-color-24-svg); +} + %with-verified-16-icon { @extend %with-icon, %verified-16-svg-prop; background-image: var(--verified-16-svg); @@ -9809,23 +10569,23 @@ } %with-visibility-hide-icon { - @extend %with-icon, %visibility-hide-svg-prop; - background-image: var(--visibility-hide-svg); + @extend %with-icon, %eye-off-16-svg-prop; + background-image: var(--eye-off-16-svg); } %with-visibility-hide-mask { - @extend %with-mask, %visibility-hide-svg-prop; - -webkit-mask-image: var(--visibility-hide-svg); - mask-image: var(--visibility-hide-svg); + @extend %with-mask, %eye-off-16-svg-prop; + -webkit-mask-image: var(--eye-off-16-svg); + mask-image: var(--eye-off-16-svg); } %with-visibility-show-icon { - @extend %with-icon, %visibility-show-svg-prop; - background-image: var(--visibility-show-svg); + @extend %with-icon, %eye-16-svg-prop; + background-image: var(--eye-16-svg); } %with-visibility-show-mask { - @extend %with-mask, %visibility-show-svg-prop; - -webkit-mask-image: var(--visibility-show-svg); - mask-image: var(--visibility-show-svg); + @extend %with-mask, %eye-16-svg-prop; + -webkit-mask-image: var(--eye-16-svg); + mask-image: var(--eye-16-svg); } %with-vmware-16-icon { @@ -9988,6 +10748,46 @@ mask-image: var(--watch-24-svg); } +%with-waypoint-16-icon { + @extend %with-icon, %waypoint-16-svg-prop; + background-image: var(--waypoint-16-svg); +} +%with-waypoint-16-mask { + @extend %with-mask, %waypoint-16-svg-prop; + -webkit-mask-image: var(--waypoint-16-svg); + mask-image: var(--waypoint-16-svg); +} + +%with-waypoint-24-icon { + @extend %with-icon, %waypoint-24-svg-prop; + background-image: var(--waypoint-24-svg); +} +%with-waypoint-24-mask { + @extend %with-mask, %waypoint-24-svg-prop; + -webkit-mask-image: var(--waypoint-24-svg); + mask-image: var(--waypoint-24-svg); +} + +%with-waypoint-color-16-icon { + @extend %with-icon, %waypoint-color-16-svg-prop; + background-image: var(--waypoint-color-16-svg); +} +%with-waypoint-color-16-mask { + @extend %with-mask, %waypoint-color-16-svg-prop; + -webkit-mask-image: var(--waypoint-color-16-svg); + mask-image: var(--waypoint-color-16-svg); +} + +%with-waypoint-color-24-icon { + @extend %with-icon, %waypoint-color-24-svg-prop; + background-image: var(--waypoint-color-24-svg); +} +%with-waypoint-color-24-mask { + @extend %with-mask, %waypoint-color-24-svg-prop; + -webkit-mask-image: var(--waypoint-color-24-svg); + mask-image: var(--waypoint-color-24-svg); +} + %with-webhook-16-icon { @extend %with-icon, %webhook-16-svg-prop; background-image: var(--webhook-16-svg); @@ -10009,13 +10809,13 @@ } %with-webhook-icon { - @extend %with-icon, %webhook-svg-prop; - background-image: var(--webhook-svg); + @extend %with-icon, %webhook-16-svg-prop; + background-image: var(--webhook-16-svg); } %with-webhook-mask { - @extend %with-mask, %webhook-svg-prop; - -webkit-mask-image: var(--webhook-svg); - mask-image: var(--webhook-svg); + @extend %with-mask, %webhook-16-svg-prop; + -webkit-mask-image: var(--webhook-16-svg); + mask-image: var(--webhook-16-svg); } %with-wifi-16-icon { @@ -10258,6 +11058,46 @@ mask-image: var(--x-square-fill-24-svg); } +%with-youtube-16-icon { + @extend %with-icon, %youtube-16-svg-prop; + background-image: var(--youtube-16-svg); +} +%with-youtube-16-mask { + @extend %with-mask, %youtube-16-svg-prop; + -webkit-mask-image: var(--youtube-16-svg); + mask-image: var(--youtube-16-svg); +} + +%with-youtube-24-icon { + @extend %with-icon, %youtube-24-svg-prop; + background-image: var(--youtube-24-svg); +} +%with-youtube-24-mask { + @extend %with-mask, %youtube-24-svg-prop; + -webkit-mask-image: var(--youtube-24-svg); + mask-image: var(--youtube-24-svg); +} + +%with-youtube-color-16-icon { + @extend %with-icon, %youtube-color-16-svg-prop; + background-image: var(--youtube-color-16-svg); +} +%with-youtube-color-16-mask { + @extend %with-mask, %youtube-color-16-svg-prop; + -webkit-mask-image: var(--youtube-color-16-svg); + mask-image: var(--youtube-color-16-svg); +} + +%with-youtube-color-24-icon { + @extend %with-icon, %youtube-color-24-svg-prop; + background-image: var(--youtube-color-24-svg); +} +%with-youtube-color-24-mask { + @extend %with-mask, %youtube-color-24-svg-prop; + -webkit-mask-image: var(--youtube-color-24-svg); + mask-image: var(--youtube-color-24-svg); +} + %with-zap-16-icon { @extend %with-icon, %zap-16-svg-prop; background-image: var(--zap-16-svg); diff --git a/ui/packages/consul-ui/app/styles/icons.scss b/ui/packages/consul-ui/app/styles/icons.scss index 96eac426b8..0ab6ec6c64 100644 --- a/ui/packages/consul-ui/app/styles/icons.scss +++ b/ui/packages/consul-ui/app/styles/icons.scss @@ -1,4 +1,71 @@ +%with-vault-100 { + @extend %with-vault-16-mask, %as-pseudo; + color: rgb(var(--tone-vault-500)); +} %with-vault-300 { @extend %with-vault-16-mask, %as-pseudo; color: rgb(var(--tone-vault-500)); } +%with-aws-100, +%with-aws-300 { + @extend %aws-color-16-svg-prop; + @extend %with-icon, %as-pseudo; + + background-image: var(--theme-dark-none) var(--aws-color-16-svg); + + -webkit-mask-image: var(--theme-light-none) var(--aws-color-16-svg); + -webkit-mask-repeat: var(--theme-light-none) no-repeat; + -webkit-mask-position: var(--theme-light-none) center; + mask-image: var(--theme-light-none) var(--aws-color-16-svg); + mask-repeat: var(--theme-light-none) no-repeat; + mask-position: var(--theme-light-none) center; + background-color: var(--theme-light-none) rgb(var(--white)); +} +%with-allow-100, +%with-aws-100, +%with-deny-100, +%with-l7-100, +%with-vault-100 { + width: 0.75rem; /* 12px */ + height: 0.75rem; /* 12px */ +} +%with-allow-500, +%with-deny-500, +%with-l7-500 { + width: 1.25rem; /* 20px */ + height: 1.25rem; /* 20px */ +} +%with-allow-300, +%with-allow-500 { + color: rgb(var(--tone-green-500)); +} +%with-deny-300, +%with-deny-500 { + color: rgb(var(--tone-red-500)); +} +%with-allow-300, +%with-allow-500, +%with-deny-300, +%with-deny-500, +%with-l7-300, +%with-l7-500 { + @extend %as-pseudo; +} +%with-allow-300 { + @extend %with-arrow-right-16-mask; +} +%with-allow-500 { + @extend %with-arrow-right-24-mask; +} +%with-deny-300 { + @extend %with-skip-16-mask; +} +%with-deny-500 { + @extend %with-skip-24-mask; +} +%with-l7-300 { + @extend %with-layers-16-mask; +} +%with-l7-500 { + @extend %with-layers-24-mask; +} From ac732ce82be0ef1d810b67744c9102e3733e26f6 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 2 Feb 2022 12:07:29 -0500 Subject: [PATCH 53/78] acl: un-embed ACLIdentity This is safer than embedding two interface because there are a number of places where we check the concrete type. If we check the concrete type on the top-level interface it will fail. So instead expose the ACLIdentity from a method. --- agent/acl_test.go | 6 ++++++ agent/consul/acl.go | 6 +++++- agent/consul/internal_endpoint.go | 2 +- agent/consul/operator_autopilot_endpoint.go | 8 ++++---- agent/consul/operator_raft_endpoint.go | 4 ++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/agent/acl_test.go b/agent/acl_test.go index 5ad4880ed0..ad7e8cebbb 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -39,6 +39,12 @@ type TestACLAgent struct { func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzResolver, resolveIdent identResolver) *TestACLAgent { t.Helper() + if resolveIdent == nil { + resolveIdent = func(s string) (structs.ACLIdentity, error) { + return nil, nil + } + } + a := &TestACLAgent{resolveAuthzFn: resolveAuthz, resolveIdentFn: resolveIdent} dataDir := testutil.TempDir(t, "acl-agent") diff --git a/agent/consul/acl.go b/agent/consul/acl.go index e18feb4150..350f9993b6 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1120,7 +1120,7 @@ func (r *ACLResolver) ResolveToken(token string) (ACLResolveResult, error) { type ACLResolveResult struct { acl.Authorizer // TODO: likely we can reduce this interface - structs.ACLIdentity + ACLIdentity structs.ACLIdentity } func (a ACLResolveResult) AccessorID() string { @@ -1130,6 +1130,10 @@ func (a ACLResolveResult) AccessorID() string { return a.ACLIdentity.ID() } +func (a ACLResolveResult) Identity() structs.ACLIdentity { + return a.ACLIdentity +} + func (r *ACLResolver) ACLsEnabled() bool { // Whether we desire ACLs to be enabled according to configuration if !r.config.ACLsEnabled { diff --git a/agent/consul/internal_endpoint.go b/agent/consul/internal_endpoint.go index 44b6af5aaf..0f7740a394 100644 --- a/agent/consul/internal_endpoint.go +++ b/agent/consul/internal_endpoint.go @@ -437,7 +437,7 @@ func (m *Internal) KeyringOperation( if err != nil { return err } - if err := m.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := m.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } switch args.Operation { diff --git a/agent/consul/operator_autopilot_endpoint.go b/agent/consul/operator_autopilot_endpoint.go index f4a3db65e6..2ee85bb062 100644 --- a/agent/consul/operator_autopilot_endpoint.go +++ b/agent/consul/operator_autopilot_endpoint.go @@ -21,7 +21,7 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { @@ -53,7 +53,7 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { @@ -88,7 +88,7 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *structs if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { @@ -155,7 +155,7 @@ func (op *Operator) AutopilotState(args *structs.DCSpecificRequest, reply *autop if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorRead(nil) != acl.Allow { diff --git a/agent/consul/operator_raft_endpoint.go b/agent/consul/operator_raft_endpoint.go index 431b455c08..33f9ad7ff1 100644 --- a/agent/consul/operator_raft_endpoint.go +++ b/agent/consul/operator_raft_endpoint.go @@ -85,7 +85,7 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest, if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { @@ -138,7 +138,7 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl if err != nil { return err } - if err := op.srv.validateEnterpriseToken(authz.ACLIdentity); err != nil { + if err := op.srv.validateEnterpriseToken(authz.Identity()); err != nil { return err } if authz.OperatorWrite(nil) != acl.Allow { From 7839b2d7e0e72a8ee870768d559c949ddca6b703 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 11 Nov 2021 19:16:53 -0500 Subject: [PATCH 54/78] ca: add a test that uses an intermediate CA as the primary CA This test found a bug in the secondary. We were appending the root cert to the PEM, but that cert was already appended. This was failing validation in Vault here: https://github.com/hashicorp/vault/blob/sdk/v0.3.0/sdk/helper/certutil/types.go#L329 Previously this worked because self signed certs have the same SubjectKeyID and AuthorityKeyID. So having the same self-signed cert repeated doesn't fail that check. However with an intermediate that is not self-signed, those values are different, and so we fail the check. A test I added in a previous commit should show that this continues to work with self-signed root certs as well. --- agent/connect/ca/provider_vault.go | 12 +-- agent/consul/leader_connect_ca.go | 12 ++- agent/consul/leader_connect_ca_test.go | 138 +++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 13 deletions(-) diff --git a/agent/connect/ca/provider_vault.go b/agent/connect/ca/provider_vault.go index 3a1d5128e7..c7b99a13f3 100644 --- a/agent/connect/ca/provider_vault.go +++ b/agent/connect/ca/provider_vault.go @@ -16,10 +16,9 @@ import ( vaultapi "github.com/hashicorp/vault/api" "github.com/mitchellh/mapstructure" - "github.com/hashicorp/consul/lib/decode" - "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/lib/decode" ) const ( @@ -400,17 +399,14 @@ func (v *VaultProvider) SetIntermediate(intermediatePEM, rootPEM string) error { return fmt.Errorf("cannot set an intermediate using another root in the primary datacenter") } - err := validateSetIntermediate( - intermediatePEM, rootPEM, - "", // we don't have access to the private key directly - v.spiffeID, - ) + // the private key is in vault, so we can't use it in this validation + err := validateSetIntermediate(intermediatePEM, rootPEM, "", v.spiffeID) if err != nil { return err } _, err = v.client.Logical().Write(v.config.IntermediatePKIPath+"intermediate/set-signed", map[string]interface{}{ - "certificate": fmt.Sprintf("%s\n%s", intermediatePEM, rootPEM), + "certificate": intermediatePEM, }) if err != nil { return err diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go index 203d3f2a40..5b795727fe 100644 --- a/agent/consul/leader_connect_ca.go +++ b/agent/consul/leader_connect_ca.go @@ -654,7 +654,7 @@ func (c *CAManager) secondaryInitializeIntermediateCA(provider ca.Provider, conf } if needsNewIntermediate { - if err := c.secondaryRenewIntermediate(provider, newActiveRoot); err != nil { + if err := c.secondaryRequestNewSigningCert(provider, newActiveRoot); err != nil { return err } } else { @@ -1028,9 +1028,11 @@ func (c *CAManager) primaryRenewIntermediate(provider ca.Provider, newActiveRoot return nil } -// secondaryRenewIntermediate should only be called while the state lock is held by -// setting the state to non-ready. -func (c *CAManager) secondaryRenewIntermediate(provider ca.Provider, newActiveRoot *structs.CARoot) error { +// secondaryRequestNewSigningCert creates a Certificate Signing Request, sends +// the request to the primary, and stores the received certificate in the +// provider. +// Should only be called while the state lock is held by setting the state to non-ready. +func (c *CAManager) secondaryRequestNewSigningCert(provider ca.Provider, newActiveRoot *structs.CARoot) error { csr, err := provider.GenerateIntermediateCSR() if err != nil { return err @@ -1145,7 +1147,7 @@ func (c *CAManager) RenewIntermediate(ctx context.Context, isPrimary bool) error // Enough time has passed, go ahead with getting a new intermediate. renewalFunc := c.primaryRenewIntermediate if !isPrimary { - renewalFunc = c.secondaryRenewIntermediate + renewalFunc = c.secondaryRequestNewSigningCert } errCh := make(chan error, 1) go func() { diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go index 17b310cb6a..c3115668e7 100644 --- a/agent/consul/leader_connect_ca_test.go +++ b/agent/consul/leader_connect_ca_test.go @@ -17,6 +17,7 @@ import ( "time" msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc" + vaultapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -606,6 +607,88 @@ func TestCAManager_UpdateConfiguration_Vault_Primary(t *testing.T) { require.Equal(t, connect.HexString(cert.SubjectKeyId), newRoot.SigningKeyID) } +func TestCAManager_Initialize_Vault_WithIntermediateAsPrimaryCA(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + ca.SkipIfVaultNotPresent(t) + + vault := ca.NewTestVaultServer(t) + vclient := vault.Client() + generateExternalRootCA(t, vclient) + + meshRootPath := "pki-root" + primaryCert := setupPrimaryCA(t, vclient, meshRootPath) + + _, s1 := testServerWithConfig(t, func(c *Config) { + c.CAConfig = &structs.CAConfiguration{ + Provider: "vault", + Config: map[string]interface{}{ + "Address": vault.Addr, + "Token": vault.RootToken, + "RootPKIPath": meshRootPath, + "IntermediatePKIPath": "pki-intermediate/", + // TODO: there are failures to init the CA system if these are not set + // to the values of the already initialized CA. + "PrivateKeyType": "ec", + "PrivateKeyBits": 256, + }, + } + }) + defer s1.Shutdown() + + runStep(t, "check primary DC", func(t *testing.T) { + testrpc.WaitForTestAgent(t, s1.RPC, "dc1") + + codec := rpcClient(t, s1) + roots := structs.IndexedCARoots{} + err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots) + require.NoError(t, err) + require.Len(t, roots.Roots, 1) + require.Equal(t, primaryCert, roots.Roots[0].RootCert) + + leafCertPEM := getLeafCert(t, codec, roots.TrustDomain, "dc1") + verifyLeafCert(t, roots.Roots[0], leafCertPEM) + }) + + // TODO: renew primary leaf signing cert + // TODO: rotate root + + runStep(t, "run secondary DC", func(t *testing.T) { + _, sDC2 := testServerWithConfig(t, func(c *Config) { + c.Datacenter = "dc2" + c.PrimaryDatacenter = "dc1" + c.CAConfig = &structs.CAConfiguration{ + Provider: "vault", + Config: map[string]interface{}{ + "Address": vault.Addr, + "Token": vault.RootToken, + "RootPKIPath": meshRootPath, + "IntermediatePKIPath": "pki-secondary/", + // TODO: there are failures to init the CA system if these are not set + // to the values of the already initialized CA. + "PrivateKeyType": "ec", + "PrivateKeyBits": 256, + }, + } + }) + defer sDC2.Shutdown() + joinWAN(t, sDC2, s1) + testrpc.WaitForActiveCARoot(t, sDC2.RPC, "dc2", nil) + + codec := rpcClient(t, sDC2) + roots := structs.IndexedCARoots{} + err := msgpackrpc.CallWithCodec(codec, "ConnectCA.Roots", &structs.DCSpecificRequest{}, &roots) + require.NoError(t, err) + require.Len(t, roots.Roots, 1) + + leafCertPEM := getLeafCert(t, codec, roots.TrustDomain, "dc2") + verifyLeafCert(t, roots.Roots[0], leafCertPEM) + + // TODO: renew secondary leaf signing cert + }) +} + func getLeafCert(t *testing.T, codec rpc.ClientCodec, trustDomain string, dc string) string { pk, _, err := connect.GeneratePrivateKey() require.NoError(t, err) @@ -624,3 +707,58 @@ func getLeafCert(t *testing.T, codec rpc.ClientCodec, trustDomain string, dc str return cert.CertPEM } + +func generateExternalRootCA(t *testing.T, client *vaultapi.Client) string { + t.Helper() + err := client.Sys().Mount("corp", &vaultapi.MountInput{ + Type: "pki", + Description: "External root, probably corporate CA", + Config: vaultapi.MountConfigInput{ + MaxLeaseTTL: "2400h", + DefaultLeaseTTL: "1h", + }, + }) + require.NoError(t, err, "failed to mount") + + resp, err := client.Logical().Write("corp/root/generate/internal", map[string]interface{}{ + "common_name": "corporate CA", + "ttl": "2400h", + }) + require.NoError(t, err, "failed to generate root") + return resp.Data["certificate"].(string) +} + +func setupPrimaryCA(t *testing.T, client *vaultapi.Client, path string) string { + t.Helper() + err := client.Sys().Mount(path, &vaultapi.MountInput{ + Type: "pki", + Description: "primary CA for Consul CA", + Config: vaultapi.MountConfigInput{ + MaxLeaseTTL: "2200h", + DefaultLeaseTTL: "1h", + }, + }) + require.NoError(t, err, "failed to mount") + + out, err := client.Logical().Write(path+"/intermediate/generate/internal", map[string]interface{}{ + "common_name": "primary CA", + "ttl": "2200h", + "key_type": "ec", + "key_bits": 256, + }) + require.NoError(t, err, "failed to generate root") + + intermediate, err := client.Logical().Write("corp/root/sign-intermediate", map[string]interface{}{ + "csr": out.Data["csr"], + "use_csr_values": true, + "format": "pem_bundle", + "ttl": "2200h", + }) + require.NoError(t, err, "failed to sign intermediate") + + _, err = client.Logical().Write(path+"/intermediate/set-signed", map[string]interface{}{ + "certificate": intermediate.Data["certificate"], + }) + require.NoError(t, err, "failed to set signed intermediate") + return ca.EnsureTrailingNewline(intermediate.Data["certificate"].(string)) +} From 45acc91c26f9fe1b9cddb489a93bf5551c8637e0 Mon Sep 17 00:00:00 2001 From: Jared Kirschner Date: Wed, 20 Oct 2021 08:09:59 -0700 Subject: [PATCH 55/78] Add changelog creation to contributor docs --- .github/CONTRIBUTING.md | 115 +++++++++++++-------- docs/contributing/add-a-changelog-entry.md | 42 ++++++++ docs/contributing/fork-the-project.md | 19 ++++ 3 files changed, 134 insertions(+), 42 deletions(-) create mode 100644 docs/contributing/add-a-changelog-entry.md create mode 100644 docs/contributing/fork-the-project.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9b55be796f..a2e713e003 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,4 +1,5 @@ # Contributing to Consul + >**Note:** We take Consul's security and our users' trust very seriously. >If you believe you have found a security issue in Consul, please responsibly >disclose by contacting us at security@hashicorp.com. @@ -14,7 +15,9 @@ talk to us! A great way to do this is in issues themselves. When you want to work on an issue, comment on it first and tell us the approach you want to take. ## Getting Started + ### Some Ways to Contribute + * Report potential bugs. * Suggest product enhancements. * Increase our test coverage. @@ -24,7 +27,8 @@ work on an issue, comment on it first and tell us the approach you want to take. are deployed from this repo. * Respond to questions about usage on the issue tracker or the Consul section of the [HashiCorp forum]: (https://discuss.hashicorp.com/c/consul) -### Reporting an Issue: +### Reporting an Issue + >Note: Issues on GitHub for Consul are intended to be related to bugs or feature requests. >Questions should be directed to other community resources such as the: [Discuss Forum](https://discuss.hashicorp.com/c/consul/29), [FAQ](https://www.consul.io/docs/faq.html), or [Guides](https://www.consul.io/docs/guides/index.html). @@ -53,68 +57,95 @@ issue. Stale issues will be closed. 4. The issue is addressed in a pull request or commit. The issue will be referenced in the commit message so that the code that fixes it is clearly - linked. + linked. Any change a Consul user might need to know about will include a + changelog entry in the PR. 5. The issue is closed. -## Building Consul - -If you wish to work on Consul itself, you'll first need [Go](https://golang.org) -installed (The version of Go should match the one of our [CI config's](https://github.com/hashicorp/consul/blob/main/.circleci/config.yml) Go image). - - -Next, clone this repository and then run `make dev`. In a few moments, you'll have a working -`consul` executable in `consul/bin` and `$GOPATH/bin`: - ->Note: `make dev` will build for your local machine's os/architecture. If you wish to build for all os/architecture combinations use `make`. - ## Making Changes to Consul -The first step to making changes is to fork Consul. Afterwards, the easiest way -to work on the fork is to set it as a remote of the Consul project: +### Prerequisites -1. Navigate to `$GOPATH/src/github.com/hashicorp/consul` -2. Rename the existing remote's name: `git remote rename origin upstream`. -3. Add your fork as a remote by running - `git remote add origin `. For example: - `git remote add origin https://github.com/myusername/consul`. -4. Checkout a feature branch: `git checkout -t -b new-feature` -5. Make changes -6. Push changes to the fork when ready to submit PR: - `git push -u origin new-feature` +If you wish to work on Consul itself, you'll first need to: +- install [Go](https://golang.org) (the version should match that of our + [CI config's](https://github.com/hashicorp/consul/blob/main/.circleci/config.yml) Go image). +- [fork the Consul repo](../docs/contributing/fork-the-project.md) -By following these steps you can push to your fork to create a PR, but the code on disk still -lives in the spot where the go cli tools are expecting to find it. +### Building Consul ->Note: If you make any changes to the code, run `gofmt -s -w` to automatically format the code according to Go standards. +To build Consul, run `make dev`. In a few moments, you'll have a working +`consul` executable in `consul/bin` and `$GOPATH/bin`: -## Testing +>Note: `make dev` will build for your local machine's os/architecture. If you wish to build for all os/architecture combinations, use `make`. -During development, it may be more convenient to check your work-in-progress by running only the tests which you expect to be affected by your changes, as the full test suite can take several minutes to execute. [Go's built-in test tool](https://golang.org/pkg/cmd/go/internal/test/) allows specifying a list of packages to test and the `-run` option to only include test names matching a regular expression. -The `go test -short` flag can also be used to skip slower tests. +### Modifying the Code -Examples (run from the repository root): -- `go test -v ./connect` will run all tests in the connect package (see `./connect` folder) -- `go test -v -run TestRetryJoin ./command/agent` will run all tests in the agent package (see `./command/agent` folder) with name substring `TestRetryJoin` +#### Code Formatting -When a pull request is opened CI will run all tests and lint to verify the change. +Go provides [tooling to apply consistent code formatting](https://golang.org/doc/effective_go#formatting). +If you make any changes to the code, run `gofmt -s -w` to automatically format the code according to Go standards. -## Go Module Dependencies +#### Updating Go Module Dependencies If a dependency is added or change, run `go mod tidy` to update `go.mod` and `go.sum`. -## Developer Documentation +#### Developer Documentation -Documentation about the Consul code base is under [./docs], +Developer-focused documentation about the Consul code base is under [./docs], and godoc package document can be read at [pkg.go.dev/github.com/hashicorp/consul]. [./docs]: ../docs/README.md [pkg.go.dev/github.com/hashicorp/consul]: https://pkg.go.dev/github.com/hashicorp/consul -### Checklists +### Testing + +During development, it may be more convenient to check your work-in-progress by running only the tests which you expect to be affected by your changes, as the full test suite can take several minutes to execute. [Go's built-in test tool](https://golang.org/pkg/cmd/go/internal/test/) allows specifying a list of packages to test and the `-run` option to only include test names matching a regular expression. +The `go test -short` flag can also be used to skip slower tests. + +Examples (run from the repository root): +- `go test -v ./connect` will run all tests in the connect package (see `./connect` folder) +- `go test -v -run TestRetryJoin ./command/agent` will run all tests in the agent package (see `./command/agent` folder) with name substring `TestRetryJoin` -Some common changes that many PRs require such as adding config fields, are -documented through checklists. +When a pull request is opened CI will run all tests and lint to verify the change. -Please check in [docs/](../docs/) for any `checklist-*.md` files that might help -with your change. +### Submitting a Pull Request + +Before writing any code, we recommend: +- Create a Github issue if none already exists for the code change you'd like to make. +- Write a comment on the Github issue indicating you're interested in contributing so +maintainers can provide their perspective if needed. + +Keep your pull requests (PRs) small and open them early so you can get feedback on +approach from maintainers before investing your time in larger changes. For example, +see how [applying URL-decoding of resource names across the whole HTTP API](https://github.com/hashicorp/consul/issues/11258) +started with [iterating on the right approach for a few endpoints](https://github.com/hashicorp/consul/pull/11335) +before applying more broadly. + +When you're ready to submit a pull request: +1. Review the [list of checklists](#checklists) for common changes and follow any + that apply to your work. +2. Include evidence that your changes work as intended (e.g., add/modify unit tests; + describe manual tests you ran, in what environment, + and the results including screenshots or terminal output). +3. Open the PR from your fork against base repository `hashicorp/consul` and branch `main`. + - [Link the PR to its associated issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue). +4. Include any specific questions that you have for the reviewer in the PR description + or as a PR comment in Github. + - If there's anything you find the need to explain or clarify in the PR, consider + whether that explanation should be added in the source code as comments. + - You can submit a [draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) + if your changes aren't finalized but would benefit from in-process feedback. +5. If there's any reason Consul users might need to know about this change, + [add a changelog entry](../docs/contributing/add-a-changelog-entry.md). +6. After you submit, the Consul maintainers team needs time to carefully review your + contribution and ensure it is production-ready, considering factors such as: security, + backwards-compatibility, potential regressions, etc. +7. After you address Consul maintainer feedback and the PR is approved, a Consul maintainer + will merge it. Your contribution will be available from the next major release (e.g., 1.x) + unless explicitly backported to an existing or previous major release by the maintainer. + +#### Checklists + +Some common changes that many PRs require are documented through checklists as +`checklist-*.md` files in [docs/](../docs/), including: +- [Adding config fields](../docs/config/checklist-adding-config-fields.md) \ No newline at end of file diff --git a/docs/contributing/add-a-changelog-entry.md b/docs/contributing/add-a-changelog-entry.md new file mode 100644 index 0000000000..4bba2e668e --- /dev/null +++ b/docs/contributing/add-a-changelog-entry.md @@ -0,0 +1,42 @@ +# Adding a Changelog Entry + +Any change that a Consul user might need to know about should have a changelog entry. + +What doesn't need a changelog entry? +- Docs changes +- Typos fixes, unless they are in a public-facing API +- Code changes we are certain no Consul users will need to know about + +To include a [changelog entry](../.changelog) in a PR, commit a text file +named `.changelog/.txt`, where `` is the number associated with the open +PR in Github. The text file should describe the changes in the following format: + +```` +```release-note: +: +``` +```` + +Valid values for `` include: +- `feature`: for the addition of a new feature +- `improvement`: for an improvement (not a bug fix) to an existing feature +- `bug`: for a bug fix +- `security`: for any Common Vulnerabilities and Exposures (CVE) resolutions +- `breaking-change`: for any change that is not fully backwards-compatible +- `deprecation`: for functionality which is now marked for removal in a future release + +`` is meant to categorize the functionality affected by the change. +Some common values are: +- `checks`: related to node or service health checks +- `cli`: related to the command-line interface and its commands +- `config`: related to configuration changes (e.g., adding a new config option) +- `connect`: catch-all for the Connect subsystem that provides service mesh functionality + if no more specific `` applies +- `http`: related to the HTTP API interface and its endpoints +- `dns`: related to DNS functionality +- `ui`: any change related to the built-in Consul UI (`website/` folder) + +Look in the [`.changelog/`](../.changelog) folder for examples of existing changelog entries. + +If a PR deserves multiple changelog entries, just add multiple entries separated by a newline +in the format described above to the `.changelog/.txt` file. diff --git a/docs/contributing/fork-the-project.md b/docs/contributing/fork-the-project.md new file mode 100644 index 0000000000..941c0fe27f --- /dev/null +++ b/docs/contributing/fork-the-project.md @@ -0,0 +1,19 @@ +# Forking the Consul Repo + +Community members wishing to contribute code to Consul must fork the Consul project +(`your-github-username/consul`). Branches pushed to that fork can then be submitted +as pull requests to the upstream project (`hashicorp/consul`). + +To locally clone the repo so that you can pull the latest from the upstream project +(`hashicorp/consul`) and push changes to your own fork (`your-github-username/consul`): + +1. [Create the forked repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo#forking-a-repository) (`your-github-username/consul`) +2. Clone the `hashicorp/consul` repository and `cd` into the folder +3. Make `hashicorp/consul` the `upstream` remote rather than `origin`: + `git remote rename origin upstream`. +4. Add your fork as the `origin` remote. For example: + `git remote add origin https://github.com/myusername/consul` +5. Checkout a feature branch: `git checkout -t -b new-feature` +6. [Make changes](../../.github/CONTRIBUTING.md#modifying-the-code) +7. Push changes to the fork when ready to [submit a PR](../../.github/CONTRIBUTING.md#submitting-a-pull-request): + `git push -u origin new-feature` \ No newline at end of file From d12e0ceddf2fe417edae64643b6ce474def47eaa Mon Sep 17 00:00:00 2001 From: Evan Culver Date: Wed, 2 Feb 2022 17:31:08 -0800 Subject: [PATCH 56/78] Add changelog entry --- .changelog/11956.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/11956.txt diff --git a/.changelog/11956.txt b/.changelog/11956.txt new file mode 100644 index 0000000000..716a6f1ae6 --- /dev/null +++ b/.changelog/11956.txt @@ -0,0 +1,3 @@ +```release-note:improvement +ci: Enable security scanning for CRT +``` From a6f51d8c1bef626f813697c6fd3cdd08f4ee6f7b Mon Sep 17 00:00:00 2001 From: Blake Covarrubias Date: Wed, 2 Feb 2022 16:42:05 -0800 Subject: [PATCH 57/78] docs: Fix discrepancy with sidecar min/max port range Remove incorrect sidecar port range on docs for built-in proxy. Updates the bind_port/port fields on the built-in proxy and sidecar service registration pages to link to the `sidecar_min_port` and `sidecar_max_port` configuration options for the defined port range. Fixes #12253 --- website/content/docs/connect/proxies/built-in.mdx | 8 +++----- .../content/docs/connect/registration/sidecar-service.mdx | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/website/content/docs/connect/proxies/built-in.mdx b/website/content/docs/connect/proxies/built-in.mdx index c37c0e94fa..fd1330c8d7 100644 --- a/website/content/docs/connect/proxies/built-in.mdx +++ b/website/content/docs/connect/proxies/built-in.mdx @@ -13,7 +13,6 @@ The [Envoy proxy](/docs/connect/proxies/envoy) should be used for production dep Consul comes with a built-in L4 proxy for testing and development with Consul Connect service mesh. - ## Getting Started To get started with the built-in proxy and see a working example you can follow the [Getting Started](https://learn.hashicorp.com/tutorials/consul/get-started-service-networking) tutorial. @@ -57,10 +56,9 @@ All fields are optional with a reasonable default. _public_ mTLS listener to. It defaults to the same address the agent binds to. - `bind_port` - The port the proxy will bind its _public_ - mTLS listener to. If not provided, the agent will attempt to assign one from its - [configured proxy port range](/docs/agent/options#sidecar_min_port) if available. - By default the range is [20000, 20255] and the port is selected at random from - that range. + mTLS listener to. If not provided, the agent will assign a random port from its + configured proxy port range specified by [`sidecar_min_port`](/docs/agent/options#sidecar_min_port) + and [`sidecar_max_port`](/docs/agent/options#sidecar_max_port). - `local_service_address`- The `[address]:port` that the proxy should use to connect to the local application instance. By default diff --git a/website/content/docs/connect/registration/sidecar-service.mdx b/website/content/docs/connect/registration/sidecar-service.mdx index 850d954b3d..c08bd17916 100644 --- a/website/content/docs/connect/registration/sidecar-service.mdx +++ b/website/content/docs/connect/registration/sidecar-service.mdx @@ -130,9 +130,9 @@ proxy. - `name` - Defaults to being `-sidecar-proxy`. - `tags` - Defaults to the tags of the parent service. - `meta` - Defaults to the service metadata of the parent service. -- `port` - Defaults to being auto-assigned from a [configurable - range](/docs/agent/options#sidecar_min_port) that is - by default `[21000, 21255]`. +- `port` - Defaults to being auto-assigned from a configurable + range specified by [`sidecar_min_port`](/docs/agent/options#sidecar_min_port) + and [`sidecar_max_port`](/docs/agent/options#sidecar_max_port). - `kind` - Defaults to `connect-proxy`. This can't be overridden currently. - `check`, `checks` - By default we add a TCP check on the local address and port for the proxy, and a [service alias From 39f15306d98ed858be8dec5d55a26e5009f19acd Mon Sep 17 00:00:00 2001 From: John Cowen Date: Thu, 3 Feb 2022 08:40:03 +0000 Subject: [PATCH 58/78] ui: Change approach to loading debug.css (#12242) We need a way to load certain CSS based on the environment you are viewing, i.e. we have debug CSS that we use for our Eng Documentation and various other DX utilities that shouldn't be compiled into our production or test builds. Previously we would compile two entirely different CSS files (app and debug) and the load one or the other depending on which environment you were in. This approach just empties out the debug.css file in certain environments (prod/test) which means we can just import that file from app. When in staging/development this imports the contents of debug.css (quite a bit of CSS) whereas when building for production/test this debug.css is emptied out during the build process. There is a slight little hack in order to have this work, we import _debug.scss which imports the debug.scss file. I couldn't for the life of me figure out how to have broccoli empty out a file during the build process, so instead we essentially copy over debug.scss during dev and create an empty file during prod to _debug.scss. When using make build to build an artifact for production CSS remains at ~58kb (during dev its a lot bigger than this) --- ui/packages/consul-ui/GNUmakefile | 5 ++++- ui/packages/consul-ui/app/styles/app.scss | 3 +++ ui/packages/consul-ui/app/styles/debug.scss | 1 - ui/packages/consul-ui/ember-cli-build.js | 8 +------ .../lib/colocated-components/index.js | 21 ++++++++++++------- .../lib/startup/templates/head.html.js | 4 +--- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/ui/packages/consul-ui/GNUmakefile b/ui/packages/consul-ui/GNUmakefile index d667f562c6..0855de1dab 100644 --- a/ui/packages/consul-ui/GNUmakefile +++ b/ui/packages/consul-ui/GNUmakefile @@ -5,8 +5,8 @@ all: build deps: ../../node_modules clean +# incase we ever need to clean anything again clean: - rm -rf ./tmp build-staging: deps yarn run build:staging @@ -17,6 +17,9 @@ build-ci: deps build: deps yarn run build +build-debug: + BROCCOLI_DEBUG=* $(MAKE) build + start: deps yarn run start diff --git a/ui/packages/consul-ui/app/styles/app.scss b/ui/packages/consul-ui/app/styles/app.scss index 3834601dc0..c2ee814d83 100644 --- a/ui/packages/consul-ui/app/styles/app.scss +++ b/ui/packages/consul-ui/app/styles/app.scss @@ -15,3 +15,6 @@ @import 'icons'; /* global control of themeable components */ @import 'themes'; +/* debug only, this is empty during a production build */ +/* but uses the contents of ./debug.scss during dev */ +@import '_debug'; diff --git a/ui/packages/consul-ui/app/styles/debug.scss b/ui/packages/consul-ui/app/styles/debug.scss index 5ca08667b7..bb52730089 100644 --- a/ui/packages/consul-ui/app/styles/debug.scss +++ b/ui/packages/consul-ui/app/styles/debug.scss @@ -1,4 +1,3 @@ -@import './app'; @import './base/icons/debug'; @import 'prism-coldark-dark'; diff --git a/ui/packages/consul-ui/ember-cli-build.js b/ui/packages/consul-ui/ember-cli-build.js index 7884e859b1..ec8397f89c 100644 --- a/ui/packages/consul-ui/ember-cli-build.js +++ b/ui/packages/consul-ui/ember-cli-build.js @@ -97,14 +97,8 @@ module.exports = function(defaults, $ = process.env) { // exclude docfy '@docfy/ember' ]; - } else { - // add debug css is we are not in test or production environments - outputPaths.app = { - css: { - 'debug': '/assets/debug.css' - } - } } + if(['production'].includes(env)) { // everything apart from production is 'debug', including test // which means this and everything it affects is never tested diff --git a/ui/packages/consul-ui/lib/colocated-components/index.js b/ui/packages/consul-ui/lib/colocated-components/index.js index 33428463f1..ef3a1130ac 100644 --- a/ui/packages/consul-ui/lib/colocated-components/index.js +++ b/ui/packages/consul-ui/lib/colocated-components/index.js @@ -3,6 +3,8 @@ const Funnel = require('broccoli-funnel'); const mergeTrees = require('broccoli-merge-trees'); +const writeFile = require('broccoli-file-creator'); +const read = require('fs').readFileSync; module.exports = { name: require('./package').name, @@ -12,15 +14,18 @@ module.exports = { * @import 'app-name/components/component-name/index.scss' */ treeForStyles: function(tree) { + let debug = read(`${this.project.root}/app/styles/debug.scss`); + if (['production', 'test'].includes(process.env.EMBER_ENV)) { + debug = ''; + } return this._super.treeForStyles.apply(this, [ - mergeTrees( - (tree || []).concat([ - new Funnel(`${this.project.root}/app/components`, { - destDir: `app/components`, - include: ['**/*.scss'], - }), - ]) - ), + mergeTrees([ + writeFile(`_debug.scss`, debug), + new Funnel(`${this.project.root}/app/components`, { + destDir: `app/components`, + include: ['**/*.scss'], + }), + ]), ]); }, }; diff --git a/ui/packages/consul-ui/lib/startup/templates/head.html.js b/ui/packages/consul-ui/lib/startup/templates/head.html.js index 1d8d38ea01..fc2c7dd49b 100644 --- a/ui/packages/consul-ui/lib/startup/templates/head.html.js +++ b/ui/packages/consul-ui/lib/startup/templates/head.html.js @@ -8,9 +8,7 @@ module.exports = ({ appName, environment, rootURL, config }) => ` - + ${ environment === 'test' ? `` : `` } From f504a027764a4a024ffb28bb975564b0d73e8622 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 8 Sep 2021 19:50:42 -0400 Subject: [PATCH 59/78] Replace build script with 'go build' --- .circleci/config.yml | 20 +++-- GNUmakefile | 18 ++-- build-support/functions/20-build.sh | 110 +------------------------ build-support/scripts/build-local.sh | 107 ------------------------ website/content/docs/install/index.mdx | 63 +++++++------- 5 files changed, 56 insertions(+), 262 deletions(-) delete mode 100755 build-support/scripts/build-local.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index cb1b1a5885..02fb797700 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -359,7 +359,7 @@ jobs: path: /tmp/jsonfile - run: *notify-slack-failure - # build all distros + # build is a templated job for build-x build-distros: &build-distros docker: - image: *GOLANG_IMAGE @@ -367,7 +367,13 @@ jobs: <<: *ENVIRONMENT steps: - checkout - - run: ./build-support/scripts/build-local.sh + - run: + name: Build + command: | + for os in $XC_OS; do + target="./pkg/bin/${GOOS}_${GOARCH}/" + GOOS="$os" CGO_ENABLED=0 go build -o "$target" -ldflags "$(GOLDFLAGS)" -tags "$(GOTAGS)" + done # save dev build to CircleCI - store_artifacts: @@ -380,7 +386,7 @@ jobs: environment: <<: *build-env XC_OS: "freebsd linux windows" - XC_ARCH: "386" + GOARCH: "386" # build all amd64 architecture supported OS binaries build-amd64: @@ -388,7 +394,7 @@ jobs: environment: <<: *build-env XC_OS: "darwin freebsd linux solaris windows" - XC_ARCH: "amd64" + GOARCH: "amd64" # build all arm/arm64 architecture supported OS binaries build-arm: @@ -433,7 +439,11 @@ jobs: - attach_workspace: # this normally runs as the first job and has nothing to attach; only used in main branch after rebuilding UI at: . - run: - command: make dev + name: Build + command: | + make dev + mkdir -p /home/circleci/go/bin + cp ./bin/consul /home/circleci/go/bin/consul # save dev build to pass to downstream jobs - persist_to_workspace: diff --git a/GNUmakefile b/GNUmakefile index 823ca06fe0..b47d04dc4f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -15,8 +15,6 @@ GOTOOLS = \ github.com/hashicorp/lint-consul-retry@master GOTAGS ?= -GOOS?=$(shell go env GOOS) -GOARCH?=$(shell go env GOARCH) GOPATH=$(shell go env GOPATH) MAIN_GOPATH=$(shell go env GOPATH | cut -d: -f1) @@ -137,20 +135,17 @@ ifdef SKIP_DOCKER_BUILD ENVOY_INTEG_DEPS=noop endif -# all builds binaries for all targets -all: bin +all: dev-build # used to make integration dependencies conditional noop: ; -bin: tools - @$(SHELL) $(CURDIR)/build-support/scripts/build-local.sh - -# dev creates binaries for testing locally - these are put into ./bin and $GOPATH +# dev creates binaries for testing locally - these are put into ./bin dev: dev-build dev-build: - @$(SHELL) $(CURDIR)/build-support/scripts/build-local.sh -o $(GOOS) -a $(GOARCH) + mkdir -p bin + CGO_ENABLED=0 go build -o ./bin -ldflags "$(GOLDFLAGS)" -tags "$(GOTAGS)" dev-docker: linux @echo "Pulling consul container image - $(CONSUL_IMAGE_VERSION)" @@ -178,9 +173,10 @@ ifeq ($(CIRCLE_BRANCH), main) @docker push $(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):latest endif -# linux builds a linux package independent of the source platform +# linux builds a linux binary independent of the source platform linux: - @$(SHELL) $(CURDIR)/build-support/scripts/build-local.sh -o linux -a amd64 + mkdir -p bin + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin -ldflags "$(GOLDFLAGS)" -tags "$(GOTAGS)" # dist builds binaries for all platforms and packages them for distribution dist: diff --git a/build-support/functions/20-build.sh b/build-support/functions/20-build.sh index 7ce6d332c4..f878fb79eb 100644 --- a/build-support/functions/20-build.sh +++ b/build-support/functions/20-build.sh @@ -326,8 +326,7 @@ function build_consul { -e CGO_ENABLED=0 \ -e GOLDFLAGS="${GOLDFLAGS}" \ -e GOTAGS="${GOTAGS}" \ - ${image_name} \ - ./build-support/scripts/build-local.sh -o "${XC_OS}" -a "${XC_ARCH}") + ${image_name} make linux ret=$? if test $ret -eq 0 @@ -354,110 +353,3 @@ function build_consul { popd > /dev/null return $ret } - -function build_consul_local { - # Arguments: - # $1 - Path to the top level Consul source - # $2 - Space separated string of OSes to build. If empty will use env vars for determination. - # $3 - Space separated string of architectures to build. If empty will use env vars for determination. - # $4 - Subdirectory to put binaries in under pkg/bin (optional) - # - # Returns: - # 0 - success - # * - error - # - # Note: - # The GOLDFLAGS and GOTAGS environment variables will be used if set - # If the CONSUL_DEV environment var is truthy only the local platform/architecture is built. - # If the XC_OS or the XC_ARCH environment vars are present then only those platforms/architectures - # will be built. Otherwise all supported platform/architectures are built - # The GOXPARALLEL environment variable is used if set - - if ! test -d "$1" - then - err "ERROR: '$1' is not a directory. build_consul must be called with the path to the top level source as the first argument'" - return 1 - fi - - local sdir="$1" - local build_os="$2" - local build_arch="$3" - local extra_dir_name="$4" - local extra_dir="" - - if test -n "${extra_dir_name}" - then - extra_dir="${extra_dir_name}/" - fi - - pushd ${sdir} > /dev/null - if is_set "${CONSUL_DEV}" - then - if test -z "${XC_OS}" - then - XC_OS=$(go env GOOS) - fi - - if test -z "${XC_ARCH}" - then - XC_ARCH=$(go env GOARCH) - fi - fi - XC_OS=${XC_OS:-"solaris darwin freebsd linux windows"} - XC_ARCH=${XC_ARCH:-"386 amd64 arm arm64"} - - if test -z "${build_os}" - then - build_os="${XC_OS}" - fi - - if test -z "${build_arch}" - then - build_arch="${XC_ARCH}" - fi - - status_stage "==> Building Consul - OSes: ${build_os}, Architectures: ${build_arch}" - mkdir pkg.bin.new 2> /dev/null - - status "Building sequentially with go install" - for os in ${build_os} - do - for arch in ${build_arch} - do - outdir="pkg.bin.new/${extra_dir}${os}_${arch}" - osarch="${os}/${arch}" - - if ! supported_osarch "${osarch}" - then - continue - fi - echo "---> ${osarch}" - - mkdir -p "${outdir}" - GOBIN_EXTRA="" - if test "${os}" != "$(go env GOHOSTOS)" -o "${arch}" != "$(go env GOHOSTARCH)" - then - GOBIN_EXTRA="${os}_${arch}/" - fi - binname="consul" - if [ $os == "windows" ];then - binname="consul.exe" - fi - debug_run env CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go install -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" && cp "${MAIN_GOPATH}/bin/${GOBIN_EXTRA}${binname}" "${outdir}/${binname}" - if test $? -ne 0 - then - err "ERROR: Failed to build Consul for ${osarch}" - rm -r pkg.bin.new - return 1 - fi - done - done - - build_consul_post "${sdir}" "${extra_dir_name}" - if test $? -ne 0 - then - err "ERROR: Failed postprocessing Consul binaries" - return 1 - fi - return 0 -} diff --git a/build-support/scripts/build-local.sh b/build-support/scripts/build-local.sh deleted file mode 100755 index 45f33282d3..0000000000 --- a/build-support/scripts/build-local.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash -SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" -pushd $(dirname ${BASH_SOURCE[0]}) > /dev/null -SCRIPT_DIR=$(pwd) -pushd ../.. > /dev/null -SOURCE_DIR=$(pwd) -popd > /dev/null -pushd ../functions > /dev/null -FN_DIR=$(pwd) -popd > /dev/null -popd > /dev/null - -source "${SCRIPT_DIR}/functions.sh" - -function usage { -cat <<-EOF -Usage: ${SCRIPT_NAME} [] - -Description: - This script will build the Consul binary on the local system. - All the requisite tooling must be installed for this to be - successful. - -Options: - - -s | --source DIR Path to source to build. - Defaults to "${SOURCE_DIR}" - - -o | --os OSES Space separated string of OS - platforms to build. - - -a | --arch ARCH Space separated string of - architectures to build. - - -h | --help Print this help text. -EOF -} - -function err_usage { - err "$1" - err "" - err "$(usage)" -} - -function main { - declare sdir="${SOURCE_DIR}" - declare build_os="" - declare build_arch="" - - - while test $# -gt 0 - do - case "$1" in - -h | --help ) - usage - return 0 - ;; - -s | --source ) - if test -z "$2" - then - err_usage "ERROR: option -s/--source requires an argument" - return 1 - fi - - if ! test -d "$2" - then - err_usage "ERROR: '$2' is not a directory and not suitable for the value of -s/--source" - return 1 - fi - - sdir="$2" - shift 2 - ;; - -o | --os ) - if test -z "$2" - then - err_usage "ERROR: option -o/--os requires an argument" - return 1 - fi - - build_os="$2" - shift 2 - ;; - -a | --arch ) - if test -z "$2" - then - err_usage "ERROR: option -a/--arch requires an argument" - return 1 - fi - - build_arch="$2" - shift 2 - ;; - * ) - err_usage "ERROR: Unknown argument: '$1'" - return 1 - ;; - esac - done - - build_consul_local "${sdir}" "${build_os}" "${build_arch}" || return 1 - - return 0 -} - -main "$@" -exit $? \ No newline at end of file diff --git a/website/content/docs/install/index.mdx b/website/content/docs/install/index.mdx index 95ac37996e..da8d113fcc 100644 --- a/website/content/docs/install/index.mdx +++ b/website/content/docs/install/index.mdx @@ -50,41 +50,44 @@ a copy of [`git`](https://www.git-scm.com/) in your `PATH`. 1. Build Consul for your target system. The binary will be placed in `./bin` (relative to the git checkout). - - - - - -```shell-session -$ make dev -``` + + + + + + ```shell-session + $ make dev + ``` - - + + -Specify your target system by setting the following environment variables -before building: + Specify your target system by setting the following environment variables + before building: -- `GOOS`: Target operating system. Valid values include: - `linux`, `darwin`, `windows`, `solaris`, `freebsd`. -- `GOARCH`: Target architecture. Valid values include: - `386`, `amd64`, `arm`, `arm64` + - `GOOS`: Target operating system. Valid values include: + `linux`, `darwin`, `windows`, `solaris`, `freebsd`. + - `GOARCH`: Target architecture. Valid values include: + `386`, `amd64`, `arm`, `arm64` -```shell-session -$ export GOOS=linux GOARCH=amd64 -$ make dev -``` + ```shell-session + $ export GOOS=linux GOARCH=amd64 + $ make dev + ``` - - + + ## Verifying the Installation From 918a1057c7a7033810f1a878a778203bab5ee5dd Mon Sep 17 00:00:00 2001 From: Jared Kirschner Date: Mon, 31 Jan 2022 12:01:40 -0800 Subject: [PATCH 60/78] Update Consul logo assets on docs site --- website/public/img/logo-hashicorp.svg | 99 +++++++++++++++++++++++++-- website/public/img/logo-text.svg | 97 ++++++++++++++++++++++++-- 2 files changed, 183 insertions(+), 13 deletions(-) diff --git a/website/public/img/logo-hashicorp.svg b/website/public/img/logo-hashicorp.svg index 3630d56bf0..58ee99fbb7 100644 --- a/website/public/img/logo-hashicorp.svg +++ b/website/public/img/logo-hashicorp.svg @@ -1,7 +1,94 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/website/public/img/logo-text.svg b/website/public/img/logo-text.svg index 6f06a71561..513b3ec4d4 100644 --- a/website/public/img/logo-text.svg +++ b/website/public/img/logo-text.svg @@ -1,8 +1,91 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + From f020cedab29467ed630ac173a0accd3ea5747643 Mon Sep 17 00:00:00 2001 From: David Yu Date: Thu, 3 Feb 2022 08:12:47 -0800 Subject: [PATCH 61/78] docs: formatting and update to consul-k8s 0.40.0 (#12256) * docs: formatting and update to consul-k8s 0.40.0 * Update index.mdx * Update index.mdx * test indentation * Update index.mdx * formatting * Update index.mdx * Update index.mdx * Update index.mdx * Update index.mdx * Update website/content/docs/k8s/upgrade/index.mdx Co-authored-by: mrspanishviking * Update website/content/docs/k8s/upgrade/index.mdx Co-authored-by: mrspanishviking * Update website/content/docs/k8s/upgrade/index.mdx Co-authored-by: mrspanishviking Co-authored-by: mrspanishviking --- website/content/docs/k8s/upgrade/index.mdx | 214 +++++++++++---------- 1 file changed, 110 insertions(+), 104 deletions(-) diff --git a/website/content/docs/k8s/upgrade/index.mdx b/website/content/docs/k8s/upgrade/index.mdx index 05eaf5bba7..7ce00caf39 100644 --- a/website/content/docs/k8s/upgrade/index.mdx +++ b/website/content/docs/k8s/upgrade/index.mdx @@ -18,12 +18,16 @@ for those changes to take effect. For example, if you've installed Consul with the following: + + ```yaml global: name: consul connectInject: enabled: false ``` + + And you wish to set `connectInject.enabled` to `true`: @@ -35,22 +39,22 @@ connectInject: + enabled: true ``` -Perform the following steps: +To update your deployment configuration using Helm, perform the following steps. 1. Determine your current installed chart version. -```bash -helm list --filter consul -NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION -consul default 2 2020-09-30 ... deployed consul-0.24.0 1.8.2 -``` + ```shell-session + $ helm list --filter consul --namespace consul + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + consul consul 2 2022-02-02 21:49:45.647678 -0800 PST deployed consul-0.40.0 1.11.2 + ``` -In this example, version `0.24.0` (from `consul-0.24.0`) is being used. + In this example, version `0.40.0` (from `consul-k8s:0.40.0`) is being used, and Consul on Kubernetes is installed in the `consul` namespace. 1. Perform a `helm upgrade`: ```shell-session - $ helm upgrade consul hashicorp/consul --version 0.24.0 --values /path/to/my/values.yaml + $ helm upgrade consul hashicorp/consul --namespace consul --version 0.40.0 --values /path/to/my/values.yaml ``` **Before performing the upgrade, be sure you've read the other sections on this page, @@ -68,43 +72,43 @@ certain Helm chart version. 1. Update your local Helm repository cache: -```bash -helm repo update -``` - -1. List all available versions: + ```shell-session + $ helm repo update + ``` -```shell-session hideClipboard -$ helm search repo hashicorp/consul --versions -NAME CHART VERSION APP VERSION DESCRIPTION -hashicorp/consul 0.24.1 1.8.2 Official HashiCorp Consul Chart -hashicorp/consul 0.24.0 1.8.1 Official HashiCorp Consul Chart -... -``` +1. List all available versions. Here you can observe that the latest version of `0.40.0`. -Here we can see that the latest version of `0.24.1`. + ```shell-session hideClipboard + $ helm search repo hashicorp/consul --versions + NAME CHART VERSION APP VERSION DESCRIPTION + hashicorp/consul 0.40.0 1.11.2 Official HashiCorp Consul Chart + hashicorp/consul 0.39.0 1.11.1 Official HashiCorp Consul Chart + hashicorp/consul 0.38.0 1.10.4 Official HashiCorp Consul Chart + hashicorp/consul 0.37.0 1.10.4 Official HashiCorp Consul Chart + ... + ``` -1. To determine which version you have installed, issue the following command: + 1. To determine which version you have installed, issue the following command: -```shell-session -$ helm list --filter consul -NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION -consul default 2 2020-09-30 ... deployed consul-0.24.0 1.8.2 -``` + ```shell-session + $ helm list --filter consul --namespace consul + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + consul consul 2 2022-02-02 21:49:45.647678 -0800 PST deployed consul-0.39.0 1.11.1 + ``` -In this example, version `0.24.0` (from `consul-0.24.0`) is being used. -If you want to upgrade to the latest `0.24.1` version, use the following procedure: + In this example, version `0.39.0` (from `consul-k8s:0.39.0`) is being used. + If you want to upgrade to the latest `0.40.0` version, use the following procedure: -1. Check the changelog for any breaking changes from that version and any versions in between: https://github.com/hashicorp/consul-helm/blob/master/CHANGELOG.md. +1. Check the changelog for any breaking changes from that version and any versions in between: [CHANGELOG.md](https://github.com/hashicorp/consul-k8s/blob/main/CHANGELOG.md). 1. Upgrade by performing a `helm upgrade` with the `--version` flag: -```shell-session -$ helm upgrade consul hashicorp/consul --version 0.24.1 --values /path/to/my/values.yaml -``` + ```shell-session + $ helm upgrade consul hashicorp/consul --namespace consul --version 0.40.0 --values /path/to/my/values.yaml + ``` -**Before performing the upgrade, be sure you've read the other sections on this page, -continuing at [Determining What Will Change](#determining-what-will-change).** + **Before performing the upgrade, be sure you've read the other sections on this page, + continuing at [Determining What Will Change](#determining-what-will-change).** ### Consul Version Upgrade @@ -123,29 +127,27 @@ to update to the new version. ```yaml global: - image: consul:1.8.3 + image: consul:1.11.2 ``` -1. Determine your current installed chart version: - -```shell-session -$ helm list --filter consul -NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION -consul default 2 2020-09-30 ... deployed consul-0.24.0 1.8.2 -``` +1. Determine your current installed chart version. In this example, version `0.39.0` (from `consul-k8s:0.39.0`) is being used. -In this example, version `0.24.0` (from `consul-0.24.0`) is being used. + ```shell-session + $ helm list --filter consul --namespace consul + NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION + consul consul 2 2022-02-02 21:49:45.647678 -0800 PST deployed consul-0.39.0 1.11.1 + ``` 1. Perform a `helm upgrade`: -```shell-session -$ helm upgrade consul hashicorp/consul --version 0.24.0 --values /path/to/my/values.yaml -``` + ```shell-session + $ helm upgrade consul hashicorp/consul --namespace consul --version 0.39.0 --values /path/to/my/values.yaml + ``` -**Before performing the upgrade, be sure you've read the other sections on this page, -continuing at [Determining What Will Change](#determining-what-will-change).** + **Before performing the upgrade, be sure you have read the other sections on this page, + continuing at [Determining What Will Change](#determining-what-will-change).** ~> NOTE: It's important to always set the `--version` flag, because otherwise Helm will use the most up-to-date version in its local cache, which may result in an @@ -163,36 +165,36 @@ that can be used. 1. Install `helm-diff` with: -```bash -helm plugin install https://github.com/databus23/helm-diff -``` + ```shell-session + $ helm plugin install https://github.com/databus23/helm-diff + ``` 1. If you are updating your `values.yaml` file, do so now. 1. Take the same `helm upgrade` command you were planning to issue but perform `helm diff upgrade` instead of `helm upgrade`: -```shell-session -$ helm diff upgrade consul hashicorp/consul --version 0.24.1 --values /path/to/your/values.yaml -``` + ```shell-session + $ helm diff upgrade consul hashicorp/consul --namespace consul --version 0.40.0 --values /path/to/your/values.yaml + ``` -This will print out the manifests that will be updated and their diffs. + This will print out the manifests that will be updated and their diffs. 1. To see only the objects that will be updated, add `| grep "has changed"`: -```shell-session -$ helm diff upgrade consul hashicorp/consul --version 0.24.1 --values /path/to/your/values.yaml | - grep "has changed" -``` + ```shell-session + $ helm diff upgrade consul hashicorp/consul --namespace consul --version 0.40.0 --values /path/to/your/values.yaml | + grep "has changed" + ``` 1. Take specific note if `consul-client, DaemonSet` or `consul-server, StatefulSet` are listed. This means that your Consul client daemonset or Consul server statefulset (or both) will be redeployed. -If either is being redeployed, we will follow the same pattern for upgrades as -on other platforms: the servers will be redeployed one-by-one, and then the -clients will be redeployed in batches. Read [Upgrading Consul](/docs/upgrading) and then continue -reading below. + If either is being redeployed, we will follow the same pattern for upgrades as + on other platforms: the servers will be redeployed one-by-one, and then the + clients will be redeployed in batches. Read [Upgrading Consul](/docs/upgrading) and then continue + reading below. -If neither the client daemonset nor the server statefulset is being redeployed, -then you can continue with the helm upgrade without any specific sequence to follow. + If neither the client daemonset nor the server statefulset is being redeployed, + then you can continue with the helm upgrade without any specific sequence to follow. ## Service Mesh @@ -249,37 +251,41 @@ To initiate the upgrade: By default there are 3 servers, so you would set this value to `3` 1. Set the `updateStrategy` for clients to `OnDelete` -```yaml -global: - image: 'consul:123.456' -server: - updatePartition: 3 -client: - updateStrategy: | - type: OnDelete -``` - -The `updatePartition` value controls how many instances of the server -cluster are updated. Only instances with an index _greater than_ the -`updatePartition` value are updated (zero-indexed). Therefore, by setting -it equal to replicas, none should update yet. - -The `updateStrategy` controls how Kubernetes rolls out changes to the client daemonset. -By setting it to `OnDelete`, no clients will be restarted until their pods are deleted. -Without this, they would be redeployed alongside the servers because their Docker -image versions have changed. This is not desirable because we want the Consul -servers to be upgraded _before_ the clients. + + + ```yaml + global: + image: 'consul:123.456' + server: + updatePartition: 3 + client: + updateStrategy: | + type: OnDelete + ``` + + + + The `updatePartition` value controls how many instances of the server + cluster are updated. Only instances with an index _greater than_ the + `updatePartition` value are updated (zero-indexed). Therefore, by setting + it equal to replicas, none should update yet. + + The `updateStrategy` controls how Kubernetes rolls out changes to the client daemonset. + By setting it to `OnDelete`, no clients will be restarted until their pods are deleted. + Without this, they would be redeployed alongside the servers because their Docker + image versions have changed. This is not desirable because we want the Consul + servers to be upgraded _before_ the clients. 1. Next, perform the upgrade: -```shell-session -$ helm upgrade consul hashicorp/consul --version --values /path/to/your/values.yaml -``` + ```shell-session + $ helm upgrade consul hashicorp/consul --namespace consul --version --values /path/to/your/values.yaml + ``` -This will not cause the servers to redeploy (although the resource will be updated). If -everything is stable, begin by decreasing the `updatePartition` value by one, -and performing `helm upgrade` again. This will cause the first Consul server -to be stopped and restarted with the new image. + This will not cause the servers to redeploy (although the resource will be updated). If + everything is stable, begin by decreasing the `updatePartition` value by one, + and performing `helm upgrade` again. This will cause the first Consul server + to be stopped and restarted with the new image. 1. Wait until the Consul server cluster is healthy again (30s to a few minutes). This can be confirmed by issuing `consul members` on one of the previous servers, @@ -298,20 +304,20 @@ restarting the clients as outlined in [Service Mesh](#service-mesh). You can either: 1. Manually issue `kubectl delete pod ` for each consul daemonset pod -2. Set the updateStrategy to rolling update with a small number: +1. Set the updateStrategy to rolling update with a small number: -```yaml -client: - updateStrategy: | - rollingUpdate: - maxUnavailable: 2 - type: RollingUpdate -``` + ```yaml + client: + updateStrategy: | + rollingUpdate: + maxUnavailable: 2 + type: RollingUpdate + ``` -Then, run `helm upgrade`. This will upgrade the clients in batches, waiting -until the clients come up healthy before continuing. + Then, run `helm upgrade`. This will upgrade the clients in batches, waiting + until the clients come up healthy before continuing. -3. Cordon and drain each node to ensure there are no connect pods active on it, and then delete the +1. Cordon and drain each node to ensure there are no connect pods active on it, and then delete the consul client pod on that node. -> NOTE: If you are using only the Service Sync functionality, you can perform an upgrade without From d2051835768be548ec37f8c4bf0c6c898aa5c3a5 Mon Sep 17 00:00:00 2001 From: Jared Kirschner Date: Mon, 31 Jan 2022 09:54:11 -0800 Subject: [PATCH 62/78] Improve README header Improvements include: - separate the project name from the badges - use the project logo - show more relevant badges --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 155f504952..695b0707fd 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,20 @@ -# Consul [![CircleCI](https://circleci.com/gh/hashicorp/consul/tree/main.svg?style=svg)](https://circleci.com/gh/hashicorp/consul/tree/main) [![Discuss](https://img.shields.io/badge/discuss-consul-ca2171.svg?style=flat)](https://discuss.hashicorp.com/c/consul) +# Consul + +

+ + HashiCorp Consul logo + +

+ +[![Docker Pulls](https://img.shields.io/docker/pulls/_/consul.svg)](https://hub.docker.com/_/consul) +[![Go Report Card](https://goreportcard.com/badge/github.com/hashicorp/consul)](https://goreportcard.com/report/github.com/hashicorp/consul) + +Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure. * Website: https://www.consul.io * Tutorials: [HashiCorp Learn](https://learn.hashicorp.com/consul) * Forum: [Discuss](https://discuss.hashicorp.com/c/consul) -Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure. - Consul provides several key features: * **Multi-Datacenter** - Consul is built to be datacenter aware, and can From 81461565d7565a3e6b5a1ab1c1e7d04d5b3d2a19 Mon Sep 17 00:00:00 2001 From: David Yu Date: Thu, 3 Feb 2022 10:40:06 -0800 Subject: [PATCH 63/78] docs: provide example for enabling mesh on a per namespace basis (#12255) * docs: provide example for enabling mesh on a per namespace basis * add headings * Update install.mdx * Update install.mdx * Update website/content/docs/k8s/installation/install.mdx Co-authored-by: Blake Covarrubias * Update install.mdx * Update website/content/docs/k8s/installation/install.mdx Co-authored-by: Blake Covarrubias * Update website/content/docs/k8s/installation/install.mdx Co-authored-by: Iryna Shustava * add changes from review * Update install.mdx Co-authored-by: Blake Covarrubias Co-authored-by: Iryna Shustava --- .../content/docs/k8s/installation/install.mdx | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/website/content/docs/k8s/installation/install.mdx b/website/content/docs/k8s/installation/install.mdx index 1d166c2921..e128ccef04 100644 --- a/website/content/docs/k8s/installation/install.mdx +++ b/website/content/docs/k8s/installation/install.mdx @@ -76,7 +76,7 @@ The [Homebrew](https://brew.sh) package manager is required to complete the foll ✓ Consul installed into namespace "consul" ``` -1. (Optional) Run `consul-k8s status` command to quickly glance at the status of the installed Consul cluster. +1. (Optional) Issue the `consul-k8s status` command to quickly glance at the status of the installed Consul cluster. ```shell-session $ consul-k8s status @@ -175,8 +175,9 @@ create a `config.yaml` file to override the default settings. You can learn what settings are available by running `helm inspect values hashicorp/consul` or by reading the [Helm Chart Reference](/docs/k8s/helm). -For example, if you want to enable the [Consul Connect](/docs/k8s/connect) feature, -use the following config file: +#### Minimal `config.yaml` for Consul Service Mesh + +The minimal settings to enable [Consul Service Mesh]((/docs/k8s/connect)) would be captured in the following `config.yaml` config file: @@ -199,6 +200,44 @@ NAME: consul ... ``` +#### Enable Consul Service Mesh on select namespaces + +By default, Consul Service Mesh is enabled on almost all namespaces (with the exception of `kube-system` and `local-path-storage`) within a Kubernetes cluster. You can restrict this to a subset of namespaces by specifying a `namespaceSelector` that matches a label attached to each namespace denoting whether to enable Consul service mesh. In order to default to enabling service mesh on select namespaces by label, the `connectInject.default` value must be set to `true`. + + + +```yaml +global: + name: consul +connectInject: + enabled: true + default: true + namespaceSelector: | + matchLabels: + connect-inject : enabled +controller: + enabled: true +``` + + + +Label the namespace(s), where you would like to enable Consul Service Mesh. + +```shell-session +$ kubectl create ns foo +$ kubectl label namespace foo connect-inject=enabled +``` + +Next, run `helm install` with the `--values` flag: + +```shell-session +$ helm install consul hashicorp/consul --create-namespace --namespace consul --values config.yaml +NAME: consul +... +``` + +#### Updating your Consul on Kubernetes configuration + If you've already installed Consul and want to make changes, you'll need to run `helm upgrade`. See [Upgrading](/docs/k8s/upgrade) for more details. From 4500622004be234cf6dd3032f562f54bc0545381 Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Thu, 3 Feb 2022 14:00:06 -0700 Subject: [PATCH 64/78] Apply suggestions from code review Co-authored-by: trujillo-adam <47586768+trujillo-adam@users.noreply.github.com> --- .../docs/intro/usecases/what-is-a-service-mesh.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index a3e5dfd1dd..b65f6f1ba6 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -45,18 +45,18 @@ Many service mesh solutions employ a sidecar proxy to handle data plane communic An API gateway is a centralized access point for handling incoming client requests and delivering them to services. The API Gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. -The API Gateway will route the incoming requests to the respective service. API Gateways primary function is to handle requests and return the reply from the service back to the client. +The API gateway will route the incoming requests to the respective service. The primary function of an API gateway is to handle requests and return the reply from the service back to the client. A service mesh specializes in the network management of services and the communication between services. -The mesh is responsible for keeping track of services and their health status, IP address, traffic routing, and ensuring all the traffic between services are authenticated and encrypted. -Unlike API Gateways, a service mesh will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. -API Gateways are frequently deployed alongside a load balancer to ensure traffic is directed to healthy and available instances of the service. +The mesh is responsible for keeping track of services and their health status, IP address, and traffic routing and ensuring all traffic between services is authenticated and encrypted. +Unlike API gateways, a service mesh will track all registered services' lifecycle and ensure requests are routed to healthy instances of the service. +API gateways are frequently deployed alongside a load balancer to ensure traffic is directed to healthy and available instances of the service. The mesh reduces the load balancer footprint as routing responsibilities are handled in a decentralized manner. -API Gateways can be used together with a service mesh to bridge external networks (non-mesh) with a service mesh. +API gateways can be used with a service mesh to bridge external networks (non-mesh) with a service mesh. --> **Note**: API Gateways are frequently used to accept north-south based traffic. North-south traffic is networking traffic that either enters or exits a data center or a virtual private network (VPC). -A service mesh is primarily used for handling east-west based traffic. East-west traffic traditionally remains inside a data center or a VPC. +-> **API gateways and traffic direction**: API gateways are often used to accept north-south traffic. North-south traffic is networking traffic that either enters or exits a data center or a virtual private network (VPC). +A service mesh is primarily used for handling east-west traffic. East-west traffic traditionally remains inside a data center or a VPC. A service mesh can be connected to another service mesh in another data center or VPC to form a federated mesh. ## What Problems Does a Service Mesh Solve? From 8aecfa877a6fd261513c058668fd52cdc7c41472 Mon Sep 17 00:00:00 2001 From: mrspanishviking Date: Thu, 3 Feb 2022 14:06:41 -0700 Subject: [PATCH 65/78] Apply suggestions from code review Co-authored-by: trujillo-adam <47586768+trujillo-adam@users.noreply.github.com> --- .../content/docs/intro/usecases/what-is-a-service-mesh.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index b65f6f1ba6..8b499b6b61 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -31,7 +31,7 @@ In a _zero trust_ model, applications require identity-based access to ensure al ## How does a Service Mesh work? -A service mesh typically consist of a control plane, and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses, this is called [service discovery](https://www.hashicorp.com/products/consul/service-discovery-and-health-checking). +A service mesh typically consist of a control plane and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses. This activity is called [service discovery](https://www.hashicorp.com/products/consul/service-discovery-and-health-checking). As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. The control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. @@ -44,7 +44,7 @@ Many service mesh solutions employ a sidecar proxy to handle data plane communic ## API Gateway vs Service Mesh An API gateway is a centralized access point for handling incoming client requests and delivering them to services. -The API Gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. +The API gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. The API gateway will route the incoming requests to the respective service. The primary function of an API gateway is to handle requests and return the reply from the service back to the client. A service mesh specializes in the network management of services and the communication between services. From ecc5dae06ff99f58ed200604dba33f097a09562c Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Thu, 3 Feb 2022 14:03:21 -0800 Subject: [PATCH 66/78] docs: update for k8s support for igw and header manip (#12264) Add docs now that k8s supports these new config entry fields --- .../config-entries/ingress-gateway.mdx | 49 +++++++++++-------- .../connect/config-entries/service-router.mdx | 24 +++------ .../config-entries/service-splitter.mdx | 36 ++++++++++---- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/website/content/docs/connect/config-entries/ingress-gateway.mdx b/website/content/docs/connect/config-entries/ingress-gateway.mdx index cc3f1014e5..918177e4c4 100644 --- a/website/content/docs/connect/config-entries/ingress-gateway.mdx +++ b/website/content/docs/connect/config-entries/ingress-gateway.mdx @@ -600,7 +600,12 @@ spec: protocol: http services: - name: api - # HTTP Header manipulation is not supported in Kubernetes CRD + requestHeaders: + add: + x-gateway: us-east-ingress + responseHeaders: + remove: + - x-debug ``` ```json @@ -676,7 +681,12 @@ spec: services: - name: api namespace: frontend - # HTTP Header manipulation is not supported in Kubernetes CRD + requestHeaders: + add: + x-gateway: us-east-ingress + responseHeaders: + remove: + - x-debug ``` ```json @@ -981,21 +991,25 @@ You can specify the following parameters to configure ingress gateway configurat }, { name: 'TLSMinVersion', + yaml: false, type: 'string: ""', - description: "Set the default minimum TLS version supported for the gateway's listeners. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.", + description: + "Set the default minimum TLS version supported for the gateway's listeners. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.", }, { name: 'TLSMaxVersion', + yaml: false, type: 'string: ""', description: { hcl: - "Set the default maximum TLS version supported for the gateway's listeners. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`." , + "Set the default maximum TLS version supported for the gateway's listeners. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`.", yaml: - "Set the default maximum TLS version supported for the gateway's listeners. Must be greater than or equal to `tls_min_version`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`." , + "Set the default maximum TLS version supported for the gateway's listeners. Must be greater than or equal to `tls_min_version`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`.", }, }, { name: 'CipherSuites', + yaml: false, type: 'array: ', description: `Set the default list of TLS cipher suites for the gateway's listeners to support when negotiating connections using @@ -1007,11 +1021,10 @@ You can specify the following parameters to configure ingress gateway configurat releases of Envoy may remove currently-supported but insecure cipher suites, and future releases of Consul may add new supported cipher suites if any are added to - Envoy.` + Envoy.`, }, { name: 'SDS', - yaml: false, type: 'SDSConfig: ', description: 'Defines a set of parameters that configures the gateway to load TLS certificates from an external SDS service. See [SDS](/docs/connect/gateways/ingress-gateway#sds) for more details on usage.

SDS properties defined in this field are used as defaults for all listeners on the gateway.', @@ -1105,7 +1118,6 @@ You can specify the following parameters to configure ingress gateway configurat \`*-suffix.example.com\` are not.`, }, { - yaml: false, name: 'RequestHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) @@ -1113,7 +1125,6 @@ You can specify the following parameters to configure ingress gateway configurat This cannot be used with a \`tcp\` listener.`, }, { - yaml: false, name: 'ResponseHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) @@ -1122,7 +1133,6 @@ You can specify the following parameters to configure ingress gateway configurat }, { name: 'TLS', - yaml: false, type: 'ServiceTLSConfig: ', description: 'TLS configuration for this service.', children: [ @@ -1154,7 +1164,6 @@ You can specify the following parameters to configure ingress gateway configurat }, { name: 'TLS', - yaml: false, type: 'TLSConfig: ', description: 'TLS configuration for this listener.', children: [ @@ -1165,26 +1174,26 @@ You can specify the following parameters to configure ingress gateway configurat hcl: "Set this configuration to `true` to enable built-in TLS for this listener.

If TLS is enabled, then each host defined in each service's `Hosts` field will be added as a DNSSAN to the gateway's x509 certificate. Note that even hosts from other listeners with TLS disabled will be added. TLS can not be disabled for individual listeners if it is enabled on the gateway.", yaml: - "Set this configuration to `true` to enable built-in TLS for this listener.

If TLS is enabled, then each host defined in the `hosts` field will be added as a DNSSAN to the gateway's x509 certificate. Note that even hosts from other listeners with TLS disabled will be added. TLS can not be disabled for individual listeners if it is enabled on the gateway.", + "Set this configuration to `true` to enable built-in TLS for this listener.

If TLS is enabled, then each host defined in each service's `hosts` field will be added as a DNSSAN to the gateway's x509 certificate. Note that even hosts from other listeners with TLS disabled will be added. TLS can not be disabled for individual listeners if it is enabled on the gateway.", }, }, { name: 'TLSMinVersion', + yaml: false, type: 'string: ""', - description: "Set the minimum TLS version supported for this listener. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.", + description: + 'Set the minimum TLS version supported for this listener. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. If unspecified, Envoy v1.22.0 and newer [will default to TLS 1.2 as a min version](https://github.com/envoyproxy/envoy/pull/19330), while older releases of Envoy default to TLS 1.0.', }, { name: 'TLSMaxVersion', + yaml: false, type: 'string: ""', - description: { - hcl: - "Set the maximum TLS version supported for this listener. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`." , - yaml: - "Set the maximum TLS version supported for this listener. Must be greater than or equal to `tls_min_version`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`." , - }, + description: + 'Set the maximum TLS version supported for this listener. Must be greater than or equal to `TLSMinVersion`. One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`.', }, { name: 'CipherSuites', + yaml: false, type: 'array: ', description: `Set the list of TLS cipher suites to support when negotiating connections using TLS 1.2 or earlier. If unspecified, @@ -1195,7 +1204,7 @@ You can specify the following parameters to configure ingress gateway configurat and is dependent on underlying support in Envoy. Future releases of Envoy may remove currently-supported but insecure cipher suites, and future releases of Consul - may add new supported cipher suites if any are added to Envoy.` + may add new supported cipher suites if any are added to Envoy.`, }, { name: 'SDS', diff --git a/website/content/docs/connect/config-entries/service-router.mdx b/website/content/docs/connect/config-entries/service-router.mdx index 5814173045..6a7ba3373e 100644 --- a/website/content/docs/connect/config-entries/service-router.mdx +++ b/website/content/docs/connect/config-entries/service-router.mdx @@ -36,10 +36,9 @@ service of the same name. to any configured [`service-resolver`](/docs/connect/config-entries/service-resolver). -## UI +## UI - -Once a `service-router` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the *routing* tab. +Once a `service-router` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the _routing_ tab. ![screenshot of service router in the UI](/img/l7-routing/Router.png) @@ -309,14 +308,16 @@ spec: name: 'Namespace', type: `string: "default"`, enterprise: true, - description: 'Specifies the namespace to which the configuration entry will apply.', + description: + 'Specifies the namespace to which the configuration entry will apply.', yaml: false, }, { name: 'Partition', type: `string: "default"`, enterprise: true, - description: 'Specifies the admin partition to which the configuration will apply.', + description: + 'Specifies the admin partition to which the configuration will apply.', yaml: false, }, { @@ -596,7 +597,6 @@ spec: 'A list of HTTP response status codes that are eligible for retry.', }, { - yaml: false, name: 'RequestHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) @@ -604,7 +604,6 @@ spec: This cannot be used with a \`tcp\` listener.`, }, { - yaml: false, name: 'ResponseHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) @@ -614,21 +613,12 @@ spec: ]} /> - ### `HTTPHeaderModifiers` : optional', description: `The set of key/value pairs that specify header values to add. @@ -641,7 +631,6 @@ spec: metadata into the value added.`, }, { - yaml: false, name: 'Set', type: 'map: optional', description: `The set of key/value pairs that specify header values to add. @@ -654,7 +643,6 @@ spec: metadata into the value added.`, }, { - yaml: false, name: 'Remove', type: 'array: optional', description: `The set of header names to remove. Only headers diff --git a/website/content/docs/connect/config-entries/service-splitter.mdx b/website/content/docs/connect/config-entries/service-splitter.mdx index cf279dbf2c..bc5d709ce5 100644 --- a/website/content/docs/connect/config-entries/service-splitter.mdx +++ b/website/content/docs/connect/config-entries/service-splitter.mdx @@ -39,9 +39,9 @@ resolution stage. to any configured [`service-resolver`](/docs/connect/config-entries/service-resolver). -## UI +## UI -Once a `service-splitter` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the *routing* tab. +Once a `service-splitter` is successfully entered, you can view it in the UI. Service routers, service splitters, and service resolvers can all be viewed by clicking on your service then switching to the _routing_ tab. ![screenshot of service splitter in the UI](/img/l7-routing/Splitter.png) @@ -152,13 +152,12 @@ spec: - ### Set HTTP Headers Split traffic between two subsets with extra headers added so clients can tell -which version (not yet supported in Kubernetes CRD): +which version: - + ```hcl Kind = "service-splitter" @@ -185,6 +184,25 @@ Splits = [ ] ``` +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceSplitter +metadata: + name: web +spec: + splits: + - weight: 90 + serviceSubset: v1 + responseHeaders: + set: + x-web-version: v1 + - weight: 10 + serviceSubset: v2 + responseHeaders: + set: + x-web-version: v2 +``` + ```json { "Kind": "service-splitter", @@ -240,14 +258,16 @@ Splits = [ name: 'Namespace', type: `string: "default"`, enterprise: true, - description: 'Specifies the namespace to which the configuration entry will apply.', + description: + 'Specifies the namespace to which the configuration entry will apply.', yaml: false, }, { name: 'Partition', type: `string: "default"`, enterprise: true, - description: 'Specifies the admin partition to which the configuration entry will apply.', + description: + 'Specifies the admin partition to which the configuration entry will apply.', yaml: false, }, { @@ -314,7 +334,6 @@ Splits = [ 'The admin partition to resolve the service from instead of the current partition. If empty, the current partition is used.', }, { - yaml: false, name: 'RequestHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) @@ -322,7 +341,6 @@ Splits = [ This cannot be used with a \`tcp\` listener.`, }, { - yaml: false, name: 'ResponseHeaders', type: 'HTTPHeaderModifiers: ', description: `A set of [HTTP-specific header modification rules](/docs/connect/config-entries/service-router#httpheadermodifiers) From d707173253b995e616d4d98aeae2cd1041d737b0 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 3 Feb 2022 14:03:32 -0500 Subject: [PATCH 67/78] ca: small cleanup of TestConnectCAConfig_Vault_TriggerRotation_Fails Before adding more test cases --- agent/consul/connect_ca_endpoint_test.go | 33 ++++++------------------ 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/agent/consul/connect_ca_endpoint_test.go b/agent/consul/connect_ca_endpoint_test.go index d170729db4..eba3f73239 100644 --- a/agent/consul/connect_ca_endpoint_test.go +++ b/agent/consul/connect_ca_endpoint_test.go @@ -558,11 +558,8 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { t.Parallel() testVault := ca.NewTestVaultServer(t) - defer testVault.Stop() _, s1 := testServerWithConfig(t, func(c *Config) { - c.Build = "1.6.0" - c.PrimaryDatacenter = "dc1" c.CAConfig = &structs.CAConfiguration{ Provider: "vault", Config: map[string]interface{}{ @@ -573,28 +570,16 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { }, } }) - defer s1.Shutdown() - - codec := rpcClient(t, s1) - defer codec.Close() - testrpc.WaitForTestAgent(t, s1.RPC, "dc1") - // Capture the current root. - { - rootList, _, err := getTestRoots(s1, "dc1") - require.NoError(t, err) - require.Len(t, rootList.Roots, 1) - } - cases := []struct { name string - configFn func() (*structs.CAConfiguration, error) + configFn func() *structs.CAConfiguration expectErr string }{ { name: "cannot edit key bits", - configFn: func() (*structs.CAConfiguration, error) { + configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ Provider: "vault", Config: map[string]interface{}{ @@ -607,13 +592,13 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { "PrivateKeyBits": 384, }, ForceWithoutCrossSigning: true, - }, nil + } }, expectErr: `error generating CA root certificate: cannot update the PrivateKeyBits field without choosing a new PKI mount for the root CA`, }, { name: "cannot edit key type", - configFn: func() (*structs.CAConfiguration, error) { + configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ Provider: "vault", Config: map[string]interface{}{ @@ -626,7 +611,7 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { "PrivateKeyBits": 4096, }, ForceWithoutCrossSigning: true, - }, nil + } }, expectErr: `error generating CA root certificate: cannot update the PrivateKeyType field without choosing a new PKI mount for the root CA`, }, @@ -634,16 +619,14 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - newConfig, err := tc.configFn() - require.NoError(t, err) - args := &structs.CARequest{ Datacenter: "dc1", - Config: newConfig, + Config: tc.configFn(), } var reply interface{} - err = msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", args, &reply) + codec := rpcClient(t, s1) + err := msgpackrpc.CallWithCodec(codec, "ConnectCA.ConfigurationSet", args, &reply) if tc.expectErr == "" { require.NoError(t, err) } else { From 608597c7b6efc971796ac793a13019174ae69890 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 3 Feb 2022 13:28:43 -0500 Subject: [PATCH 68/78] ca: relax and move private key type/bit validation for vault This commit makes two changes to the validation. Previously we would call this validation in GenerateRoot, which happens both on initialization (when a follower becomes leader), and when a configuration is updated. We only want to do this validation during config update so the logic was moved to the UpdateConfiguration function. Previously we would compare the config values against the actual cert. This caused problems when the cert was created manually in Vault (not created by Consul). Now we compare the new config against the previous config. Using a already created CA cert should never error now. Adding the key bit and types to the config should only error when the previous values were not the defaults. --- agent/connect/ca/provider_vault.go | 53 +++++++++++++----------- agent/consul/connect_ca_endpoint_test.go | 53 ++++++++++++++++++++---- agent/consul/leader_connect_ca.go | 24 ++++++++++- 3 files changed, 97 insertions(+), 33 deletions(-) diff --git a/agent/connect/ca/provider_vault.go b/agent/connect/ca/provider_vault.go index c7b99a13f3..9e107a2990 100644 --- a/agent/connect/ca/provider_vault.go +++ b/agent/connect/ca/provider_vault.go @@ -160,6 +160,34 @@ func (v *VaultProvider) Configure(cfg ProviderConfig) error { return nil } +func (v *VaultProvider) ValidateConfigUpdate(prevRaw, nextRaw map[string]interface{}) error { + prev, err := ParseVaultCAConfig(prevRaw) + if err != nil { + return err + } + next, err := ParseVaultCAConfig(nextRaw) + if err != nil { + return err + } + + if prev.RootPKIPath != next.RootPKIPath { + return nil + } + + if prev.PrivateKeyType != "" && prev.PrivateKeyType != connect.DefaultPrivateKeyType { + if prev.PrivateKeyType != next.PrivateKeyType { + return fmt.Errorf("cannot update the PrivateKeyType field without changing RootPKIPath") + } + } + + if prev.PrivateKeyBits != 0 && prev.PrivateKeyBits != connect.DefaultPrivateKeyBits { + if prev.PrivateKeyBits != next.PrivateKeyBits { + return fmt.Errorf("cannot update the PrivateKeyBits field without changing RootPKIPath") + } + } + return nil +} + // renewToken uses a vaultapi.LifetimeWatcher to repeatedly renew our token's lease. // If the token can no longer be renewed and auth method is set, // it will re-authenticate to Vault using the auth method and restart the renewer with the new token. @@ -272,31 +300,6 @@ func (v *VaultProvider) GenerateRoot() (RootResult, error) { if err != nil { return RootResult{}, err } - - if rootPEM != "" { - rootCert, err := connect.ParseCert(rootPEM) - if err != nil { - return RootResult{}, err - } - - // Vault PKI doesn't allow in-place cert/key regeneration. That - // means if you need to change either the key type or key bits then - // you also need to provide new mount points. - // https://www.vaultproject.io/api-docs/secret/pki#generate-root - // - // A separate bug in vault likely also requires that you use the - // ForceWithoutCrossSigning option when changing key types. - foundKeyType, foundKeyBits, err := connect.KeyInfoFromCert(rootCert) - if err != nil { - return RootResult{}, err - } - if v.config.PrivateKeyType != foundKeyType { - return RootResult{}, fmt.Errorf("cannot update the PrivateKeyType field without choosing a new PKI mount for the root CA") - } - if v.config.PrivateKeyBits != foundKeyBits { - return RootResult{}, fmt.Errorf("cannot update the PrivateKeyBits field without choosing a new PKI mount for the root CA") - } - } } return RootResult{PEM: rootPEM}, nil diff --git a/agent/consul/connect_ca_endpoint_test.go b/agent/consul/connect_ca_endpoint_test.go index eba3f73239..bb4d7188e1 100644 --- a/agent/consul/connect_ca_endpoint_test.go +++ b/agent/consul/connect_ca_endpoint_test.go @@ -572,13 +572,53 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { }) testrpc.WaitForTestAgent(t, s1.RPC, "dc1") - cases := []struct { + // note: unlikely many table tests, the ordering of these cases does matter + // because any non-errored case will modify the CA config, and any subsequent + // tests will use the same agent with that new CA config. + testSteps := []struct { name string configFn func() *structs.CAConfiguration expectErr string }{ { - name: "cannot edit key bits", + name: "allow modifying key type and bits from default", + configFn: func() *structs.CAConfiguration { + return &structs.CAConfiguration{ + Provider: "vault", + Config: map[string]interface{}{ + "Address": testVault.Addr, + "Token": testVault.RootToken, + "RootPKIPath": "pki-root/", + "IntermediatePKIPath": "pki-intermediate/", + // + "PrivateKeyType": "rsa", + "PrivateKeyBits": 4096, + }, + ForceWithoutCrossSigning: true, + } + }, + }, + { + name: "error when trying to modify key bits", + configFn: func() *structs.CAConfiguration { + return &structs.CAConfiguration{ + Provider: "vault", + Config: map[string]interface{}{ + "Address": testVault.Addr, + "Token": testVault.RootToken, + "RootPKIPath": "pki-root/", + "IntermediatePKIPath": "pki-intermediate/", + // + "PrivateKeyType": "rsa", + "PrivateKeyBits": 2048, + }, + ForceWithoutCrossSigning: true, + } + }, + expectErr: `cannot update the PrivateKeyBits field without changing RootPKIPath`, + }, + { + name: "error when trying to modify key type", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ Provider: "vault", @@ -589,15 +629,15 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { "IntermediatePKIPath": "pki-intermediate/", // "PrivateKeyType": "ec", - "PrivateKeyBits": 384, + "PrivateKeyBits": 256, }, ForceWithoutCrossSigning: true, } }, - expectErr: `error generating CA root certificate: cannot update the PrivateKeyBits field without choosing a new PKI mount for the root CA`, + expectErr: `cannot update the PrivateKeyType field without changing RootPKIPath`, }, { - name: "cannot edit key type", + name: "allow update that does not change key type or bits", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ Provider: "vault", @@ -613,11 +653,10 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { ForceWithoutCrossSigning: true, } }, - expectErr: `error generating CA root certificate: cannot update the PrivateKeyType field without choosing a new PKI mount for the root CA`, }, } - for _, tc := range cases { + for _, tc := range testSteps { t.Run(tc.name, func(t *testing.T) { args := &structs.CARequest{ Datacenter: "dc1", diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go index 5b795727fe..47b5bafcee 100644 --- a/agent/consul/leader_connect_ca.go +++ b/agent/consul/leader_connect_ca.go @@ -781,7 +781,7 @@ func (c *CAManager) UpdateConfiguration(args *structs.CARequest) (reterr error) }() // Attempt to initialize the config if we failed to do so in Initialize for some reason - _, err = c.initializeCAConfig() + prevConfig, err := c.initializeCAConfig() if err != nil { return err } @@ -832,6 +832,15 @@ func (c *CAManager) UpdateConfiguration(args *structs.CARequest) (reterr error) RawConfig: args.Config.Config, State: args.Config.State, } + + if args.Config.Provider == config.Provider { + if validator, ok := newProvider.(ValidateConfigUpdater); ok { + if err := validator.ValidateConfigUpdate(prevConfig.Config, args.Config.Config); err != nil { + return fmt.Errorf("new configuration is incompatible with previous configuration: %w", err) + } + } + } + if err := newProvider.Configure(pCfg); err != nil { return fmt.Errorf("error configuring provider: %v", err) } @@ -858,6 +867,19 @@ func (c *CAManager) UpdateConfiguration(args *structs.CARequest) (reterr error) return nil } +// ValidateConfigUpdater is an optional interface that may be implemented +// by a ca.Provider. If the provider implements this interface, the +// ValidateConfigurationUpdate will be called when a user attempts to change the +// CA configuration, and the provider type has not changed from the previous +// configuration. +type ValidateConfigUpdater interface { + // ValidateConfigUpdate should return an error if the next configuration is + // incompatible with the previous configuration. + // + // TODO: use better types after https://github.com/hashicorp/consul/issues/12238 + ValidateConfigUpdate(previous, next map[string]interface{}) error +} + func (c *CAManager) primaryUpdateRootCA(newProvider ca.Provider, args *structs.CARequest, config *structs.CAConfiguration) error { providerRoot, err := newProvider.GenerateRoot() if err != nil { From 81a977ce1df6b4b7f6f0345ae25dd098f5ba0963 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 3 Feb 2022 17:39:36 -0500 Subject: [PATCH 69/78] add changelog --- .changelog/12267.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/12267.txt diff --git a/.changelog/12267.txt b/.changelog/12267.txt new file mode 100644 index 0000000000..ca9106c0e2 --- /dev/null +++ b/.changelog/12267.txt @@ -0,0 +1,3 @@ +```release-note:bug +ca: adjust validation of PrivateKeyType/Bits with the Vault provider, to remove the error when the cert is created manually in Vault. +``` From 51b0f82d0e1541a5fcf5dcafb6736c16e26812ba Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 3 Feb 2022 18:44:09 -0500 Subject: [PATCH 70/78] Make test more readable And fix typo --- agent/connect/ca/provider_vault.go | 4 +- agent/consul/connect_ca_endpoint_test.go | 68 ++++++++---------------- 2 files changed, 23 insertions(+), 49 deletions(-) diff --git a/agent/connect/ca/provider_vault.go b/agent/connect/ca/provider_vault.go index 9e107a2990..d837fe1a85 100644 --- a/agent/connect/ca/provider_vault.go +++ b/agent/connect/ca/provider_vault.go @@ -163,11 +163,11 @@ func (v *VaultProvider) Configure(cfg ProviderConfig) error { func (v *VaultProvider) ValidateConfigUpdate(prevRaw, nextRaw map[string]interface{}) error { prev, err := ParseVaultCAConfig(prevRaw) if err != nil { - return err + return fmt.Errorf("failed to parse existing CA config: %w", err) } next, err := ParseVaultCAConfig(nextRaw) if err != nil { - return err + return fmt.Errorf("failed to parse new CA config: %w", err) } if prev.RootPKIPath != next.RootPKIPath { diff --git a/agent/consul/connect_ca_endpoint_test.go b/agent/consul/connect_ca_endpoint_test.go index bb4d7188e1..f32bf6ec1d 100644 --- a/agent/consul/connect_ca_endpoint_test.go +++ b/agent/consul/connect_ca_endpoint_test.go @@ -559,20 +559,26 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { testVault := ca.NewTestVaultServer(t) + newConfig := func(keyType string, keyBits int) map[string]interface{} { + return map[string]interface{}{ + "Address": testVault.Addr, + "Token": testVault.RootToken, + "RootPKIPath": "pki-root/", + "IntermediatePKIPath": "pki-intermediate/", + "PrivateKeyType": keyType, + "PrivateKeyBits": keyBits, + } + } + _, s1 := testServerWithConfig(t, func(c *Config) { c.CAConfig = &structs.CAConfiguration{ Provider: "vault", - Config: map[string]interface{}{ - "Address": testVault.Addr, - "Token": testVault.RootToken, - "RootPKIPath": "pki-root/", - "IntermediatePKIPath": "pki-intermediate/", - }, + Config: newConfig(connect.DefaultPrivateKeyType, connect.DefaultPrivateKeyBits), } }) testrpc.WaitForTestAgent(t, s1.RPC, "dc1") - // note: unlikely many table tests, the ordering of these cases does matter + // note: unlike many table tests, the ordering of these cases does matter // because any non-errored case will modify the CA config, and any subsequent // tests will use the same agent with that new CA config. testSteps := []struct { @@ -584,16 +590,8 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { name: "allow modifying key type and bits from default", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ - Provider: "vault", - Config: map[string]interface{}{ - "Address": testVault.Addr, - "Token": testVault.RootToken, - "RootPKIPath": "pki-root/", - "IntermediatePKIPath": "pki-intermediate/", - // - "PrivateKeyType": "rsa", - "PrivateKeyBits": 4096, - }, + Provider: "vault", + Config: newConfig("rsa", 4096), ForceWithoutCrossSigning: true, } }, @@ -602,16 +600,8 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { name: "error when trying to modify key bits", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ - Provider: "vault", - Config: map[string]interface{}{ - "Address": testVault.Addr, - "Token": testVault.RootToken, - "RootPKIPath": "pki-root/", - "IntermediatePKIPath": "pki-intermediate/", - // - "PrivateKeyType": "rsa", - "PrivateKeyBits": 2048, - }, + Provider: "vault", + Config: newConfig("rsa", 2048), ForceWithoutCrossSigning: true, } }, @@ -621,16 +611,8 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { name: "error when trying to modify key type", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ - Provider: "vault", - Config: map[string]interface{}{ - "Address": testVault.Addr, - "Token": testVault.RootToken, - "RootPKIPath": "pki-root/", - "IntermediatePKIPath": "pki-intermediate/", - // - "PrivateKeyType": "ec", - "PrivateKeyBits": 256, - }, + Provider: "vault", + Config: newConfig("ec", 256), ForceWithoutCrossSigning: true, } }, @@ -640,16 +622,8 @@ func TestConnectCAConfig_Vault_TriggerRotation_Fails(t *testing.T) { name: "allow update that does not change key type or bits", configFn: func() *structs.CAConfiguration { return &structs.CAConfiguration{ - Provider: "vault", - Config: map[string]interface{}{ - "Address": testVault.Addr, - "Token": testVault.RootToken, - "RootPKIPath": "pki-root/", - "IntermediatePKIPath": "pki-intermediate/", - // - "PrivateKeyType": "rsa", - "PrivateKeyBits": 4096, - }, + Provider: "vault", + Config: newConfig("rsa", 4096), ForceWithoutCrossSigning: true, } }, From b0ac7a2b1d3be6ced13796e76e378166e8c104dd Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Thu, 3 Feb 2022 18:07:05 -0700 Subject: [PATCH 71/78] adding more content per feedback --- .../docs/intro/usecases/what-is-a-service-mesh.mdx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 8b499b6b61..8f104e0a65 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -27,7 +27,12 @@ Some of the benefits of a service mesh include; - network automation A common use case for leveraging a service mesh is to achieve a [_zero trust_ model](/use-cases/zero-trust-networking). -In a _zero trust_ model, applications require identity-based access to ensure all communication within the service mesh is authenticated with TLS certificates and encrypted in transit. +In a zero trust model, applications require identity-based access to ensure all communication within the service mesh is authenticated with TLS certificates and encrypted in transit. + +In traditional security strategies, protection is primarily focused at the perimeter of a network. +In cloud environments, the surface area for network access is much wider than the traditional on-premises networks. +In addition, traditional security practices overlook the fact that many bad actors can originate from within the network walls. +A zero trust model addresses these concerns while allowing organizations to scale as needed. ## How does a Service Mesh work? @@ -64,7 +69,7 @@ A service mesh can be connected to another service mesh in another data center o Modern infrastructure is transitioning from being primarily static to dynamic in nature (ephemeral). This dynamic infrastructure has a short life cycle, meaning virtual machines (VM) and containers are frequently recycled. It's difficult for an organization to manage and keep track of application services that live on short-lived resources. A service mesh solves this problem by acting as a central registry of all registered services. -As service instances, either VMs or containers, come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a service mesh solves. +As instances of a service (e.g., VM, container, serverless functions) come up and down, the mesh is aware of their state and availability. The ability to conduct _service discovery_ is the foundation to the other problems a service mesh solves. As a service mesh is aware of the state of a service and its instances, the mesh can implement more intelligent and dynamic network routing. Many service meshes offer L7 traffic management capabilities. As a result, operators and developers can create powerful rules to direct network traffic as needed, such as load balancing, traffic splitting, dynamic failover, and custom resolvers. From be999934c7560d8885c107456b88d58d486e32ce Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 4 Feb 2022 08:01:20 -0700 Subject: [PATCH 72/78] updated several sections based on feedback --- .../docs/intro/usecases/what-is-a-service-mesh.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index 8f104e0a65..e59597d027 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -95,13 +95,15 @@ Non-Kubernetes based service meshes can be installed through infrastructure as c ## What is a Multi Platform Service Mesh? -A multi-platform service mesh is capable of supporting various infrastructure environments. This can range from having the service mesh support Kubernetes and non-Kubernetes workloads, to having a service mesh span across various cloud environments (multi-cloud). +A multi-platform service mesh is capable of supporting various infrastructure environments. +This can range from having the service mesh support Kubernetes and non-Kubernetes workloads, to having a service mesh span across various cloud environments (multi-cloud and hybrid cloud). ## What is Consul? -Consul is a multi-networking tool that offers a fully-featured service mesh solution that solves the networking and security challenges of operating microservices and cloud infrastructure. +Consul is a multi-networking tool that offers a fully-featured service mesh solution that solves the networking and security challenges of operating microservices and cloud infrastructure (multi-cloud and hybrid cloud). Consul offers a software-driven approach to routing and segmentation. It also brings additional benefits such as failure handling, retries, and network observability. -Each of these features can be used individually as needed or they can be used together to build a full service mesh and achieve [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) security. In simple terms, Consul is the control plane of the service mesh. +Each of these features can be used individually as needed or they can be used together to build a full service mesh and achieve [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) security. +In simple terms, Consul is the control plane of the service mesh. The data plane is supported by Consul through its first class support of [Envoy](https://www.envoyproxy.io/) as a proxy. You can use Consul with virtual machines (VMs), containers, or with container orchestration platforms, such as [Nomad](https://www.nomadproject.io/) and Kubernetes. Consul is platform agnostic which makes it a great fit for all environments, including legacy platforms. From b62c3b4fbc6a4b77a79ad706ef12c7157b432bbb Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 4 Feb 2022 10:22:37 -0500 Subject: [PATCH 73/78] updating the binary and container blocks in security-scan file --- .release/security-scan.hcl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 3fd4ef388e..6a2a57b8b8 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -1,13 +1,19 @@ container { dependencies = true alpine_secdb = true - secrets = true + + secrets { + all = true + } } binary { - secrets = true go_modules = true osv = true oss_index = true nvd = true + + secrets { + all = true + } } From a820445fbc5c6d19650c0b5994183f88d9dfbaf0 Mon Sep 17 00:00:00 2001 From: Karl Cardenas Date: Fri, 4 Feb 2022 09:00:59 -0700 Subject: [PATCH 74/78] updated all sub-headers to sentence case --- .../docs/intro/usecases/what-is-a-service-mesh.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx index e59597d027..a999bd3fe0 100644 --- a/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx +++ b/website/content/docs/intro/usecases/what-is-a-service-mesh.mdx @@ -11,7 +11,7 @@ description: >- A _service mesh_ is a dedicated network layer that provides secure service-to-service communication within and across infrastructure, including on-premises and cloud environments. Service meshes are often used with a microservice architectural pattern, but can provide value in any scenario where complex networking is involved. -## Benefits of a Service Mesh +## Benefits of a service mesh A service mesh provides benefits for all organizations, ranging from security to improved application resiliency. Some of the benefits of a service mesh include; @@ -34,7 +34,7 @@ In cloud environments, the surface area for network access is much wider than th In addition, traditional security practices overlook the fact that many bad actors can originate from within the network walls. A zero trust model addresses these concerns while allowing organizations to scale as needed. -## How does a Service Mesh work? +## How does a service mesh work? A service mesh typically consist of a control plane and a data plane. The control plane maintains a central registry that keeps track of all services and their respective IP addresses. This activity is called [service discovery](https://www.hashicorp.com/products/consul/service-discovery-and-health-checking). As long as the application is registered with the control plane, the control plane will be able to share with other members of the mesh how to communicate with the application and enforce rules for who can communicate with each other. @@ -46,7 +46,7 @@ Many service mesh solutions employ a sidecar proxy to handle data plane communic ![Overview of a service mesh](/img/what_is_service_mesh_1.png) -## API Gateway vs Service Mesh +## API gateway vs service mesh An API gateway is a centralized access point for handling incoming client requests and delivering them to services. The API gateway acts as a control plane that allows operators and developers to manage incoming client requests and apply different handling logic depending on the request. @@ -64,7 +64,7 @@ API gateways can be used with a service mesh to bridge external networks (non-me A service mesh is primarily used for handling east-west traffic. East-west traffic traditionally remains inside a data center or a VPC. A service mesh can be connected to another service mesh in another data center or VPC to form a federated mesh. -## What Problems Does a Service Mesh Solve? +## What problems does a service mesh solve? Modern infrastructure is transitioning from being primarily static to dynamic in nature (ephemeral). This dynamic infrastructure has a short life cycle, meaning virtual machines (VM) and containers are frequently recycled. @@ -87,13 +87,13 @@ As a result, network administrators have to open up network ranges to permit net An operator defines a policy that only allows _service A_ to communicate with _service B_. Otherwise, the default action is to deny the traffic. This shift from an IP address-based security model to a service-focused model reduces the overhead of securing network traffic and allows an organization to take advantage of multi-cloud environments without sacrificing security due to complexity. -## How Do You Implement a Service Mesh? +## How do you implement a service mesh? Service meshes are commonly installed in Kubernetes clusters. There are also platform-agnostic service meshes available for non-Kubernetes-based workloads. For Kubernetes, most service meshes can be installed by operators through a [Helm chart](https://helm.sh/). Additionally, the service mesh may offer a CLI tool that supports the installation and maintenance of the service mesh. Non-Kubernetes based service meshes can be installed through infrastructure as code (IaC) products such as [Terraform](https://www.terraform.io/), CloudFormation, ARM Templates, Puppet, Chef, etc. -## What is a Multi Platform Service Mesh? +## What is a multi platform service mesh? A multi-platform service mesh is capable of supporting various infrastructure environments. This can range from having the service mesh support Kubernetes and non-Kubernetes workloads, to having a service mesh span across various cloud environments (multi-cloud and hybrid cloud). From bad0a6bfe35672e5d929242109038ad4bc86f54e Mon Sep 17 00:00:00 2001 From: David Yu Date: Fri, 4 Feb 2022 09:23:55 -0800 Subject: [PATCH 75/78] docs: mention Consul API gateway in Ingress Controllers page (#12268) * docs: mention Consul API gateway * Remove Ambassador integration * Update ingress-controllers.mdx * Update website/content/docs/k8s/connect/ingress-controllers.mdx Co-authored-by: mrspanishviking Co-authored-by: mrspanishviking --- website/content/docs/k8s/connect/ingress-controllers.mdx | 4 +++- website/data/docs-nav-data.json | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/website/content/docs/k8s/connect/ingress-controllers.mdx b/website/content/docs/k8s/connect/ingress-controllers.mdx index e8e4c06d18..b814d12415 100644 --- a/website/content/docs/k8s/connect/ingress-controllers.mdx +++ b/website/content/docs/k8s/connect/ingress-controllers.mdx @@ -12,7 +12,9 @@ description: Configuring Ingress Controllers With Consul On Kubernetes [Transparent Proxy](/docs/connect/transparent-proxy) mode enabled. This page describes a general approach for integrating Ingress Controllers with Consul on Kubernetes to secure traffic from the Controller -to the backend services. This allows Consul to transparently secure traffic from the ingress point through the entire traffic flow of the service. +to the backend services by deploying sidecars along with your Ingress Controller. This allows Consul to transparently secure traffic from the ingress point through the entire traffic flow of the service. + +If you are looking for a fully supported solution for ingress traffic into Consul Service Mesh, please visit [Consul API Gateway](https://www.consul.io/docs/api-gateway) for instruction on how to install Consul API Gateway along with Consul on Kubernetes. A few steps are generally required to enable an Ingress controller to join the mesh and pass traffic through to a service: diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index b91baacd5b..1acb4ffb06 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -521,10 +521,6 @@ "title": "Configuring a Connect CA Provider", "path": "k8s/connect/connect-ca-provider" }, - { - "title": "Ambassador Edge Stack Integration", - "href": "https://learn.hashicorp.com/tutorials/consul/load-balancing-ambassador" - }, { "title": "Health Checks", "path": "k8s/connect/health" From 20e4f7364928fad1e5ffcef7550c4a37f3290132 Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 4 Feb 2022 14:05:28 -0500 Subject: [PATCH 76/78] reverting changes for the container + binary blocks --- .github/workflows/build.yml | 3 ++- .release/ci.hcl | 6 +----- .release/security-scan.hcl | 10 ++-------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6069e1058..9fab5e0045 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,8 @@ on: # Sequence of patterns matched against refs/heads branches: # Push events on the main branch - - main + # - main + - 'fix-security-scan' env: PKG_NAME: consul diff --git a/.release/ci.hcl b/.release/ci.hcl index bf4a2144f3..fbd912ba47 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -10,11 +10,7 @@ project "consul" { organization = "hashicorp" repository = "consul" release_branches = [ - "main", - "release/1.8.x", - "release/1.9.x", - "release/1.10.x", - "release/1.11.x" + "fix-security-scan" ] } } diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 6a2a57b8b8..a3d2c7cbc4 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -1,19 +1,13 @@ container { + secrets = true dependencies = true alpine_secdb = true - - secrets { - all = true - } } binary { + secrets = true go_modules = true osv = true oss_index = true nvd = true - - secrets { - all = true - } } From 092a27e84dabfe83e541e3251c2cdf4bf94c579f Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 4 Feb 2022 14:22:25 -0500 Subject: [PATCH 77/78] turning go modules to false due to jwt issue --- .release/security-scan.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index a3d2c7cbc4..33ee8cda72 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -6,7 +6,7 @@ container { binary { secrets = true - go_modules = true + go_modules = false osv = true oss_index = true nvd = true From 12fc63d11c1e6a42b33ee149de12cf734ef9b7eb Mon Sep 17 00:00:00 2001 From: Claire Labry Date: Fri, 4 Feb 2022 14:59:30 -0500 Subject: [PATCH 78/78] clean up from testing --- .github/workflows/build.yml | 3 +-- .release/ci.hcl | 6 +++++- .release/security-scan.hcl | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9fab5e0045..a6069e1058 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,8 +5,7 @@ on: # Sequence of patterns matched against refs/heads branches: # Push events on the main branch - # - main - - 'fix-security-scan' + - main env: PKG_NAME: consul diff --git a/.release/ci.hcl b/.release/ci.hcl index fbd912ba47..bf4a2144f3 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -10,7 +10,11 @@ project "consul" { organization = "hashicorp" repository = "consul" release_branches = [ - "fix-security-scan" + "main", + "release/1.8.x", + "release/1.9.x", + "release/1.10.x", + "release/1.11.x" ] } } diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 33ee8cda72..eeb188891c 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -1,11 +1,11 @@ container { - secrets = true dependencies = true alpine_secdb = true + secrets = true } binary { - secrets = true + secrets = true go_modules = false osv = true oss_index = true