Merge branch 'main' into eculver/envoy-1.19.1

This commit is contained in:
Evan Culver 2021-09-28 15:58:20 -07:00
commit 9b73e7319d
No known key found for this signature in database
GPG Key ID: 3BBE9838C95315C7
69 changed files with 16056 additions and 414 deletions

3
.changelog/10914.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
ui: hide create button for policies/roles/namespace if users token has no write permissions to those areas
```

4
.changelog/11129.txt Normal file
View File

@ -0,0 +1,4 @@
```release-note:improvement
ui: Add initial support for partitions to intentions
```

4
.changelog/11130.txt Normal file
View File

@ -0,0 +1,4 @@
```release-note:improvement
ui: Removed informational panel from the namespace selector menu when editing
namespaces
```

3
.changelog/11149.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
ui: Don't show a CRD warning for read-only intentions
```

View File

@ -47,6 +47,34 @@ manage licenses on older servers [[GH-10952](https://github.com/hashicorp/consul
* use the MaxQueryTime instead of RPCHoldTimeout for blocking RPC queries
[[GH-8978](https://github.com/hashicorp/consul/pull/8978)]. [[GH-10299](https://github.com/hashicorp/consul/issues/10299)]
## 1.10.3 (September 27, 2021)
FEATURES:
* sso/oidc: **(Enterprise only)** Add support for providing acr_values in OIDC auth flow [[GH-11026](https://github.com/hashicorp/consul/issues/11026)]
IMPROVEMENTS:
* audit-logging: **(Enterprise Only)** Audit logs will now include select HTTP headers in each logs payload. Those headers are: `Forwarded`, `Via`, `X-Forwarded-For`, `X-Forwarded-Host` and `X-Forwarded-Proto`. [[GH-11107](https://github.com/hashicorp/consul/issues/11107)]
* connect: update supported envoy versions to 1.18.4, 1.17.4, 1.16.5 [[GH-10961](https://github.com/hashicorp/consul/issues/10961)]
* telemetry: Add new metrics for the count of KV entries in the Consul store. [[GH-11090](https://github.com/hashicorp/consul/issues/11090)]
BUG FIXES:
* api: Revert early out errors from license APIs to allow v1.10+ clients to
manage licenses on older servers [[GH-10952](https://github.com/hashicorp/consul/issues/10952)]
* connect: Fix upstream listener escape hatch for prepared queries [[GH-11109](https://github.com/hashicorp/consul/issues/11109)]
* grpc: strip local ACL tokens from RPCs during forwarding if crossing datacenters [[GH-11099](https://github.com/hashicorp/consul/issues/11099)]
* tls: consider presented intermediates during server connection tls handshake. [[GH-10964](https://github.com/hashicorp/consul/issues/10964)]
* ui: **(Enterprise Only)** Fix saving intentions with namespaced source/destination [[GH-11095](https://github.com/hashicorp/consul/issues/11095)]
* ui: Don't show a CRD warning for read-only intentions [[GH-11149](https://github.com/hashicorp/consul/issues/11149)]
* ui: Ensure routing-config page blocking queries are cleaned up correctly [[GH-10915](https://github.com/hashicorp/consul/issues/10915)]
* ui: Ignore reported permissions for KV area meaning the KV is always enabled
for both read/write access if the HTTP API allows. [[GH-10916](https://github.com/hashicorp/consul/issues/10916)]
* ui: hide create button for policies/roles/namespace if users token has no write permissions to those areas [[GH-10914](https://github.com/hashicorp/consul/issues/10914)]
* xds: ensure the active streams counters are 64 bit aligned on 32 bit systems [[GH-11085](https://github.com/hashicorp/consul/issues/11085)]
* xds: fixed a bug where Envoy sidecars could enter a state where they failed to receive xds updates from Consul [[GH-10987](https://github.com/hashicorp/consul/issues/10987)]
## 1.10.2 (August 27, 2021)
KNOWN ISSUES:
@ -249,6 +277,23 @@ NOTES:
* legal: **(Enterprise only)** Enterprise binary downloads will now include a copy of the EULA and Terms of Evaluation in the zip archive
## 1.9.10 (September 27, 2021)
FEATURES:
* sso/oidc: **(Enterprise only)** Add support for providing acr_values in OIDC auth flow [[GH-11026](https://github.com/hashicorp/consul/issues/11026)]
IMPROVEMENTS:
* audit-logging: **(Enterprise Only)** Audit logs will now include select HTTP headers in each logs payload. Those headers are: `Forwarded`, `Via`, `X-Forwarded-For`, `X-Forwarded-Host` and `X-Forwarded-Proto`. [[GH-11107](https://github.com/hashicorp/consul/issues/11107)]
* connect: update supported envoy versions to 1.16.5 [[GH-10961](https://github.com/hashicorp/consul/issues/10961)]
* telemetry: Add new metrics for the count of KV entries in the Consul store. [[GH-11090](https://github.com/hashicorp/consul/issues/11090)]
BUG FIXES:
* tls: consider presented intermediates during server connection tls handshake. [[GH-10964](https://github.com/hashicorp/consul/issues/10964)]
* ui: **(Enterprise Only)** Fix saving intentions with namespaced source/destination [[GH-11095](https://github.com/hashicorp/consul/issues/11095)]
## 1.9.9 (August 27, 2021)
KNOWN ISSUES:
@ -590,6 +635,21 @@ BUG FIXES:
* telemetry: fixed a bug that caused logs to be flooded with `[WARN] agent.router: Non-server in server-only area` [[GH-8685](https://github.com/hashicorp/consul/issues/8685)]
* ui: show correct datacenter for gateways [[GH-8704](https://github.com/hashicorp/consul/issues/8704)]
## 1.8.16 (September 27, 2021)
FEATURES:
* sso/oidc: **(Enterprise only)** Add support for providing acr_values in OIDC auth flow [[GH-11026](https://github.com/hashicorp/consul/issues/11026)]
IMPROVEMENTS:
* audit-logging: **(Enterprise Only)** Audit logs will now include select HTTP headers in each logs payload. Those headers are: `Forwarded`, `Via`, `X-Forwarded-For`, `X-Forwarded-Host` and `X-Forwarded-Proto`. [[GH-11107](https://github.com/hashicorp/consul/issues/11107)]
BUG FIXES:
* tls: consider presented intermediates during server connection tls handshake. [[GH-10964](https://github.com/hashicorp/consul/issues/10964)]
* ui: **(Enterprise Only)** Fixes a visual issue where namespaces would "double up" in the Source/Destination select menu when creating/editing intentions [[GH-11102](https://github.com/hashicorp/consul/issues/11102)]
## 1.8.15 (August 27, 2021)
KNOWN ISSUES:

View File

@ -2864,44 +2864,6 @@ func (a *Agent) AdvertiseAddrLAN() string {
return a.config.AdvertiseAddrLAN.String()
}
// resolveProxyCheckAddress returns the best address to use for a TCP check of
// the proxy's public listener. It expects the input to already have default
// values populated by applyProxyConfigDefaults. It may return an empty string
// indicating that the TCP check should not be created at all.
//
// By default this uses the proxy's bind address which in turn defaults to the
// agent's bind address. If the proxy bind address ends up being 0.0.0.0 we have
// to assume the agent can dial it over loopback which is usually true.
//
// In some topologies such as proxy being in a different container, the IP the
// agent used to dial proxy over a local bridge might not be the same as the
// container's public routable IP address so we allow a manual override of the
// check address in config "tcp_check_address" too.
//
// Finally the TCP check can be disabled by another manual override
// "disable_tcp_check" in cases where the agent will never be able to dial the
// proxy directly for some reason.
func (a *Agent) resolveProxyCheckAddress(proxyCfg map[string]interface{}) string {
// If user disabled the check return empty string
if disable, ok := proxyCfg["disable_tcp_check"].(bool); ok && disable {
return ""
}
// If user specified a custom one, use that
if chkAddr, ok := proxyCfg["tcp_check_address"].(string); ok && chkAddr != "" {
return chkAddr
}
// If we have a bind address and its diallable, use that
if bindAddr, ok := proxyCfg["bind_address"].(string); ok &&
bindAddr != "" && bindAddr != "0.0.0.0" && bindAddr != "[::]" {
return bindAddr
}
// Default to localhost
return "127.0.0.1"
}
func (a *Agent) cancelCheckMonitors(checkID structs.CheckID) {
// Stop any monitors
delete(a.checkReapAfter, checkID)

View File

@ -58,7 +58,7 @@ func (d *AutopilotDelegate) NotifyState(state *autopilot.State) {
func (d *AutopilotDelegate) RemoveFailedServer(srv *autopilot.Server) {
go func() {
if err := d.server.RemoveFailedNode(srv.Name, false); err != nil {
d.server.logger.Error("failedto remove server", "name", srv.Name, "id", srv.ID, "error", err)
d.server.logger.Error("failed to remove server", "name", srv.Name, "id", srv.ID, "error", err)
}
}()
}

View File

@ -75,7 +75,7 @@ func TestIntentionApply_new(t *testing.T) {
//nolint:staticcheck
ixn.Intention.UpdatePrecedence()
// Partition fields will be normalized on Intention.Get
ixn.Intention.NormalizePartitionFields()
ixn.Intention.FillPartitionAndNamespace(nil, true)
require.Equal(t, ixn.Intention, actual)
}
@ -269,7 +269,7 @@ func TestIntentionApply_updateGood(t *testing.T) {
//nolint:staticcheck
ixn.Intention.UpdatePrecedence()
// Partition fields will be normalized on Intention.Get
ixn.Intention.NormalizePartitionFields()
ixn.Intention.FillPartitionAndNamespace(nil, true)
require.Equal(t, ixn.Intention, actual)
}
}

View File

@ -1741,3 +1741,51 @@ func intFromBool(cond bool) byte {
}
return 0
}
func aclPolicyInsert(tx WriteTxn, policy *structs.ACLPolicy) error {
if err := tx.Insert(tableACLPolicies, policy); err != nil {
return fmt.Errorf("failed inserting acl policy: %v", err)
}
return updateTableIndexEntries(tx, tableACLPolicies, policy.ModifyIndex, &policy.EnterpriseMeta)
}
func aclRoleInsert(tx WriteTxn, role *structs.ACLRole) error {
// insert the role into memdb
if err := tx.Insert(tableACLRoles, role); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update acl-roles index
return updateTableIndexEntries(tx, tableACLRoles, role.ModifyIndex, &role.EnterpriseMeta)
}
func aclTokenInsert(tx WriteTxn, token *structs.ACLToken) error {
// insert the token into memdb
if err := tx.Insert(tableACLTokens, token); err != nil {
return fmt.Errorf("failed inserting acl token: %v", err)
}
// update the overall acl-tokens index
return updateTableIndexEntries(tx, tableACLTokens, token.ModifyIndex, token.EnterpriseMetadata())
}
func aclAuthMethodInsert(tx WriteTxn, method *structs.ACLAuthMethod) error {
// insert the auth method into memdb
if err := tx.Insert(tableACLAuthMethods, method); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update acl-auth-methods index
return updateTableIndexEntries(tx, tableACLAuthMethods, method.ModifyIndex, &method.EnterpriseMeta)
}
func aclBindingRuleInsert(tx WriteTxn, rule *structs.ACLBindingRule) error {
rule.EnterpriseMeta.Normalize()
// insert the role into memdb
if err := tx.Insert(tableACLBindingRules, rule); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update acl-binding-rules index
return updateTableIndexEntries(tx, tableACLBindingRules, rule.ModifyIndex, &rule.EnterpriseMeta)
}

View File

@ -11,15 +11,10 @@ import (
"github.com/hashicorp/consul/agent/structs"
)
func aclPolicyInsert(tx WriteTxn, policy *structs.ACLPolicy) error {
if err := tx.Insert(tableACLPolicies, policy); err != nil {
return fmt.Errorf("failed inserting acl policy: %v", err)
func updateTableIndexEntries(tx WriteTxn, tableName string, modifyIndex uint64, _ *structs.EnterpriseMeta) error {
if err := indexUpdateMaxTxn(tx, modifyIndex, tableName); err != nil {
return fmt.Errorf("failed updating %s index: %v", tableName, err)
}
if err := indexUpdateMaxTxn(tx, policy.ModifyIndex, tableACLPolicies); err != nil {
return fmt.Errorf("failed updating acl policies index: %v", err)
}
return nil
}
@ -56,20 +51,6 @@ func (s *Store) ACLPolicyUpsertValidateEnterprise(*structs.ACLPolicy, *structs.A
///// ACL Token Functions /////
///////////////////////////////////////////////////////////////////////////////
func aclTokenInsert(tx WriteTxn, token *structs.ACLToken) error {
// insert the token into memdb
if err := tx.Insert(tableACLTokens, token); err != nil {
return fmt.Errorf("failed inserting acl token: %v", err)
}
// update the overall acl-tokens index
if err := indexUpdateMaxTxn(tx, token.ModifyIndex, tableACLTokens); err != nil {
return fmt.Errorf("failed updating acl tokens index: %v", err)
}
return nil
}
func aclTokenGetFromIndex(tx ReadTxn, id string, index string, entMeta *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error) {
return tx.FirstWatch(tableACLTokens, index, id)
}
@ -119,19 +100,6 @@ func (s *Store) ACLTokenUpsertValidateEnterprise(token *structs.ACLToken, existi
///// ACL Role Functions /////
///////////////////////////////////////////////////////////////////////////////
func aclRoleInsert(tx WriteTxn, role *structs.ACLRole) error {
// insert the role into memdb
if err := tx.Insert(tableACLRoles, role); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update the overall acl-roles index
if err := indexUpdateMaxTxn(tx, role.ModifyIndex, tableACLRoles); err != nil {
return fmt.Errorf("failed updating acl roles index: %v", err)
}
return nil
}
func aclRoleGetByID(tx ReadTxn, id string, _ *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error) {
return tx.FirstWatch(tableACLRoles, indexID, id)
}
@ -165,20 +133,6 @@ func (s *Store) ACLRoleUpsertValidateEnterprise(role *structs.ACLRole, existing
///// ACL Binding Rule Functions /////
///////////////////////////////////////////////////////////////////////////////
func aclBindingRuleInsert(tx WriteTxn, rule *structs.ACLBindingRule) error {
// insert the role into memdb
if err := tx.Insert(tableACLBindingRules, rule); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update the overall acl-binding-rules index
if err := indexUpdateMaxTxn(tx, rule.ModifyIndex, tableACLBindingRules); err != nil {
return fmt.Errorf("failed updating acl binding-rules index: %v", err)
}
return nil
}
func aclBindingRuleGetByID(tx ReadTxn, id string, _ *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error) {
return tx.FirstWatch(tableACLBindingRules, indexID, id)
}
@ -220,20 +174,6 @@ func (s *Store) ACLBindingRuleUpsertValidateEnterprise(rule *structs.ACLBindingR
///// ACL Auth Method Functions /////
///////////////////////////////////////////////////////////////////////////////
func aclAuthMethodInsert(tx WriteTxn, method *structs.ACLAuthMethod) error {
// insert the role into memdb
if err := tx.Insert(tableACLAuthMethods, method); err != nil {
return fmt.Errorf("failed inserting acl role: %v", err)
}
// update the overall acl-auth-methods index
if err := indexUpdateMaxTxn(tx, method.ModifyIndex, tableACLAuthMethods); err != nil {
return fmt.Errorf("failed updating acl auth methods index: %v", err)
}
return nil
}
func aclAuthMethodGetByName(tx ReadTxn, method string, _ *structs.EnterpriseMeta) (<-chan struct{}, interface{}, error) {
return tx.FirstWatch(tableACLAuthMethods, indexID, Query{Value: method})
}

View File

@ -156,7 +156,7 @@ func TestStore_IntentionSetGet_basic(t *testing.T) {
//nolint:staticcheck
expected.SetHash()
expected.NormalizePartitionFields()
expected.FillPartitionAndNamespace(nil, true)
}
require.True(t, watchFired(ws), "watch fired")
@ -1098,7 +1098,7 @@ func TestStore_IntentionsList(t *testing.T) {
UpdatedAt: testTimeA,
}
if !legacy {
ret.NormalizePartitionFields()
ret.FillPartitionAndNamespace(nil, true)
}
return ret
}

View File

@ -74,8 +74,3 @@ func (ixn *Intention) FillPartitionAndNamespace(entMeta *EnterpriseMeta, fillDef
ixn.SourcePartition = ""
ixn.DestinationPartition = ""
}
func (ixn *Intention) NormalizePartitionFields() {
ixn.SourcePartition = ""
ixn.DestinationPartition = ""
}

View File

@ -15,6 +15,6 @@ func TestIntention(t testing.T) *Intention {
SourceType: IntentionSourceConsul,
Meta: map[string]string{},
}
ixn.NormalizePartitionFields()
ixn.FillPartitionAndNamespace(nil, true)
return ixn
}

View File

@ -71,23 +71,26 @@ func GetPolicyIDFromPartial(client *api.Client, partialID string) (string, error
return policyID, nil
}
func GetPolicyIDByName(client *api.Client, name string) (string, error) {
func GetPolicyByName(client *api.Client, name string) (*api.ACLPolicy, error) {
if name == "" {
return "", fmt.Errorf("No name specified")
return nil, fmt.Errorf("No name specified")
}
policies, _, err := client.ACL().PolicyList(nil)
policy, _, err := client.ACL().PolicyReadByName(name, nil)
if err != nil {
return nil, fmt.Errorf("Failed to find policy with name %s: %w", name, err)
}
return policy, nil
}
func GetPolicyIDByName(client *api.Client, name string) (string, error) {
policy, err := GetPolicyByName(client, name)
if err != nil {
return "", err
}
for _, policy := range policies {
if policy.Name == name {
return policy.ID, nil
}
}
return "", fmt.Errorf("No such policy with name %s", name)
return policy.ID, nil
}
func GetRulesFromLegacyToken(client *api.Client, tokenID string, isSecret bool) (string, error) {

View File

@ -5,6 +5,7 @@ import (
"fmt"
"strings"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/acl"
"github.com/hashicorp/consul/command/acl/policy"
"github.com/hashicorp/consul/command/flags"
@ -67,19 +68,26 @@ func (c *cmd) Run(args []string) int {
}
var policyID string
var pol *api.ACLPolicy
if c.policyID != "" {
policyID, err = acl.GetPolicyIDFromPartial(client, c.policyID)
if err != nil {
c.UI.Error(fmt.Sprintf("Error determining policy ID: %v", err))
return 1
}
pol, _, err = client.ACL().PolicyRead(policyID, nil)
} else {
policyID, err = acl.GetPolicyIDByName(client, c.policyName)
}
if err != nil {
c.UI.Error(fmt.Sprintf("Error determining policy ID: %v", err))
return 1
pol, err = acl.GetPolicyByName(client, c.policyName)
}
p, _, err := client.ACL().PolicyRead(policyID, nil)
if err != nil {
c.UI.Error(fmt.Sprintf("Error reading policy %q: %v", policyID, err))
var errArg string
if c.policyID != "" {
errArg = fmt.Sprintf("id:%s", policyID)
} else {
errArg = fmt.Sprintf("name:%s", c.policyName)
}
c.UI.Error(fmt.Sprintf("Error reading policy %q: %v", errArg, err))
return 1
}
@ -88,7 +96,7 @@ func (c *cmd) Run(args []string) int {
c.UI.Error(err.Error())
return 1
}
out, err := formatter.FormatPolicy(p)
out, err := formatter.FormatPolicy(pol)
if err != nil {
c.UI.Error(err.Error())
return 1

View File

@ -53,6 +53,7 @@ func TestPolicyReadCommand(t *testing.T) {
)
assert.NoError(err)
// Test querying by id field
args := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
@ -66,6 +67,22 @@ func TestPolicyReadCommand(t *testing.T) {
output := ui.OutputWriter.String()
assert.Contains(output, fmt.Sprintf("test-policy"))
assert.Contains(output, policy.ID)
// Test querying by name field
argsName := []string{
"-http-addr=" + a.HTTPAddr(),
"-token=root",
"-name=test-policy",
}
cmd = New(ui)
code = cmd.Run(argsName)
assert.Equal(code, 0)
assert.Empty(ui.ErrorWriter.String())
output = ui.OutputWriter.String()
assert.Contains(output, fmt.Sprintf("test-policy"))
assert.Contains(output, policy.ID)
}
func TestPolicyReadCommand_JSON(t *testing.T) {

View File

@ -4,6 +4,9 @@ export default class IntentionAbility extends BaseAbility {
resource = 'intention';
get canWrite() {
return super.canWrite && (typeof this.item === 'undefined' || this.item.IsEditable);
return super.canWrite && (typeof this.item === 'undefined' || !this.canViewCRD);
}
get canViewCRD() {
return (typeof this.item !== 'undefined' && this.item.IsManagedByCRD);
}
}

View File

@ -7,10 +7,11 @@ import { get } from '@ember/object';
// will give us all the intentions that have the `ns` as either the SourceNS or
// the DestinationNS.
// We currently list intentions by the * wildcard namespace for back compat reasons
// FIXME: Is now a good time to change this behaviour ^ ?
// TODO: Update to use this.formatDatacenter()
export default class IntentionAdapter extends Adapter {
requestForQuery(request, { dc, ns, filter, index, uri }) {
requestForQuery(request, { dc, ns, partition, filter, index, uri }) {
return request`
GET /v1/connect/intentions?${{ dc }}
X-Request-ID: ${uri}${
@ -21,7 +22,7 @@ export default class IntentionAdapter extends Adapter {
}
${{
partition: '',
partition: '*',
ns: '*',
index,
filter,
@ -36,14 +37,21 @@ export default class IntentionAdapter extends Adapter {
// get the information we need from the id, which has been previously
// encoded
const [SourceNS, SourceName, DestinationNS, DestinationName] = id
.split(':')
.map(decodeURIComponent);
const [
SourcePartition,
SourceNS,
SourceName,
DestinationPartition,
DestinationNS,
DestinationName,
] = id.split(':').map(decodeURIComponent);
// FIXME: Service and Namespace are encoded into the URL here
// guessing we need to do the same thing for Partitions
return request`
GET /v1/connect/intentions/exact?${{
source: `${SourceNS}/${SourceName}`,
destination: `${DestinationNS}/${DestinationName}`,
source: `${SourcePartition}/${SourceNS}/${SourceName}`,
destination: `${DestinationPartition}/${DestinationNS}/${DestinationName}`,
dc: dc,
}}
Cache-Control: no-store
@ -54,10 +62,12 @@ export default class IntentionAdapter extends Adapter {
requestForCreateRecord(request, serialized, data) {
const body = {
SourceNS: serialized.SourceNS,
DestinationNS: serialized.DestinationNS,
SourceName: serialized.SourceName,
DestinationName: serialized.DestinationName,
SourceNS: serialized.SourceNS,
DestinationNS: serialized.DestinationNS,
SourcePartition: serialized.SourcePartition,
DestinationPartition: serialized.DestinationPartition,
SourceType: serialized.SourceType,
Meta: serialized.Meta,
Description: serialized.Description,
@ -72,10 +82,12 @@ export default class IntentionAdapter extends Adapter {
body.Permissions = serialized.Permissions;
}
}
// FIXME: Service and Namespace are encoded into the URL here
// guessing we need to do the same thing for Partitions
return request`
PUT /v1/connect/intentions/exact?${{
source: `${data.SourceNS}/${data.SourceName}`,
destination: `${data.DestinationNS}/${data.DestinationName}`,
source: `${data.SourcePartition}/${data.SourceNS}/${data.SourceName}`,
destination: `${data.DestinationPartition}/${data.DestinationNS}/${data.DestinationName}`,
dc: data.Datacenter,
}}
@ -85,16 +97,20 @@ export default class IntentionAdapter extends Adapter {
requestForUpdateRecord(request, serialized, data) {
// you can no longer save Destinations
delete serialized.DestinationNS;
delete serialized.DestinationName;
delete serialized.DestinationNS;
// FIXME: Does the above comment stand for partitions also?
delete serialized.DestinationPartition;
return this.requestForCreateRecord(...arguments);
}
requestForDeleteRecord(request, serialized, data) {
// FIXME: Service and Namespace are encoded into the URL here
// guessing we need to do the same thing for Partitions
return request`
DELETE /v1/connect/intentions/exact?${{
source: `${data.SourceNS}/${data.SourceName}`,
destination: `${data.DestinationNS}/${data.DestinationName}`,
source: `${data.SourcePartition}/${data.SourceNS}/${data.SourceName}`,
destination: `${data.DestinationPartition}/${data.DestinationNS}/${data.DestinationName}`,
dc: data.Datacenter,
}}
`;

View File

@ -28,7 +28,7 @@
<em>Search for an existing service, or enter any Service name.</em>
{{/if}}
</label>
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
{{#if (can 'choose nspaces')}}
<label data-test-source-nspace class="type-select{{if item.error.SourceNS ' has-error'}}">
<span>Source Namespace</span>
<PowerSelectWithCreate
@ -50,7 +50,30 @@
<em>Search for an existing namespace, or enter any Namespace name.</em>
{{/if}}
</label>
{{/if}}
{{/if}}
{{#if (can 'choose partitions')}}
<label data-test-source-partition class="type-select{{if item.error.SourcePartition ' has-error'}}">
<span>Source Partition</span>
<PowerSelectWithCreate
@disabled={{not create}}
@options={{partitions}}
@selected={{SourcePartition}}
@searchPlaceholder="Type partition name"
@buildSuggestion={{action "createNewLabel" "Use a Consul Partition called '{{term}}'"}}
@showCreateWhen={{action "isUnique" partitions}}
@onCreate={{action onchange "SourcePartition"}}
@onChange={{action onchange "SourcePartition"}} as |partition|>
{{#if (eq partition.Name '*') }}
* (All Partitions)
{{else}}
{{partition.Name}}
{{/if}}
</PowerSelectWithCreate>
{{#if create}}
<em>Search for an existing partition, or enter any Partition name.</em>
{{/if}}
</label>
{{/if}}
</fieldset>
<fieldset>
<h2>Destination</h2>
@ -76,7 +99,7 @@
<em>Search for an existing service, or enter any Service name.</em>
{{/if}}
</label>
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
{{#if (can 'choose nspaces')}}
<label data-test-destination-nspace class="type-select{{if item.error.DestinationNS ' has-error'}}">
<span>Destination Namespace</span>
<PowerSelectWithCreate
@ -99,7 +122,31 @@
<em>For the destination, you may choose any namespace for which you have access.</em>
{{/if}}
</label>
{{/if}}
{{/if}}
{{#if (can 'choose partitions')}}
<label data-test-destination-partition class="type-select{{if item.error.DestinationPartition ' has-error'}}">
<span>Destination Partition</span>
<PowerSelectWithCreate
@disabled={{not create}}
@options={{partitions}}
@searchField="Name"
@selected={{DestinationPartition}}
@searchPlaceholder="Type partition name"
@buildSuggestion={{action "createNewLabel" "Use a future Consul Partition called '{{term}}'"}}
@showCreateWhen={{action "isUnique" partitions}}
@onCreate={{action onchange "DestinationPartition"}}
@onChange={{action onchange "DestinationPartition"}} as |partition|>
{{#if (eq partition.Name '*') }}
* (All Partitions)
{{else}}
{{partition.Name}}
{{/if}}
</PowerSelectWithCreate>
{{#if create}}
<em>For the destination, you may choose any partition for which you have access.</em>
{{/if}}
</label>
{{/if}}
</fieldset>
</div>
<fieldset>

View File

@ -95,6 +95,17 @@ as |api|>
/>
{{/if}}
{{#if (can 'use partitions')}}
<DataSource
@src={{uri '/*/*/${dc}/partitions'
(hash
dc=@dc
)
}}
@onchange={{action this.createPartitions item}}
/>
{{/if}}
{{#if (and api.isCreate this.isManagedByCRDs)}}
<Consul::Intention::Notice::CustomResource @type="warning" />
{{/if}}
@ -103,11 +114,14 @@ as |api|>
>
<Consul::Intention::Form::Fieldsets
@nspaces={{this.nspaces}}
@partitions={{this.partitions}}
@services={{this.services}}
@SourceName={{this.SourceName}}
@SourceNS={{this.SourceNS}}
@SourcePartition={{this.SourcePartition}}
@DestinationName={{this.DestinationName}}
@DestinationNS={{this.DestinationNS}}
@DestinationPartition={{this.DestinationPartition}}
@item={{item}}
@disabled={{api.disabled}}
@create={{api.isCreate}}

View File

@ -12,6 +12,10 @@ export default class ConsulIntentionForm extends Component {
@tracked SourceNS;
@tracked DestinationNS;
@tracked partitions;
@tracked SourcePartition;
@tracked DestinationPartition;
@tracked isManagedByCRDs;
modal = null; // reference to the warning modal
@ -115,6 +119,28 @@ export default class ConsulIntentionForm extends Component {
this.DestinationNS = destination;
}
@action
createPartitions(item, e) {
// Partitions in the menus should:
// 1. Include an 'All Partitions' option
// 2. Include the current SourcePartition and DestinationPartition incase they don't exist yet
let items = e.data.toArray().sort((a, b) => a.Name.localeCompare(b.Name));
items = [{ Name: '*' }].concat(items);
let source = items.findBy('Name', item.SourcePartition);
if (!source) {
source = { Name: item.SourcePartition };
items = [source].concat(items);
}
let destination = items.findBy('Name', item.DestinationPartition);
if (!destination) {
destination = { Name: item.DestinationPartition };
items = [destination].concat(items);
}
this.partitions = items;
this.SourcePartition = source;
this.DestinationPartition = destination;
}
@action
change(e, form, item) {
const target = e.target;
@ -125,6 +151,8 @@ export default class ConsulIntentionForm extends Component {
case 'DestinationName':
case 'SourceNS':
case 'DestinationNS':
case 'SourcePartition':
case 'DestinationPartition':
name = selected = target.value;
// Names can be selected Service EmberObjects or typed in strings
// if its not a string, use the `Name` from the Service EmberObject
@ -158,6 +186,13 @@ export default class ConsulIntentionForm extends Component {
this.nspaces = [selected].concat(this.nspaces.toArray());
}
break;
case 'SourcePartition':
case 'DestinationPartition':
if (this.partitions.filterBy('Name', name).length === 0) {
selected = { Name: name };
this.partitions = [selected].concat(this.partitions.toArray());
}
break;
}
this[target.name] = selected;
break;

View File

@ -1,5 +1,26 @@
.consul-intention-list {
td.permissions {
color: $blue-500;
}
%consul-intention-list td.permissions {
color: $blue-500;
}
%consul-intention-list em {
--word-spacing: 0.25rem;
}
%consul-intention-list em span::before,
%consul-intention-list em span:first-child {
margin-right: var(--word-spacing);
}
%consul-intention-list em span:last-child {
margin-left: var(--word-spacing);
}
%consul-intention-list em span::before {
@extend %as-pseudo;
}
%consul-intention-list span[class|='nspace']::before {
@extend %with-folder-outline-mask;
}
%consul-intention-list span[class|='partition']::before {
@extend %with-user-team-mask;
}
.consul-intention-list {
@extend %consul-intention-list;
}

View File

@ -25,7 +25,13 @@ as |item index|>
{{item.SourceName}}
{{/if}}
{{! TODO: slugify }}
<em class={{concat 'nspace-' (or item.SourceNS 'default')}}>{{or item.SourceNS 'default'}}</em>
<em>
<span
class={{concat 'partition-' (or item.SourcePartition 'default')}}
>{{or item.SourcePartition 'default'}}</span> / <span
class={{concat 'nspace-' (or item.SourceNS 'default')}}
>{{or item.SourceNS 'default'}}</span>
</em>
</a>
</td>
<td class="intent intent-{{slugify item.Action}}" data-test-intention-action={{item.Action}}>
@ -39,7 +45,13 @@ as |item index|>
{{item.DestinationName}}
{{/if}}
{{! TODO: slugify }}
<em class={{concat 'nspace-' (or item.DestinationNS 'default')}}>{{or item.DestinationNS 'default'}}</em>
<em>
<span
class={{concat 'partition-' (or item.DestinationPartition 'default')}}
>{{or item.DestinationPartition 'default'}}</span> / <span
class={{concat 'nspace-' (or item.DestinationNS 'default')}}
>{{or item.DestinationNS 'default'}}</span>
</em>
</span>
</td>
<td class="permissions">
@ -53,6 +65,7 @@ as |item index|>
{{/if}}
</td>
</BlockSlot>
{{#if (or (can "write intention" item=item) (can "view CRD intention" item=item))}}
<BlockSlot @name="actions" as |index change checked|>
<PopoverMenu
@expanded={{if (eq checked index) true false}}
@ -101,7 +114,7 @@ as |item index|>
</InformedAction>
</div>
</li>
{{else}}
{{else if (can "view CRD intention" item=item)}}
<li role="none">
<div role="menu">
<InformedAction
@ -140,4 +153,5 @@ as |item index|>
</BlockSlot>
</PopoverMenu>
</BlockSlot>
{{/if}}
</TabularCollection>

View File

@ -4,11 +4,11 @@
<dl>
<dt>Destination</dt>
<dd>
{{item.DestinationName}}{{#if (env "CONSUL_NSPACES_ENABLED")}} / {{item.DestinationNS}}{{/if}}
{{item.DestinationName}}{{#if (can "use partitions")}} / {{item.DestinationPartition}}{{/if}}{{#if (can "use nspaces")}} / {{item.DestinationNS}}{{/if}}
</dd>
<dt>Source</dt>
<dd>
{{item.SourceName}}{{#if (env "CONSUL_NSPACES_ENABLED")}} / {{item.SourceNS}}{{/if}}
{{item.SourceName}}{{#if (can "use partitions")}} / {{item.SourcePartition}}{{/if}}{{#if (can "use nspaces")}} / {{item.SourceNS}}{{/if}}
</dd>
{{#if item.Action}}
<dt>Action</dt>

View File

@ -74,7 +74,7 @@
<button data-test-delete
type="button"
class="type-delete"
onclick={{queue (action confirm onInvalidate item) (refresh-route)}}
onclick={{action confirm onInvalidate item}}
>
Invalidate
</button>
@ -83,8 +83,8 @@
<p>
{{message}}
</p>
<button type="button" class="type-delete" {{action execute}}>Confirm Invalidate</button>
<button type="button" class="type-cancel" {{action cancel}}>Cancel</button>
<button type="button" class="type-delete" onclick={{action execute}}>Confirm Invalidate</button>
<button type="button" class="type-cancel" onclick={{action cancel}}>Cancel</button>
</BlockSlot>
</ConfirmationDialog>
</BlockSlot>

View File

@ -115,13 +115,6 @@
<BlockSlot @name="trigger">
{{@nspace}}
</BlockSlot>
{{#if (is-href 'dc.nspaces')}}
<BlockSlot @name="header">
<p>
Namespaces themselves are not namespaced, so switching will not change the current view.
</p>
</BlockSlot>
{{/if}}
<BlockSlot @name="menu">
{{#let components.MenuItem components.MenuSeparator as |MenuItem MenuSeparator|}}
<DataSource

View File

@ -12,11 +12,14 @@ export default class Intention extends Model {
@attr('string') Datacenter;
@attr('string') Description;
// FIXME: Will we have Source/DestinationPartition?
@attr('string', { defaultValue: () => 'default' }) SourceNS;
@attr('string', { defaultValue: () => '*' }) SourceName;
@attr('string', { defaultValue: () => 'default' }) DestinationNS;
@attr('string', { defaultValue: () => '*' }) DestinationName;
@attr('string', { defaultValue: () => 'default' }) SourceNS;
@attr('string', { defaultValue: () => 'default' }) DestinationNS;
@attr('string', { defaultValue: () => 'default' }) SourcePartition;
@attr('string', { defaultValue: () => 'default' }) DestinationPartition;
@attr('number') Precedence;
@attr('string', { defaultValue: () => 'consul' }) SourceType;
@nullValue(undefined) @attr('string') Action;
@ -38,9 +41,4 @@ export default class Intention extends Model {
);
return typeof meta !== 'undefined';
}
@computed('IsManagedByCRD')
get IsEditable() {
return !this.IsManagedByCRD;
}
}

View File

@ -22,7 +22,7 @@ export default class IntentionSerializer extends Serializer {
item.LegacyID = item.ID;
}
item.ID = this
.uri`${item.SourceNS}:${item.SourceName}:${item.DestinationNS}:${item.DestinationName}`;
.uri`${item.SourcePartition}:${item.SourceNS}:${item.SourceName}:${item.DestinationPartition}:${item.DestinationNS}:${item.DestinationName}`;
return item;
}
@ -56,7 +56,7 @@ export default class IntentionSerializer extends Serializer {
return respond((headers, body) => {
body = data;
body.ID = this
.uri`${serialized.SourceNS}:${serialized.SourceName}:${serialized.DestinationNS}:${serialized.DestinationName}`;
.uri`${serialized.SourcePartition}:${serialized.SourceNS}:${serialized.SourceName}:${serialized.DestinationPartition}:${serialized.DestinationNS}:${serialized.DestinationName}`;
return this.fingerprint(primaryKey, slugKey, body.Datacenter)(body);
});
}

View File

@ -69,9 +69,12 @@ export default class IntentionRepository extends RepositoryService {
let item;
if (params.id === '') {
const defaultNspace = this.env.var('CONSUL_NSPACES_ENABLED') ? '*' : 'default';
const defaultPartition = this.env.var('CONSUL_PARTITIONS_ENABLED') ? '*' : 'default';
item = await this.create({
SourceNS: params.nspace || defaultNspace,
DestinationNS: params.nspace || defaultNspace,
SourcePartition: params.partition || defaultPartition,
DestinationPartition: params.partition || defaultPartition,
Datacenter: params.dc,
Partition: params.partition,
});

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,9 @@ main,
html:not(.has-nspaces) [class*='nspace-'] {
display: none;
}
html:not(.has-partitions) [class*='partition-'] {
display: none;
}
#wrapper {
@extend %viewport-container;
display: flex;

View File

@ -6,9 +6,6 @@
%main-nav-horizontal {
@extend %theme-dark;
}
%main-nav-vertical .nspaces .menu-panel > div {
@extend %theme-light;
}
%main-nav-vertical .menu-panel a:hover,
%main-nav-vertical .menu-panel a:focus {
background-color: var(--blue-500);

View File

@ -69,7 +69,9 @@ as |route|>
</h1>
</BlockSlot>
<BlockSlot @name="actions">
{{#if (can "create policies")}}
<a data-test-create href="{{href-to 'dc.acls.policies.create'}}" class="type-create">Create</a>
{{/if}}
</BlockSlot>
<BlockSlot @name="toolbar">
{{#if (gt items.length 0) }}

View File

@ -63,7 +63,9 @@ as |route|>
</h1>
</BlockSlot>
<BlockSlot @name="actions">
{{#if (can "create roles")}}
<a data-test-create href="{{href-to 'dc.acls.roles.create'}}" class="type-create">Create</a>
{{/if}}
</BlockSlot>
<BlockSlot @name="toolbar">
{{#if (gt items.length 0) }}

View File

@ -31,7 +31,7 @@ as |item|}}
</BlockSlot>
<BlockSlot @name="header">
<h1>
{{#if item.IsEditable}}
{{#if (can "write intention" item=item)}}
{{#if item.ID}}
<route.Title @title="Edit Intention" />
{{else}}

View File

@ -55,7 +55,9 @@ as |route|>
</h1>
</BlockSlot>
<BlockSlot @name="actions">
{{#if (can "create nspaces")}}
<a data-test-create href="{{href-to 'dc.nspaces.create'}}" class="type-create">Create</a>
{{/if}}
</BlockSlot>
<BlockSlot @name="toolbar">
{{#if (gt items.length 0)}}

View File

@ -22,10 +22,12 @@ ${legacy ? `
"Action": "${fake.helpers.randomize(['allow', 'deny'])}",
`:``}
"Description": "${fake.lorem.sentence()}",
"SourceNS": "default",
"SourceName": "${fake.hacker.noun()}-${i}",
"DestinationNS": "default",
"DestinationName": "${fake.hacker.noun()}",
"SourceNS": "default",
"DestinationNS": "default",
"SourcePartition": "default",
"DestinationPartition": "default",
"SourceType": "${fake.helpers.randomize(['consul', 'externaluri'])}",
${!legacy ? `
"Permissions": [

View File

@ -6,10 +6,12 @@ return `
"ID": "${legacy ? ID : ''}"
${ http.method !== "PUT" ? `
,"Description": "${fake.lorem.sentence()}",
"SourceNS": "default",
"SourceName": "${fake.hacker.noun()}",
"DestinationNS": "default",
"DestinationName": "${fake.hacker.noun()}",
"SourceNS": "default",
"DestinationNS": "default",
"SourcePartition": "default",
"DestinationPartition": "default",
"SourceType": "${fake.helpers.randomize(['consul', 'externaluri'])}",
${legacy ? `
"Action": "${fake.helpers.randomize(['allow', 'deny'])}",

View File

@ -8,10 +8,12 @@ return `
"ID": "${legacy ? ID : ''}"
${ http.method !== "PUT" ? `
,"Description": "${fake.lorem.sentence()}",
"SourceNS": "${source[0]}",
"SourceName": "${source[1]}",
"DestinationNS": "${destination[0]}",
"DestinationName": "${destination[1]}",
"SourceName": "${source[2]}",
"DestinationName": "${destination[2]}",
"SourceNS": "${source[1]}",
"DestinationNS": "${destination[1]}",
"SourcePartition": "${source[0]}",
"DestinationPartition": "${destination[0]}",
"SourceType": "${fake.helpers.randomize(['consul', 'externaluri'])}",
${legacy ? `
"Action": "${fake.helpers.randomize(['allow', 'deny'])}",

View File

@ -37,22 +37,24 @@ Feature: dc / intentions / create: Intention Create
Then I see the text "db" in "[data-test-destination-element] .ember-power-select-selected-item"
# Set source nspace
And I click "[data-test-source-nspace] .ember-power-select-trigger"
And I click ".ember-power-select-option:nth-child(2)"
And I click ".ember-power-select-option:last-child"
Then I see the text "nspace-0" in "[data-test-source-nspace] .ember-power-select-selected-item"
# Set destination nspace
And I click "[data-test-destination-nspace] .ember-power-select-trigger"
And I click ".ember-power-select-option:nth-child(2)"
And I click ".ember-power-select-option:last-child"
Then I see the text "nspace-0" in "[data-test-destination-nspace] .ember-power-select-selected-item"
# Specifically set deny
And I click ".value-deny"
And I submit
Then a PUT request was made to "/v1/connect/intentions/exact?source=nspace-0%2Fweb&destination=nspace-0%2Fdb&dc=datacenter" from yaml
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fnspace-0%2Fweb&destination=default%2Fnspace-0%2Fdb&dc=datacenter" from yaml
---
body:
SourceName: web
DestinationName: db
SourceNS: nspace-0
DestinationNS: nspace-0
SourcePartition: default
DestinationPartition: default
Action: deny
---
Then the url should be /datacenter/intentions
@ -90,7 +92,7 @@ Feature: dc / intentions / create: Intention Create
# Specifically set deny
And I click ".value-deny"
And I submit
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fweb&destination=default%2Fdb&dc=datacenter" from yaml
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fweb&destination=default%2Fdefault%2Fdb&dc=datacenter" from yaml
---
body:
SourceName: web

View File

@ -4,10 +4,12 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success
Given 1 datacenter model with the value "datacenter"
And 1 intention model from yaml
---
SourceNS: default
SourceName: name
DestinationNS: default
DestinationName: destination
SourceNS: default
DestinationNS: default
SourcePartition: default
DestinationPartition: default
ID: ee52203d-989f-4f7a-ab5a-2bef004164ca
Meta: ~
---
@ -19,7 +21,7 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success
And I click actions on the intentionList.intentions
And I click delete on the intentionList.intentions
And I click confirmDelete on the intentionList.intentions
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fname&destination=default%2Fdestination&dc=datacenter"
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fname&destination=default%2Fdefault%2Fdestination&dc=datacenter"
And "[data-notification]" has the "notification-delete" class
And "[data-notification]" has the "success" class
Scenario: Deleting an intention from the intention detail page
@ -30,7 +32,7 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success
---
And I click delete
And I click confirmDelete
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fname&destination=default%2Fdestination&dc=datacenter"
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fname&destination=default%2Fdefault%2Fdestination&dc=datacenter"
And "[data-notification]" has the "notification-delete" class
And "[data-notification]" has the "success" class
Scenario: Deleting an intention from the intention detail page and getting an error
@ -39,7 +41,7 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success
dc: datacenter
intention: ee52203d-989f-4f7a-ab5a-2bef004164ca
---
Given the url "/v1/connect/intentions/exact?source=default%2Fname&destination=default%2Fdestination&dc=datacenter" responds with a 500 status
Given the url "/v1/connect/intentions/exact?source=default%2Fdefault%2Fname&destination=default%2Fdefault%2Fdestination&dc=datacenter" responds with a 500 status
And I click delete
And I click confirmDelete
And "[data-notification]" has the "notification-update" class
@ -50,7 +52,7 @@ Feature: dc / intentions / deleting: Deleting items with confirmations, success
dc: datacenter
intention: ee52203d-989f-4f7a-ab5a-2bef004164ca
---
Given the url "/v1/connect/intentions/exact?source=default%2Fname&destination=default%2Fdestination&dc=datacenter" responds with from yaml
Given the url "/v1/connect/intentions/exact?source=default%2Fdefault%2Fname&destination=default%2Fdefault%2Fdestination&dc=datacenter" responds with from yaml
---
status: 500
body: "duplicate intention found:"

View File

@ -4,10 +4,12 @@ Feature: dc / intentions / permissions / warn: Intention Permission Warn
Given 1 datacenter model with the value "datacenter"
And 1 intention model from yaml
---
SourceNS: default
SourceName: web
DestinationNS: default
DestinationName: db
SourceNS: default
DestinationNS: default
SourcePartition: default
DestinationPartition: default
Action: ~
Permissions:
- Action: allow
@ -28,4 +30,4 @@ Feature: dc / intentions / permissions / warn: Intention Permission Warn
And I submit
And I see the warning object
And I click the warning.confirm object
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fweb&destination=default%2Fdb&dc=datacenter" from yaml
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fweb&destination=default%2Fdefault%2Fdb&dc=datacenter" from yaml

View File

@ -4,10 +4,12 @@ Feature: dc / intentions / update: Intention Update
Given 1 datacenter model with the value "datacenter"
And 1 intention model from yaml
---
SourceNS: default
SourceName: web
DestinationNS: default
DestinationName: db
SourceNS: default
DestinationNS: default
SourcePartition: default
DestinationPartition: default
ID: intention-id
---
When I visit the intention page for yaml
@ -24,7 +26,7 @@ Feature: dc / intentions / update: Intention Update
---
And I click "[value=[Action]]"
And I submit
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fweb&destination=default%2Fdb&dc=datacenter" from yaml
Then a PUT request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fweb&destination=default%2Fdefault%2Fdb&dc=datacenter" from yaml
---
Description: [Description]
Action: [Action]
@ -39,7 +41,7 @@ Feature: dc / intentions / update: Intention Update
| Desc | allow |
------------------------------
Scenario: There was an error saving the intention
Given the url "/v1/connect/intentions/exact?source=default%2Fweb&destination=default%2Fdb&dc=datacenter" responds with a 500 status
Given the url "/v1/connect/intentions/exact?source=default%2Fdefault%2Fweb&destination=default%2Fdefault%2Fdb&dc=datacenter" responds with a 500 status
And I submit
Then the url should be /datacenter/intentions/intention-id
Then "[data-notification]" has the "notification-update" class

View File

@ -15,10 +15,12 @@ Feature: dc / services / show / intentions: Intentions per service
- ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f0
Action: allow
Meta: ~
SourceNS: default
SourceName: name
DestinationNS: default
DestinationName: destination
SourceNS: default
DestinationNS: default
SourcePartition: default
DestinationPartition: default
- ID: 755b72bd-f5ab-4c92-90cc-bed0e7d8e9f1
Action: deny
@ -39,11 +41,11 @@ Feature: dc / services / show / intentions: Intentions per service
Scenario: I can see intentions
And I see 3 intention models on the intentionList component
And I click intention on the intentionList.intentions component
Then the url should be /dc1/services/service-0/intentions/default:name:default:destination
Then the url should be /dc1/services/service-0/intentions/default:default:name:default:default:destination
Scenario: I can delete intentions
And I click actions on the intentionList.intentions component
And I click delete on the intentionList.intentions component
And I click confirmDelete on the intentionList.intentions
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fname&destination=default%2Fdestination&dc=dc1"
Then a DELETE request was made to "/v1/connect/intentions/exact?source=default%2Fdefault%2Fname&destination=default%2Fdefault%2Fdestination&dc=dc1"
And "[data-notification]" has the "notification-delete" class
And "[data-notification]" has the "success" class

View File

@ -7,7 +7,8 @@ const nspaceRunner = getNspaceRunner('intention');
module('Integration | Adapter | intention', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
const id = 'SourceNS:SourceName:DestinationNS:DestinationName';
const id =
'SourcePartition:SourceNS:SourceName:DestinationPartition:DestinationNS:DestinationName';
test('requestForQuery returns the correct url', function(assert) {
return nspaceRunner(
(adapter, serializer, client) => {
@ -15,6 +16,7 @@ module('Integration | Adapter | intention', function(hooks) {
return adapter.requestForQuery(request, {
dc: dc,
ns: 'team-1',
partition: 'partition-1',
filter: '*',
index: 1,
});
@ -23,6 +25,7 @@ module('Integration | Adapter | intention', function(hooks) {
filter: '*',
index: 1,
ns: '*',
partition: '*',
},
{
filter: '*',
@ -36,7 +39,7 @@ module('Integration | Adapter | intention', function(hooks) {
const adapter = this.owner.lookup('adapter:intention');
const client = this.owner.lookup('service:client/http');
const request = client.url.bind(client);
const expected = `GET /v1/connect/intentions/exact?source=SourceNS%2FSourceName&destination=DestinationNS%2FDestinationName&dc=${dc}`;
const expected = `GET /v1/connect/intentions/exact?source=SourcePartition%2FSourceNS%2FSourceName&destination=DestinationPartition%2FDestinationNS%2FDestinationName&dc=${dc}`;
const actual = adapter
.requestForQueryRecord(request, {
dc: dc,
@ -59,17 +62,19 @@ module('Integration | Adapter | intention', function(hooks) {
const adapter = this.owner.lookup('adapter:intention');
const client = this.owner.lookup('service:client/http');
const request = client.url.bind(client);
const expected = `PUT /v1/connect/intentions/exact?source=SourceNS%2FSourceName&destination=DestinationNS%2FDestinationName&dc=${dc}`;
const expected = `PUT /v1/connect/intentions/exact?source=SourcePartition%2FSourceNS%2FSourceName&destination=DestinationPartition%2FDestinationNS%2FDestinationName&dc=${dc}`;
const actual = adapter
.requestForCreateRecord(
request,
{},
{
Datacenter: dc,
SourceNS: 'SourceNS',
SourceName: 'SourceName',
DestinationNS: 'DestinationNS',
DestinationName: 'DestinationName',
SourceNS: 'SourceNS',
DestinationNS: 'DestinationNS',
SourcePartition: 'SourcePartition',
DestinationPartition: 'DestinationPartition',
}
)
.split('\n')[0];
@ -79,17 +84,19 @@ module('Integration | Adapter | intention', function(hooks) {
const adapter = this.owner.lookup('adapter:intention');
const client = this.owner.lookup('service:client/http');
const request = client.url.bind(client);
const expected = `PUT /v1/connect/intentions/exact?source=SourceNS%2FSourceName&destination=DestinationNS%2FDestinationName&dc=${dc}`;
const expected = `PUT /v1/connect/intentions/exact?source=SourcePartition%2FSourceNS%2FSourceName&destination=DestinationPartition%2FDestinationNS%2FDestinationName&dc=${dc}`;
const actual = adapter
.requestForUpdateRecord(
request,
{},
{
Datacenter: dc,
SourceNS: 'SourceNS',
SourceName: 'SourceName',
DestinationNS: 'DestinationNS',
DestinationName: 'DestinationName',
SourceNS: 'SourceNS',
DestinationNS: 'DestinationNS',
SourcePartition: 'SourcePartition',
DestinationPartition: 'DestinationPartition',
}
)
.split('\n')[0];
@ -99,17 +106,19 @@ module('Integration | Adapter | intention', function(hooks) {
const adapter = this.owner.lookup('adapter:intention');
const client = this.owner.lookup('service:client/http');
const request = client.url.bind(client);
const expected = `DELETE /v1/connect/intentions/exact?source=SourceNS%2FSourceName&destination=DestinationNS%2FDestinationName&dc=${dc}`;
const expected = `DELETE /v1/connect/intentions/exact?source=SourcePartition%2FSourceNS%2FSourceName&destination=DestinationPartition%2FDestinationNS%2FDestinationName&dc=${dc}`;
const actual = adapter
.requestForDeleteRecord(
request,
{},
{
Datacenter: dc,
SourceNS: 'SourceNS',
SourceName: 'SourceName',
DestinationNS: 'DestinationNS',
DestinationName: 'DestinationName',
SourceNS: 'SourceNS',
DestinationNS: 'DestinationNS',
SourcePartition: 'SourcePartition',
DestinationPartition: 'DestinationPartition',
}
)
.split('\n')[0];

View File

@ -26,7 +26,7 @@ module('Integration | Serializer | intention', function(hooks) {
// refactored out our Serializer this can go
Namespace: nspace,
Partition: partition,
uid: `["${partition}","${nspace}","${dc}","${item.SourceNS}:${item.SourceName}:${item.DestinationNS}:${item.DestinationName}"]`,
uid: `["${partition}","${nspace}","${dc}","${item.SourcePartition}:${item.SourceNS}:${item.SourceName}:${item.DestinationPartition}:${item.DestinationNS}:${item.DestinationName}"]`,
})
);
const actual = serializer.respondForQuery(
@ -55,10 +55,12 @@ module('Integration | Serializer | intention', function(hooks) {
url: `/v1/connect/intentions/${id}?dc=${dc}`,
};
const item = {
SourceNS: 'SourceNS',
SourceName: 'SourceName',
DestinationNS: 'DestinationNS',
DestinationName: 'DestinationName',
SourceNS: 'SourceNS',
DestinationNS: 'DestinationNS',
SourcePartition: 'SourcePartition',
DestinationPartition: 'DestinationPartition',
};
return get(request.url).then(function(payload) {
payload = {
@ -76,7 +78,7 @@ module('Integration | Serializer | intention', function(hooks) {
// refactored out our Serializer this can go
Namespace: nspace,
Partition: partition,
uid: `["${partition}","${nspace}","${dc}","${item.SourceNS}:${item.SourceName}:${item.DestinationNS}:${item.DestinationName}"]`,
uid: `["${partition}","${nspace}","${dc}","${item.SourcePartition}:${item.SourceNS}:${item.SourceName}:${item.DestinationPartition}:${item.DestinationNS}:${item.DestinationName}"]`,
});
const actual = serializer.respondForQueryRecord(
function(cb) {

View File

@ -0,0 +1,65 @@
/* globals requirejs */
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Ability | *', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
const abilities = Object.keys(requirejs.entries)
.filter(key => key.indexOf('/abilities/') !== -1)
.map(key => key.split('/').pop())
.filter(item => item !== '-test');
abilities.forEach(item => {
const ability = this.owner.factoryFor(`ability:${item}`).create();
[true, false].forEach(bool => {
const permissions = this.owner.lookup(`service:repository/permission`);
ability.permissions = {
has: _ => bool,
permissions: bool ? ['more-than-zero'] : [],
generate: function() {
return permissions.generate(...arguments);
},
};
['Create', 'Read', 'Update', 'Delete', 'Write', 'List'].forEach(perm => {
switch (item) {
case 'permission':
ability.item = {
ID: bool ? 'not-anonymous' : 'anonymous',
};
break;
case 'acl':
ability.item = {
ID: bool ? 'not-anonymous' : 'anonymous',
};
break;
case 'token':
ability.item = {
AccessorID: 'not-anonymous',
};
ability.token = {
AccessorID: bool ? 'different-to-item' : 'not-anonymous',
};
break;
case 'nspace':
case 'partition':
ability.item = {
ID: bool ? 'not-default' : 'default',
};
break;
case 'kv':
// TODO: We currently hardcode KVs to always be true
assert.equal(true, ability[`can${perm}`], `Expected ${item}.can${perm} to be true`);
return;
}
assert.equal(
bool,
ability[`can${perm}`],
`Expected ${item}.can${perm} to be ${bool ? 'true' : 'false'}`
);
});
});
});
});
});

View File

@ -61,9 +61,8 @@ The options below are all specified on the command-line.
address is advertised. However, in some cases, there may be a routable address
that cannot be bound. This flag enables gossiping a different address to support
this. If this address is not routable, the node will be in a constant flapping
state as other nodes will treat the non-routability as a failure. In Consul 1.0
and later this can be set to a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template.
state as other nodes will treat the non-routability as a failure. In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-advertise-wan` ((#\_advertise-wan)) - The advertise WAN address is used
to change the address that we advertise to server nodes joining through the WAN.
@ -73,7 +72,8 @@ The options below are all specified on the command-line.
and private datacenters. This flag enables server nodes gossiping through the public
network for the WAN while using private VLANs for gossiping to each other and their
client agents, and it allows client agents to be reached at this address when being
accessed from a remote datacenter if the remote datacenter is configured with [`translate_wan_addrs`](#translate_wan_addrs). In Consul 1.0 and later this can be set to a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template) template
accessed from a remote datacenter if the remote datacenter is configured with [`translate_wan_addrs`](#translate_wan_addrs). In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-bootstrap` ((#\_bootstrap)) - This flag is used to control if a server
is in "bootstrap" mode. It is important that no more than one server **per** datacenter
@ -99,9 +99,8 @@ The options below are all specified on the command-line.
`"[::]"`, Consul will [advertise](/docs/agent/options#_advertise) the public
IPv6 address. If there are multiple public IPv6 addresses available, Consul will
exit with an error at startup. Consul uses both TCP and UDP and the same port for
both. If you have any firewalls, be sure to allow both protocols. In Consul 1.0
and later this can be set to a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template that needs to resolve to a single address. Some example templates:
both. If you have any firewalls, be sure to allow both protocols. In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that must resolve at runtime to a single address. Some example templates:
```shell
# Using address within a specific CIDR
@ -121,17 +120,15 @@ The options below are all specified on the command-line.
- `-serf-wan-bind` ((#\_serf_wan_bind)) - The address that should be bound
to for Serf WAN gossip communications. By default, the value follows the same rules
as [`-bind` command-line flag](#_bind), and if this is not specified, the `-bind`
option is used. This is available in Consul 0.7.1 and later. In Consul 1.0 and
later this can be set to a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template
option is used. This is available in Consul 0.7.1 and later. In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-serf-lan-bind` ((#\_serf_lan_bind)) - The address that should be bound
to for Serf LAN gossip communications. This is an IP address that should be reachable
by all other LAN nodes in the cluster. By default, the value follows the same rules
as [`-bind` command-line flag](#_bind), and if this is not specified, the `-bind`
option is used. This is available in Consul 0.7.1 and later. In Consul 1.0 and
later this can be set to a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template
option is used. This is available in Consul 0.7.1 and later. In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-check_output_max_size` - Override the default
limit of 4k for maximum size of checks, this is a positive value. By limiting this
@ -142,7 +139,7 @@ The options below are all specified on the command-line.
- `-client` ((#\_client)) - The address to which Consul will bind client
interfaces, including the HTTP and DNS servers. By default, this is "127.0.0.1",
allowing only loopback connections. In Consul 1.0 and later this can be set to
a space-separated list of addresses to bind to, or a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
a space-separated list of addresses to bind to, or a [go-sockaddr]
template that can potentially resolve to multiple addresses.
- `-config-file` ((#\_config_file)) - A configuration file to load. For
@ -299,9 +296,12 @@ The options below are all specified on the command-line.
By default, the agent won't join any nodes when it starts up. Note that using [`retry_join`](#retry_join) could be more appropriate to help mitigate node startup race conditions when automating
a Consul cluster deployment.
In Consul 1.1.0 and later this can be set to a
[go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template
In Consul 1.1.0 and later this can be dynamically defined with a
[go-sockaddr]
template that is resolved at runtime.
If using Enterprise network segments, see [additional documentation on
joining a client to a segment](/docs/enterprise/network-segments#join_a_client_to_a_segment).
- `-retry-join` ((#\_retry_join)) - Similar to [`-join`](#_join) but allows retrying a join until
it is successful. Once it joins successfully to a member in a list of members
@ -309,15 +309,23 @@ The options below are all specified on the command-line.
membership via gossip. This is useful for cases where you know the address will
eventually be available. This option can be specified multiple times to
specify multiple agents to join. The value can contain IPv4, IPv6, or DNS
addresses. In Consul 1.1.0 and later this can be set to a
[go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template. If Consul is running on the non-default Serf LAN port, the port must
addresses. IPv6 must use the "bracketed" syntax. If multiple values
are given, they are tried and retried in the order listed until the first
succeeds.
In Consul 1.1.0 and later this can be dynamically defined with a
[go-sockaddr]
template that is resolved at runtime.
If Consul is running on the non-default Serf LAN port, the port must
be specified in the join address, or configured as the agent's default Serf port
using the [`ports.serf_lan`](#serf_lan_port) configuration option or
[`-serf-lan-port`](#_serf_lan_port) command line flag.
IPv6 must use the "bracketed" syntax. If multiple values
are given, they are tried and retried in the order listed until the first
succeeds. Here are some examples:
If using network segments (Enterprise), see [additional documentation on
joining a client to a segment](/docs/enterprise/network-segments#join_a_client_to_a_segment).
Here are some examples of using `-retry-join`:
```shell
# Using a DNS entry
@ -369,18 +377,16 @@ The options below are all specified on the command-line.
startup will fail. By default, the agent won't [`-join-wan`](#_join_wan) any nodes
when it starts up.
In Consul 1.1.0 and later this can be set to a
[go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template.
In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-retry-join-wan` ((#\_retry_join_wan)) - Similar to [`retry-join`](#_retry_join)
but allows retrying a wan join if the first attempt fails. This is useful for cases
where we know the address will become available eventually. As of Consul 0.9.3
[Cloud Auto-Joining](#cloud-auto-joining) is supported as well.
In Consul 1.1.0 and later this can be set to a
[go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
template
In Consul 1.1.0 and later this can be dynamically defined with a [go-sockaddr]
template that is resolved at runtime.
- `-retry-interval-wan` ((#\_retry_interval_wan)) - Time to wait between
[`-join-wan`](#_join_wan) attempts. Defaults to 30s.
@ -435,7 +441,7 @@ The options below are all specified on the command-line.
but allows retrying discovery of fallback addresses for the mesh gateways in the
primary datacenter if the first attempt fails. This is useful for cases where we
know the address will become available eventually. [Cloud Auto-Joining](#cloud-auto-joining)
is supported as well as [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template)
is supported as well as [go-sockaddr]
templates. This was added in Consul 1.8.0.
- `-raft-protocol` ((#\_raft_protocol)) - This controls the internal version
@ -453,10 +459,11 @@ The options below are all specified on the command-line.
- `-segment` ((#\_segment)) <EnterpriseAlert inline /> - This flag is used to set
the name of the network segment the agent belongs to. An agent can only join and
communicate with other agents within its network segment. Review the [Network Segments
tutorial](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters) for
more details. By default, this is an empty string, which is the default network
segment.
communicate with other agents within its network segment. Ensure the [join
operation uses the correct port for this segment](/docs/enterprise/network-segments#join_a_client_to_a_segment).
Review the [Network Segments documentation](/docs/enterprise/network-segments)
for more details. By default, this is an empty string, which is the `<default>`
network segment.
- `-serf-lan-allowed-cidrs` ((#\_serf_lan_allowed_cidrs)) - The Serf LAN allowed CIDRs allow to accept incoming
connections for Serf only from several networks (multiple values are supported).
@ -777,7 +784,7 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'."
- `addresses` - This is a nested object that allows setting
bind addresses. In Consul 1.0 and later these can be set to a space-separated list
of addresses to bind to, or a [go-sockaddr](https://godoc.org/github.com/hashicorp/go-sockaddr/template) template that can potentially resolve to multiple addresses.
of addresses to bind to, or a [go-sockaddr] template that can potentially resolve to multiple addresses.
`http`, `https` and `xds` all support binding to a Unix domain socket. A
socket can be specified in the form `unix:///path/to/socket`. A new domain
@ -821,6 +828,7 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'."
`reconnect_timeout` setting when determining when this node may be removed from the cluster.
- `serf_lan` ((#serf_lan_bind)) Equivalent to the [`-serf-lan-bind` command-line flag](#_serf_lan_bind).
This is an IP address, not to be confused with [`ports.serf_lan`](#serf_lan_port).
- `serf_lan_allowed_cidrs` ((#serf_lan_allowed_cidrs)) Equivalent to the [`-serf-lan-allowed-cidrs` command-line flag](#_serf_lan_allowed_cidrs).
@ -1849,9 +1857,9 @@ bind_addr = "{{ GetPrivateInterfaces | include \"network\" \"10.0.0.0/8\" | attr
- `segment` <EnterpriseAlert inline /> - Equivalent to the [`-segment` command-line flag](#_segment).
- `segments` <EnterpriseAlert inline /> - This is a list of nested objects
that allows setting the bind/advertise information for network segments. This can
only be set on servers. Review the [Network Segments tutorial](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters)
- `segments` <EnterpriseAlert inline /> - (Server agents only) This is a list of nested objects
that specifies user-defined network segments, not including the `<default>` segment, which is
created automatically. Review the [Network Segments documentation](/docs/enterprise/network-segments)
for more details.
- `name` ((#segment_name)) - The name of the segment. Must be a string
@ -2385,3 +2393,7 @@ items which are reloaded include:
- TLS Configuration
- Please be aware that this is currently limited to reload a configuration that is already TLS enabled. You cannot enable or disable TLS only with reloading.
- Watches
<!-- list of reference-style links -->
[go-sockaddr]: https://godoc.org/github.com/hashicorp/go-sockaddr/template

View File

@ -355,7 +355,7 @@ spec:
{
name: 'Name',
description:
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined.",
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 [`Permissions`](/docs/connect/config-entries/service-intentions#permissions).",
type: 'string: <required>',
yaml: false,
},
@ -364,7 +364,7 @@ spec:
type: `string: "default"`,
enterprise: true,
description:
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined.",
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 [`Permissions`](/docs/connect/config-entries/service-intentions#permissions).",
yaml: false,
},
{
@ -398,7 +398,7 @@ spec:
hcl: false,
type: 'string: <required>',
description:
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined.",
"The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (`*`) to match all services that don't otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 [`Permissions`](/docs/connect/config-entries/service-intentions#permissions).",
},
{
name: 'namespace',
@ -406,7 +406,7 @@ spec:
enterprise: true,
type: 'string: <optional>',
description:
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined. If not set, the namespace used will depend on the `connectInject.consulNamespaces` configuration. See [ServiceIntentions Special Case (Enterprise)](/docs/k8s/crds#serviceintentions-special-case-enterprise) for more details.",
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined. If not set, the namespace used will depend on the `connectInject.consulNamespaces` configuration. See [ServiceIntentions Special Case (Enterprise)](/docs/k8s/crds#serviceintentions-special-case-enterprise) for more details. Wildcard intentions cannot be used when defining L7 [`Permissions`](/docs/connect/config-entries/service-intentions#permissions).",
},
],
},
@ -470,7 +470,9 @@ spec:
provided permissions in this intention will be subject to the default
intention behavior is defined by the default [ACL policy](/docs/agent/options#acl_default_policy).<br><br>
This should be omitted for an L4 intention as it is mutually exclusive with
the \`Action\` field.`,
the \`Action\` field.<br><br>
Setting \`Permissions\` is not valid if a wildcard is used for the \`Name\` or \`Namespace\` because they can only be
applied to services with a compatible protocol.`,
yaml: `The list of all [additional L7 attributes](#intentionpermission) that extend the intention match criteria.<br><br>
Permission precedence is applied top to bottom. For any given request the
first permission to match in the list is terminal and stops further
@ -478,7 +480,9 @@ spec:
provided permissions in this intention will be subject to the default
intention behavior is defined by the default [ACL policy](/docs/agent/options#acl_default_policy).<br><br>
This should be omitted for an L4 intention as it is mutually exclusive with
the \`action\` field.`,
the \`action\` field.<br><br>
Setting \`permissions\` is not valid if a wildcard is used for the \`spec.destination.name\` or \`spec.destination.namespace\`
because they can only be applied to services with a compatible protocol.`,
},
},
{

View File

@ -61,7 +61,8 @@ receive incoming traffic even if that traffic has passed through a gateway.
## Modes of Operation
Each upstream of a Connect proxy can be configured to be routed through a mesh gateway. Depending on
your network, the proxy's connection to the gateway can happen in one of the following modes:
your network, the proxy's connection to the gateway can happen in one of the following modes
illustrated in the diagram above:
- `local` - In this mode the Connect proxy makes its outbound connection to a gateway running in the
same datacenter. That gateway is then responsible for ensuring the data gets forwarded along to

View File

@ -38,6 +38,8 @@ Operators looking to simplify their WAN deployment and minimize the exposed
security surface area can elect to join these datacenters together using [mesh
gateways](/docs/connect/gateways/mesh-gateway) to do so.
![Mesh Gateway Architecture](/img/mesh-gateways.png)
## Architecture
There are two main kinds of communication that occur over the WAN link spanning

View File

@ -32,8 +32,6 @@ for the built-in proxy.
"config": {
"bind_address": "0.0.0.0",
"bind_port": 20000,
"tcp_check_address": "192.168.0.1",
"disable_tcp_check": false,
"local_service_address": "127.0.0.1:1234",
"local_connect_timeout_ms": 1000,
"handshake_timeout_ms": 10000,
@ -64,19 +62,6 @@ All fields are optional with a reasonable default.
By default the range is [20000, 20255] and the port is selected at random from
that range.
- `tcp_check_address` - The address the agent will
run a [TCP health check](/docs/agent/checks) against. By default this is the same
as the proxy's [bind address](#bind_address) except if the bind address is `0.0.0.0`
or `[::]` in which case this defaults to `127.0.0.1` and assumes the agent can
dial the proxy over loopback. For more complex configurations where agent and proxy
communicate over a bridge for example, this configuration can be used to specify
a different _address_ (but not port) for the agent to use for health checks if
it can't talk to the proxy over localhost or its publicly advertised port. The
check always uses the same port that the proxy is bound to.
- `disable_tcp_check` - If true, this disables a
TCP check being setup for the proxy. Default is false.
- `local_service_address`- The `[address]:port`
that the proxy should use to connect to the local application instance. By default
it assumes `127.0.0.1` as the address and takes the port from the service definition's

View File

@ -11,19 +11,33 @@ description: |-
<EnterpriseAlert>
This feature requires{' '}
<a href="https://www.hashicorp.com/products/consul/">Consul Enterprise</a>{' '}
with the Global Visibility, Routing, and Scale module.
version 0.9.3+ with the Global Visibility, Routing, and Scale module.
</EnterpriseAlert>
Consul Network Segments enables operators to create separate LAN gossip segments
in one Consul cluster. Agents in a segment are only able to join and communicate
with other agents in its network segment. This functionality is useful for
clusters that have multiple tenants that should not be able to communicate
with each other.
Consul requires full connectivity between all agents (servers and clients) in a
[datacenter](/docs/agent/options#_datacenter) within a given
LAN gossip pool. By default, all Consul agents will be a part of one shared Serf LAN
gossip pool known as the `<default>` network segment, thus requiring full mesh
connectivity within the datacenter.
To get started with network segments you can review the tutorial on HashiCorp Learn for
[Network Segments](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters).
![Consul datacenter default agent connectivity: one network segment](/img/network-segments/consul-network-segments-single.png)
~> **Note:** Prior to Consul 1.7.3, a Consul agent configured with too many network segments may not be able to start due to [limitations](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters#network-segments-limitations) in Serf.
In some environments, full connectivity between all agents is not possible—known as a
"segmented network". This is usually the result of business policies enforced through
network rules or firewalls. To use Consul in a segmented network, you must break up
the LAN gossip pool along network communication boundaries into separate "network
segments". Network segments are isolated LAN gossip pools that only require full
connectivity between agent members on the same segment.
![Consul datacenter agent connectivity with network segments](/img/network-segments/consul-network-segments-multiple.png)
To get started with network segments you can review the tutorial on HashiCorp
Learn for [Network Segments](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters).
-> **Info:** Network segments enable you to operate a Consul datacenter without full
mesh (LAN) connectivity between agents. To federate multiple Consul datacenters
without full mesh (WAN) connectivity between all server agents in all datacenters,
use [Network Areas (Enterprise)](/docs/enterprise/federation).
# Consul Networking Models
@ -52,3 +66,171 @@ among themselves, and use Serf to maintain a shared view of the members of the
pool for different purposes, like finding a Consul server in a local cluster,
or finding servers in a remote cluster. A **segmented** LAN Gossip Pool limits a
group of agents to only connect with the agents in its segment.
# Network Segments Configuration
## Server Configuration
Server agents are members of all segments. The datacenter includes a `<default>`
segment, as well as additional segments defined in the
[`segments`](/docs/agent/options#segments) server agent configuration option.
Each additional segment is defined by:
- a non-empty name
- a unique port
- optionally, a custom bind and advertise address for the additional segment's
Serf LAN listener on the server
~> **Note:** Prior to Consul 1.7.3, a Consul server agent configured with too
many network segments may not be able to start due to [limitations](https://learn.hashicorp.com/tutorials/consul/network-partition-datacenters#network-segments-limitations)
in Serf.
### Example Server Configuration
The following server agent configuration will create two user-defined network
segments: `alpha` and `beta`.
<CodeTabs heading="Example network segments configuration for server agents">
```hcl
segments = [
{
name = "alpha"
bind = "{{GetPrivateIP}}"
advertise = "{{GetPrivateIP}}"
port = 8303
},
{
name = "beta"
bind = "{{GetPrivateIP}}"
advertise = "{{GetPrivateIP}}"
port = 8304
}
]
```
```json
{
"segments": [
{
"name": "alpha",
"bind": "{{GetPrivateIP}}",
"advertise": "{{GetPrivateIP}}",
"port": 8303
},
{
"name": "beta",
"bind": "{{GetPrivateIP}}",
"advertise": "{{GetPrivateIP}}",
"port": 8304
}
]
}
```
</CodeTabs>
The server [agent configuration](/docs/agent/options) options relevant to network
segments are:
- [`ports.serf_lan`](/docs/agent/options#serf_lan_port): The Serf LAN port on this server
for the `<default>` network segment's gossip pool.
- [`segments`](/docs/agent/options#segments): A list of user-defined network segments
on this server, including their names and Serf LAN ports.
## Client Configuration
Each client agent can only be a member of one segment at a time. This will be the
`<default>` segment unless otherwise specified in the agent's
[`segment`](/docs/agent/options.html#_segment) agent configuration option.
### Join a Client to a Segment ((#join_a_client_to_a_segment))
For a client agent to [join](/commands/join) the Consul
datacenter, it must connect to another agent (client or server) within its
configured segment.
<Tabs>
<Tab heading="Join via another client">
Clients A and B specify the same segment S. Client B is already joined to the segment S
LAN gossip pool. Client A wants to join via Client B. In order to do so, Client A
must connect to Client B's configured [Serf LAN port](/docs/agent/options#serf_lan_port).
</Tab>
<Tab heading="Join via a server">
Client A specifies segment S and wants to join the segment S gossip pool via Server 1.
In order to do so, Client A must connect to Server 1's configured [Serf LAN port
for segment S](/docs/agent/options#segment_port).
</Tab>
</Tabs>
There are several methods to specify the port used by the join operation, listed in order
of precedence:
1. **Specify an explicit port in the join address**. This can be done at the CLI when starting
the agent (e.g., `consul agent -retry-join "client-b-address:8303"`), or in the agent's
configuration using the [retry-join option](/docs/agent/options#retry_join). This method
is not compatible with [cloud auto-join](/docs/install/cloud-auto-join#auto-join-with-network-segments).
2. **Specify an alternate Serf LAN port for the agent**. This can be done at the CLI when starting
the agent (e.g., `consul agent -retry-join "client-b-address" -serf-lan-port 8303`), or in
the agent's configuration using the [serf_lan](/docs/agent/options#serf_lan_port) option.
When a Serf LAN port is not explicitly specified in the join address, the agent will attempt to
join the target host at the Serf LAN port specified in CLI or agent configuration.
3. **Use the default Serf LAN port (8301)**. The agent will attempt to join the target host
on port 8301.
-> Agents within a segment can use different port numbers for their Serf LAN port.
For example, on the `<default>` segment, Server S can use port 8301, Client A
can use 8303, and Client B can use 8304. However, if an agent wishes to join a
segment via an agent that uses a different port number, the target agent's Serf LAN
port must be specified in the join address (method 1 above).
### Example Client Configuration
The following client agent configuration will cause the agent to:
- Open a Serf LAN listener port on 8303.
- Attempt to join the cluster via servers on port 8303 (since an alternate port is not
specified in the `retry_join` addresses).
<CodeTabs heading="Example network segment configuration for client agents">
```hcl
node_name = "consul-client1"
retry_join = ["consul-server1", "consul-server2", "consul-server3"]
segment = "alpha"
ports = {
serf_lan = 8303
}
```
```json
{
"node_name": "consul-client1",
"retry_join": ["consul-server1", "consul-server2", "consul-server3"],
"segment": "alpha",
"ports": {
"serf_lan": 8303
}
}
```
</CodeTabs>
The client [agent configuration](/docs/agent/options) options relevant to network
segments are:
- [`segment`](/docs/agent/options#segment-2): The name of the network segment this
client agent belongs to.
- [`ports.serf_lan`](/docs/agent/options#serf_lan_port):
Serf LAN port for the above segment on this client. This is not required
to match the configured Serf LAN port for other agents on this segment.
- [`retry_join`](/docs/agent/options#retry_join) or
[`start_join`](/docs/agent/options#start_join): A list of agent addresses to join
when starting. Ensure the correct Serf LAN port for this segment is used when joining
the LAN gossip pool using one of the [available configuration methods](#join_a_client_to_a_segment).

View File

@ -73,7 +73,7 @@ $ export CONSUL_HTTP_SSL_VERIFY=false
If ACLs are enabled also set:
```shell-session
$ export CONSUL_HTTP_TOKEN=$(kubectl get secret consul-bootstrap-acl-token -o jsonpath={.data.token} | base64 --decode)
$ export CONSUL_HTTP_TOKEN=$(kubectl get secret consul-bootstrap-acl-token --template='{{.data.token | base64decode }}')
```
## Register external services with Consul

View File

@ -11,7 +11,7 @@ description: >-
# Kubernetes
Consul has many integrations with Kubernetes. You can deploy Consul
to Kubernetes using the Helm chart, sync services between Consul and
to Kubernetes using the [Helm chart](/docs/k8s/installation/install#helm-chart-installation) or [Consul K8s CLI<sup>ALPHA</sup>](/docs/k8s/installation/install#consul-k8s-cli-installation), sync services between Consul and
Kubernetes, run Consul Connect Service Mesh, and more.
This section documents the official integrations between Consul and Kubernetes.

View File

@ -113,7 +113,7 @@ Then you have likely enabled ACLs. You need to specify your ACL token when
running the `license get` command. First, assign the ACL token to the `CONSUL_HTTP_TOKEN` environment variable:
```shell-session
$ export CONSUL_HTTP_TOKEN=$(kubectl get secrets/hashicorp-consul-bootstrap-acl-token --template={{.data.token}} | base64 --decode)
$ export CONSUL_HTTP_TOKEN=$(kubectl get secrets/hashicorp-consul-bootstrap-acl-token --template='{{.data.token | base64decode }}')
```
Now the token will be used when running Consul commands:

View File

@ -15,78 +15,75 @@ For pure-Kubernetes workloads, this enables Consul to also exist purely
within Kubernetes. For heterogeneous workloads, Consul agents can join
a server running inside or outside of Kubernetes.
This page starts with a large how-to section for various specific tasks.
To learn more about the general architecture of Consul on Kubernetes, scroll
down to the [architecture](/docs/k8s/installation/install#architecture) section.
If you would like to get hands-on experience testing Consul as a service mesh
for Kubernetes, check the guides in the [Getting Started with Consul service
mesh](https://learn.hashicorp.com/tutorials/consul/service-mesh-deploy?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) track.
You can install Consul on Kubernetes using the following methods:
1. [Helm chart install](#helm-chart-installation)
1. [Consul K8s CLI install <sup>ALPHA</sup>.](#consul-k8s-cli-installation)
Refer to the [architecture](/docs/k8s/installation/install#architecture) section to learn more about the general architecture of Consul on Kubernetes.
For a hands-on experience with Consul as a service mesh
for Kubernetes, follow the [Getting Started with Consul service
mesh](https://learn.hashicorp.com/tutorials/consul/service-mesh-deploy?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Helm Chart Installation
The recommended way to run Consul on Kubernetes is via the
[Helm chart](/docs/k8s/helm). This will install and configure
all the necessary components to run Consul. The configuration enables you
to run just a server cluster, just a client cluster, or both. Using the Helm
chart, you can have a full Consul deployment up and running in minutes.
to run a server cluster, a client cluster, or both.
Step-by-step tutorials for how to deploy Consul to Kubernetes, please see
our [Deploy to Kubernetes](https://learn.hashicorp.com/collections/consul/kubernetes-deploy)
collection. This collection includes configuration caveats for single node deployments.
collection. This collection includes configuration caveats for single-node deployments.
While the Helm chart exposes dozens of useful configurations and automatically
sets up complex resources, it **does not automatically operate Consul.**
You are still responsible for learning how to monitor, backup,
The Helm chart exposes several useful configurations and automatically
sets up complex resources, but it **does not automatically operate Consul.**
You must still become familiar with how to monitor, backup,
upgrade, etc. the Consul cluster.
The Helm chart has no required configuration and will install a Consul
cluster with reasonable defaults out of the box. Prior to going to production,
it is highly recommended that you
[learn about the configuration options](/docs/k8s/helm#configuration-values).
cluster with default configurations. We strongly recommend [learning about the configuration options](/docs/k8s/helm#configuration-values) prior to going to production.
~> **Security Warning:** By default, the chart will install an insecure configuration
of Consul. This provides a less complicated out-of-box experience for new users,
but is not appropriate for a production setup. It is highly recommended to use
a properly secured Kubernetes cluster or make sure that you understand and enable
but is not appropriate for a production setup. We strongly recommend using
a properly-secured Kubernetes cluster or making sure that you understand and enable
the [recommended security features](/docs/internals/security). Currently,
some of these features are not supported in the Helm chart and require additional
manual configuration.
### Prerequisites
The Consul Helm chart works only with Helm 3. Install the latest version of the Helm CLI here:
The Consul Helm only supports Helm 3. Install the latest version of the Helm CLI here:
[Installing Helm](https://helm.sh/docs/intro/install/).
### Installing Consul
Add the HashiCorp Helm Repository:
1. Add the HashiCorp Helm Repository:
```shell-session
$ helm repo add hashicorp https://helm.releases.hashicorp.com
"hashicorp" has been added to your repositories
```
```shell-session
$ helm repo add hashicorp https://helm.releases.hashicorp.com
"hashicorp" has been added to your repositories
```
Ensure you have access to the consul chart:
1. Verify that you have access to the consul chart:
```shell-session
$ helm search repo hashicorp/consul
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/consul 0.32.0 1.10.0 Official HashiCorp Consul Chart
```
```shell-session
$ helm search repo hashicorp/consul
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/consul 0.32.0 1.10.0 Official HashiCorp Consul Chart
```
Now you're ready to install Consul! To install Consul with the default
configuration using Helm 3 run:
1. Issue the following command to install Consul with the default configuration using Helm 3:
```shell-session
$ helm install consul hashicorp/consul --set global.name=consul
NAME: consul
...
```
```shell-session
$ helm install consul hashicorp/consul --set global.name=consul
NAME: consul
...
```
_That's it._ The Helm chart does everything to set up a recommended
Consul-on-Kubernetes deployment.
In a couple minutes, a Consul cluster will be formed and a leader
elected and every node will have a running Consul agent.
The Helm chart does everything to set up a recommended Consul-on-Kubernetes deployment.
After installation, a Consul cluster will be formed, a leader will be elected, and every node will have a running Consul agent.
### Customizing Your Installation
@ -102,11 +99,11 @@ use the following config file:
```yaml
global:
name: consul
name: consul
connectInject:
enabled: true
enabled: true
controller:
enabled: true
enabled: true
```
</CodeBlockConfig>
@ -122,6 +119,45 @@ NAME: consul
If you've already installed Consul and want to make changes, you'll need to run
`helm upgrade`. See [Upgrading](/docs/k8s/operations/upgrading) for more details.
## Consul K8s CLI Installation
You can install Consul on Kubernetes using the Consul K8s CLI tool.
The tool is currently availabe as an alpha release and is not recommended for production environments.
1. Download and build the CLI as described in the [Consul K8s CLI reference](/docs/k8s/k8s-cli).
1. Issue the `install` subcommand to install Consul on Kubernetes:
```shell-session
consul-k8s install <OPTIONS>
```
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.
```shell-session
==> 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.
## Viewing the Consul UI
The Consul UI is enabled by default when using the Helm chart.
@ -161,7 +197,7 @@ to see all resources and make modifications.
To retrieve the bootstrap token that has full permissions, run:
```shell-session
$ kubectl get secrets/consul-bootstrap-acl-token --template={{.data.token}} | base64 --decode
$ kubectl get secrets/consul-bootstrap-acl-token --template='{{.data.token | base64decode }}'
e7924dd1-dc3f-f644-da54-81a73ba0a178%
```

View File

@ -35,15 +35,13 @@ The following sections detail how to export this data.
1. Retrieve the certificate authority cert:
```sh
kubectl get secrets/consul-ca-cert --template='{{index .data "tls.crt" }}' |
base64 --decode > consul-agent-ca.pem
kubectl get secrets/consul-ca-cert --template='{{index .data "tls.crt" | base64decode }}' > consul-agent-ca.pem
```
1. And the certificate authority signing key:
```sh
kubectl get secrets/consul-ca-key --template='{{index .data "tls.key" }}' |
base64 --decode > consul-agent-ca-key.pem
kubectl get secrets/consul-ca-key --template='{{index .data "tls.key" | base64decode }}' > consul-agent-ca-key.pem
```
1. With the `consul-agent-ca.pem` and `consul-agent-ca-key.pem` files you can

View File

@ -0,0 +1,110 @@
---
layout: docs
page_title: Consul K8s CLI Reference
description: >-
Consul K8s CLI is a tool for quickly installing and interacting with Consul on Kubernetes.
---
# Consul K8s CLI Reference
Consul K8s CLI is a tool for quickly installing and interacting with Consul on Kubernetes.
This topic describes the commands, subcommands, and available options for using Consul K8s CLI.
~> Consul K8s CLI is is currently availabe as an alpha release and is not recommended for production environments.
## Download and Build the Binary
1. Clone the [consul-k8s](https://github.com/hashicorp/consul-k8s/tree/cli-install/cli) project.
1. Navigate to the `consul-k8s/cli` directory and issue the following command to build the tool:
```shell-session
go build -o bin/consul-k8s
```
1. (Optional) Move the binary to you `$PATH` for ease of use, e.g.:
```shell-session
mv bin/consul-k8s /usr/local/bin/consul-k8s
```
## Usage
Consul K8s CLI uses the following syntax:
```shell-session
consul-k8s <SUBCOMMAND> <OPTIONS>
```
## Subcommands
You can use the following subcommands with `consul-k8s`.
### `install`
The `install` command installs Consul on Kubernetes.
```shell-session
consul-k8s install <OPTIONS>
```
The following options are available.
| Flag | Description | Default | Required |
| --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------- |
| `-auto-approve` &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Boolean value that enables you to skip the installation confirmation prompt. | `false` | Optional |
| `-dry-run` | Boolean value that validates the installation and returns a summary. | `false` | Optional |
| `-config-file` | String value that specifies the path to a file containing custom installation configurations, e.g., Consul Helm chart values file. <br/> You can use the `-config-file` flag multiple times to specify multiple files. | none | Optional |
| `-namespace` | String value that specifies the namespace of the Consul installation. | `consul` | Optional |
| `-preset` | String value that installs Consul based on a preset configuration. You can specify the following values: <br/> `demo`: Installs a single replica server with sidecar injection enabled; useful for testing service mesh functionality. <br/> `secure`: Installs a single replica server with sidecar injection, ACLs, and TLS enabled; useful for testing service mesh functionality. | Configuration of the Consul Helm chart. | Optional |
| `-set` | String value that enables you to set a customizeable value. <br/> You can use the `-set` flag multiple times to set multiple values. <br/> Consul Helm chart values are supported. | none | Optional |
| `-set-file` | String value that specifies the name of a file. The contents of the file will be used to set a customizeable value. <br/> You can use the `-set-file` flag multiple times to specify multiple files. <br/> Consul Helm chart values are supported. | none | Optional |
| `-set-string` | String value that enables you to set a customizeable string value. <br/> You can use the `-set-string` flag multiple times to specify multiple strings. <br/> Consul Helm chart values are supported. | none | Optional |
| `-timeout` | Specifies how long to wait for the installation process to complete before timing out. The value is specified with an integer and string value indicating a unit of time. <br/> The following units are supported: <br/> `ms` (milliseconds)<br/>`s` (seconds)<br/>`m` (minutes) <br/>In the following example, installation will timeout after one minute:<br/> `consul-k8s install -timeout 1m` | Optional | `10m` |
| `-wait` | Boolean value that determines if Consul should wait for resources in the installation to be ready before exiting the command. | Optional | `true` |
See [Global Options](#global-options) for additional commands that you can use when installing Consul on Kubernetes.
#### Example Command
The following example command installs Consul according in the `myNS` namespace according to the `secure` preset.
```shell-session
consul-k8s install -preset=secure -namespace=myNS
```
### `uninstall`
The `uninstall` command removes Consul from Kubernetes.
```shell-session
consul-k8s uninstall <OPTIONS>
```
The following options are available.
| Flag | Description | Default | Required |
| --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -------- |
| `-auto-approve` &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Boolean value that enables you to skip the removal confirmation prompt. | `false` | Optional |
| `-name` | String value for the name of the installation to remove. | none | Optional |
| `-namespace` | String value that specifies the namespace of the Consul installation to remove. | `consul` | Optional |
| `-timeout` | Specifies how long to wait for the removal process to complete before timing out. The value is specified with an integer and string value indicating a unit of time. <br/> The following units are supported: <br/> `ms` (milliseconds)<br/>`s` (seconds)<br/>`m` (minutes) <br/>`h` (hours) <br/>In the following example, removal will timeout after one minute:<br/> `consul-k8s uninstall -timeout 1m` | Optional | `10m` |
| `-wipe-data` | Boolan value that deletes PVCs and secrets associated with the Consul installation during installation. <br/> Data will be removed without a verification prompt if the `-auto-approve` flag is set to `true`. | `false` <br/> Instructions for removing data will be printed to the console. | Optional |
See [Global Options](#global-options) for additional commands that you can use when uninstalling Consul from Kubernetes.
#### Example Command
The following example command immediately uninstalls Consul from the `my-ns` namespace with the name `my-consul` and removes PVCs and secrets associated with the installation without asking for verification:
```shell-session
consul-k8s uninstall -namespace=my-ns -name=my-consul -wipe-data=true -auto-approve=true
```
## Global Options
The following global options are available.
| Flag | Description | Default | Required |
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------- | -------- |
| `-context` &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | String value that sets the Kubernetes context to use for Consul K8s CLI operations. | none | Optional |
| `-kubeconfig` <br/> Alias: `-c` | String value that specifies the path to the `kubeconfig` file. <br/> | none | Optional |

View File

@ -6,73 +6,92 @@ description: Uninstall Consul on Kubernetes
# Uninstall Consul
Uninstalling Consul requires running `helm delete` **and** then manually cleaning
up some resources that Helm does not delete.
You can uninstall Consul using Helm commands or the Consul K8s CLI.
1. First, run `helm delete`:
## Helm commands
```shell-session
$ helm delete hashicorp
release "hashicorp" uninstalled
```
Run the `helm uninstall` **and** manually remove resources that Helm does not delete.
2. After deleting the Helm release, you need to delete the `PersistentVolumeClaim`'s
for the persistent volumes that store Consul's data. These are not deleted by Helm due to a [bug](https://github.com/helm/helm/issues/5156).
To delete, run:
1. First, run `helm uninstall`:
```shell-session
$ kubectl get pvc -l chart=consul-helm
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-default-hashicorp-consul-server-0 Bound pvc-32cb296b-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
data-default-hashicorp-consul-server-1 Bound pvc-32d79919-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
data-default-hashicorp-consul-server-2 Bound pvc-331581ea-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
```shell-session
$ helm uninstall hashicorp
release "hashicorp" uninstalled
```
$ kubectl delete pvc -l chart=consul-helm
persistentvolumeclaim "data-default-hashicorp-consul-server-0" deleted
persistentvolumeclaim "data-default-hashicorp-consul-server-1" deleted
persistentvolumeclaim "data-default-hashicorp-consul-server-2" deleted
```
1. After deleting the Helm release, you need to delete the `PersistentVolumeClaim`'s
for the persistent volumes that store Consul's data. A [bug](https://github.com/helm/helm/issues/5156) in Helm prevents PVCs from being deleted. Issue the following commands:
~> **NOTE:** This will delete **all** data stored in Consul and it can't be
recovered unless you've taken other backups.
```shell-session
$ kubectl get pvc -l chart=consul-helm
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-default-hashicorp-consul-server-0 Bound pvc-32cb296b-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
data-default-hashicorp-consul-server-1 Bound pvc-32d79919-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
data-default-hashicorp-consul-server-2 Bound pvc-331581ea-1213-11ea-b6f0-42010a8001db 10Gi RWO standard 17m
3. If installing with ACLs enabled, you will need to then delete the ACL secrets:
$ kubectl delete pvc -l chart=consul-helm
persistentvolumeclaim "data-default-hashicorp-consul-server-0" deleted
persistentvolumeclaim "data-default-hashicorp-consul-server-1" deleted
persistentvolumeclaim "data-default-hashicorp-consul-server-2" deleted
```
```shell-session
$ kubectl get secret | grep consul | grep Opaque
consul-acl-replication-acl-token Opaque 1 41m
consul-bootstrap-acl-token Opaque 1 41m
consul-client-acl-token Opaque 1 41m
consul-connect-inject-acl-token Opaque 1 37m
consul-controller-acl-token Opaque 1 37m
consul-federation Opaque 4 41m
consul-mesh-gateway-acl-token Opaque 1 41m
```
~> **NOTE:** This will delete **all** data stored in Consul and it can't be
recovered unless you've taken other backups.
4. Ensure that the secrets you're about to delete are all created by Consul and not
created by someone else that happen to have the word `consul`:
1. If installing with ACLs enabled, you will need to then delete the ACL secrets:
```shell-session
$ kubectl get secret | grep consul | grep Opaque | awk '{print $1}' | xargs kubectl delete secret
secret "consul-acl-replication-acl-token" deleted
secret "consul-bootstrap-acl-token" deleted
secret "consul-client-acl-token" deleted
secret "consul-connect-inject-acl-token" deleted
secret "consul-controller-acl-token" deleted
secret "consul-federation" deleted
secret "consul-mesh-gateway-acl-token" deleted
secret "consul-gossip-encryption-key" deleted
```
```shell-session
$ kubectl get secret | grep consul | grep Opaque
consul-acl-replication-acl-token Opaque 1 41m
consul-bootstrap-acl-token Opaque 1 41m
consul-client-acl-token Opaque 1 41m
consul-connect-inject-acl-token Opaque 1 37m
consul-controller-acl-token Opaque 1 37m
consul-federation Opaque 4 41m
consul-mesh-gateway-acl-token Opaque 1 41m
```
5. If installing with `tls.enabled` then there will be a `ServiceAccount` that is left behind:
1. Ensure that the secrets you're about to delete are all created by Consul and not
created by another user with the word `consul`.
```shell-session
$ kubectl get serviceaccount consul-tls-init
NAME SECRETS AGE
consul-tls-init 1 47m
```
```shell-session
$ kubectl get secret | grep consul | grep Opaque | awk '{print $1}' | xargs kubectl delete secret
secret "consul-acl-replication-acl-token" deleted
secret "consul-bootstrap-acl-token" deleted
secret "consul-client-acl-token" deleted
secret "consul-connect-inject-acl-token" deleted
secret "consul-controller-acl-token" deleted
secret "consul-federation" deleted
secret "consul-mesh-gateway-acl-token" deleted
secret "consul-gossip-encryption-key" deleted
```
```shell-session
$ kubectl delete serviceaccount consul-tls-init
serviceaccount "consul-tls-init" deleted
```
1. If installing with `tls.enabled` then, run the following commands to delete the `ServiceAccount` left behind:
```shell-session
$ kubectl get serviceaccount consul-tls-init
NAME SECRETS AGE
consul-tls-init 1 47m
```
```shell-session
$ kubectl delete serviceaccount consul-tls-init
serviceaccount "consul-tls-init" deleted
```
## Consul K8s CLI
Issue the `consul-k8s uninstall` command to remove Consul on Kubernetes. You can specify the installation name, namespace, and data retention behavior using the applicable options. By default, the uninstallation preserves the secrets and PVCs that are provisioned by Consul on Kubernetes.
```shell-session
$ consul-k8s uninstall <OPTIONS>
```
In the following example, Consul will be uninstalled and the data removed without prompting you to verify the operations:
```shell-session
$ consul-k8s uninstall -auto-approve=true -wipe-data=true
```
Refer to the [Consul K8s CLI reference](/docs/k8s/k8s-cli#uninstall) topic for details.

View File

@ -2,11 +2,12 @@ export const ALERT_BANNER_ACTIVE = true
// https://github.com/hashicorp/web-components/tree/master/packages/alert-banner
export default {
tag: 'Event',
url: 'https://hashiconf.com/global/?utm_campaign=22Q3_WW_HASHICONFGLOBAL_EVENT-USER&utm_source=CorpBanner&utm_medium=EVT&utm_offer=EVENT-USER',
text: 'Join us for HashiConf Global - product updates, technical sessions, workshops & more',
linkText: 'Register now',
tag: 'Oct 19-21',
url:
'https://hashiconf.com/global/?utm_campaign=22Q3_WW_HASHICONFGLOBAL_EVENT-USER&utm_source=CorpBanner&utm_medium=EVT&utm_offer=EVENT-USER',
text: 'The countdown to HashiConf Global is on. View the full schedule now.',
linkText: 'View Schedule',
// Set the expirationDate prop with a datetime string (e.g. '2020-01-31T12:00:00-07:00')
// if you'd like the component to stop showing at or after a certain date
expirationDate: '2021-10-01T12:00:00-07:00',
expirationDate: '2021-10-19T12:00:00-07:00',
}

View File

@ -359,7 +359,7 @@
"title": "Get Started",
"routes": [
{
"title": "Install with Helm Chart",
"title": "Installing Consul on Kubernetes",
"path": "k8s/installation/install"
},
{
@ -552,6 +552,10 @@
{
"title": "Helm Chart Configuration",
"path": "k8s/helm"
},
{
"title": "Consul K8s CLI Reference",
"path": "k8s/k8s-cli"
}
]
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 414 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

View File

@ -0,0 +1,783 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="280.90906mm"
height="186.34019mm"
viewBox="0 0 280.90906 186.34019"
version="1.1"
id="svg88127"
sodipodi:docname="consul-network-segments-multiple.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview140"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.78514107"
inkscape:cx="311.40901"
inkscape:cy="430.49589"
inkscape:window-width="1920"
inkscape:window-height="986"
inkscape:window-x="-11"
inkscape:window-y="1066"
inkscape:window-maximized="1"
inkscape:current-layer="svg88127" />
<defs
id="defs88124" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#d2d4db;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
id="rect79523-0"
width="279.90906"
height="185.34019"
x="0.50000042"
y="0.5"
rx="0.75959074"
ry="0.75959074" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 194.76786,47.305395 c -50.54431,45.34622 -77.75005,4.57881 -88.50161,-0.6547"
id="path2951-8-2-4-5-6-5-5" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 204.97298,46.768285 c -11.40091,18.81636 -61.96028,16.58689 -89.8412,-0.40284"
id="path2951-8-2-4-5-6-5-6-9" />
<g
id="g77638"
transform="translate(-271.24368,-366.15677)">
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-1-4"
width="31.143223"
height="30.383631"
x="379.2648"
y="517.2453"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-7-8"
cx="386.64767"
cy="539.23132"
r="2.551281" />
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-4-2-4"
width="31.143223"
height="30.383631"
x="432.97595"
y="517.2453"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-5-6-7"
cx="440.35886"
cy="539.23132"
r="2.551281" />
</g>
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 84.916047,102.20382 96.869967,46.902565"
id="path2951-2-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 84.916047,119.39197 96.869967,46.902565"
id="path2951-87-9-6" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 84.916047,102.20382 141.82869,35.409955"
id="path2951-8-90-3" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 84.916047,102.20382 186.71117,47.305395"
id="path2951-8-9-3-2" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 84.916047,119.39197 186.71117,47.305395"
id="path2951-8-9-6-6-7" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 106.26625,46.650695 161.73227,151.08853"
id="path2951-8-9-0-2-7-5-8-6" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 150.42248,35.409955 161.73227,151.08853"
id="path2951-8-9-0-2-7-5-7-3-8" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 194.76786,47.305395 161.73227,151.08853"
id="path2951-8-9-0-2-7-5-7-8-5-7" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 106.26625,46.650695 139.16434,151.08853"
id="path2951-8-9-0-2-7-2-7-1-7" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 150.42248,35.409955 139.16434,151.08853"
id="path2951-8-9-0-2-7-2-7-9-5-29" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 150.42248,35.409955 c -11.73908,19.40908 -27.77893,19.30419 -44.15623,11.24074"
id="path2951-8-9-0-2-7-2-7-9-5-2-0" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 150.7459,35.393265 c 11.73908,19.40908 27.64466,19.97558 44.02196,11.91213"
id="path2951-8-9-0-2-7-2-7-9-5-2-8-5" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 160.89616,35.007125 c 13.93242,16.39323 28.11752,19.24986 44.07682,11.76116"
id="path2951-8-9-0-2-7-2-7-9-5-2-8-7-5" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 160.89616,35.007125 c -11.73908,19.40908 -28.71569,20.09316 -45.09299,12.02971"
id="path2951-8-9-0-2-7-2-7-9-5-2-8-7-8-4" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 194.76786,47.305395 139.16434,151.08853"
id="path2951-8-9-0-2-7-2-7-9-4-74-8" />
<path
style="fill:none;stroke:#ffc05b;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 161.73227,151.08853 H 139.16434"
id="path2951-8-9-0-2-7-2-7-9-4-7-3-5-2" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.26261,102.40417 204.97298,46.768285"
id="path2951-7-1-4" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.44348,119.39196 204.97298,46.768285"
id="path2951-7-1-0-91" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 160.89616,35.007125 54.54732,84.384835"
id="path2951-7-1-0-9-4" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.44348,119.39197 V 102.20382"
id="path2951-7-4-4-3" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.44348,119.39196 115.80317,47.036835"
id="path2951-8-2-6-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.71117,47.305395 c -29.99232,15.40662 -65.55301,18.27741 -89.841203,-0.40283"
id="path2951-8-2-4-5-6-9" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 96.869967,46.902565 c 19.494283,5.78072 28.945213,4.43732 44.958723,-11.49261"
id="path2951-8-2-4-2-7-9" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.71117,47.305395 c -19.64434,6.15586 -30.07885,7.27142 -44.95872,-11.49261"
id="path2951-8-2-4-2-7-8-1" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.26261,102.40417 115.80317,47.036835"
id="path2951-8-9-9-3-0" />
<path
style="fill:none;stroke:#7a95ff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 215.44348,102.20382 160.89616,35.007125"
id="path2951-8-9-9-3-5-3" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 84.916047,102.20382 v 17.18815"
id="path2951-8-9-0-2-7-2-6-6-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 141.82869,35.409955 84.916047,119.39197"
id="path2951-8-9-0-2-7-2-6-7-6-5" />
<rect
style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.800685;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect64860-4-0"
width="27.802698"
height="13.036117"
x="87.290443"
y="87.505371" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="101.0126"
y="92.637543"
id="text13642-47-9-7"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke-width:0.109038"
x="101.0126"
y="92.637543"
id="tspan3647-47-8-4">&lt;DEFAULT&gt;</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke-width:0.109038"
x="101.0126"
y="98.089417"
id="tspan59522-5-4">SEGMENT</tspan></text>
<rect
style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.800685;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect64860-4-2-4"
width="27.802698"
height="13.036117"
x="135.84164"
y="104.40628" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#ad6a00;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="149.56381"
y="110.06134"
id="text13642-47-9-8-7"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#ad6a00;fill-opacity:1;stroke-width:0.109038"
x="149.56381"
y="110.06134"
id="tspan3647-47-8-0-6">ALPHA</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#ad6a00;fill-opacity:1;stroke-width:0.109038"
x="149.56381"
y="115.51321"
id="tspan59522-5-9-19">SEGMENT</tspan></text>
<rect
style="opacity:0.75;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.800685;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect64860-4-2-1-8"
width="27.802698"
height="13.036117"
x="183.88577"
y="87.505371" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#0026bc;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="197.60794"
y="93.160431"
id="text13642-47-9-8-6-5"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#0026bc;fill-opacity:1;stroke-width:0.109038"
x="197.60794"
y="93.160431"
id="tspan3647-47-8-0-5-8">BETA</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#0026bc;fill-opacity:1;stroke-width:0.109038"
x="197.60794"
y="98.612305"
id="tspan59522-5-9-1-2">SEGMENT</tspan></text>
<path
style="opacity:0.5;fill:none;stroke:#ca2171;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1"
d="M 0.469407,57.554075 H 280.18871"
id="path12070-8-3" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#eb88b7;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="12.758301"
y="53.198151"
id="text13642-2-4"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#eb88b7;fill-opacity:1;stroke-width:0.109038"
x="12.758301"
y="53.198151"
id="tspan3647-1-9">SERVER AGENTS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#b6b8c2;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="15.013611"
y="11.064087"
id="text13642-2-8-5"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#b6b8c2;fill-opacity:1;stroke-width:0.109038"
x="15.013611"
y="11.064087"
id="tspan3647-1-2-8">DATACENTER 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#eb88b7;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="12.867432"
y="65.039307"
id="text13642-6-9-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#eb88b7;fill-opacity:1;stroke-width:0.109038"
x="12.867432"
y="65.039307"
id="tspan3647-3-8-6">CLIENT AGENTS</tspan></text>
<g
style="fill:none"
id="g80108-6"
transform="matrix(0.26458333,0,0,0.26458333,2.637777,7.6231848)">
<path
d="m 36.335395,-0.44087498 -8.3684,-4.25171002 c -0.4336,-0.218042 -0.9109,-0.33148 -1.3947,-0.33148 -0.4838,0 -0.9611,0.113438 -1.3947,0.33148 l -8.36839,4.25171002 c -0.5215,0.2636 -0.960296,0.66974 -1.267112,1.17282 C 15.235276,1.235035 15.072672,1.815115 15.072448,2.406975 v 10.10786 c -0.0075,0.5953 0.150256,1.1807 0.455109,1.6891 0.304852,0.5084 0.744508,0.9192 1.268558,1.1855 l 8.36828,4.2517 c 0.4354,0.2202 0.915,0.3348 1.4013,0.3348 0.4863,0 0.966,-0.1146 1.4013,-0.3348 l 8.3684,-4.2517 c 0.5215,-0.2636 0.9603,-0.6698 1.2671,-1.1729 0.3068,-0.503 0.4695,-1.0831 0.4697,-1.675 V 2.406975 c -2e-4,-0.59186 -0.1629,-1.17194 -0.4697,-1.67502998 -0.3068,-0.50308 -0.7456,-0.90922 -1.2671,-1.17282 z M 26.098595,-2.740555 c 0.1412,-0.0784 0.2996,-0.11951 0.4606,-0.11951 0.1609,0 0.3192,0.04111 0.4604,0.11951 l 7.6447,3.87735 -2.8816,1.47072 -8.1051,-4.11799 z m 0.4606,8.02209 -8.10527,-4.11798 2.88155,-1.47071998 8.11842,4.13137998 z m -8.82893,8.2762 c -0.17618,-0.0885 -0.32405,-0.2258 -0.42652,-0.3962 -0.10247,-0.1704 -0.15534,-0.3668 -0.15243,-0.5665 v -9.70675 l 8.36838,4.23835 v 10.3886 z m 17.65773,0 -7.7894,3.9442 v -10.3753 l 8.3683,-4.23835 v 9.72015 c -0.0127,0.1855 -0.0727,0.3645 -0.1742,0.5192 -0.1015,0.1548 -0.241,0.28 -0.4047,0.3632 z"
fill="#b3b6c3"
id="path80099-8" />
</g>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-3-2-3"
width="31.143223"
height="30.383631"
x="91.37381"
y="16.653198"
rx="0.94948852"
ry="0.94948852" />
<g
id="g51357-7"
transform="matrix(0.75411024,0,0,0.75411024,-122.58066,-1.3109452)">
<g
id="g10468-1-54"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-0"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-1"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-8"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-1"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-7"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-9"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-78"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-94"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-0"
style="stroke-width:0.446569" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:0.6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="45.360958"
y="94.897339"
id="text13642-4-5-7-8"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:0.6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="45.360958"
y="94.897339"
id="tspan3647-7-9-8-0">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="53.128521"
y="100.98047"
id="text13642-4-5-7-6-0-8"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="53.128521"
y="100.98047"
id="tspan3647-7-9-8-0-3-7">8303</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="59.677105"
y="107.08105"
id="text13642-4-5-7-6-0-2-61"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="59.677105"
y="107.08105"
id="tspan3647-7-9-8-0-3-6-4">8304</tspan></text>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-5-1"
width="31.143223"
height="30.383631"
x="135.28271"
y="5.0115356"
rx="0.94948852"
ry="0.94948852" />
<g
style="fill:none"
id="g10621-7-4"
transform="matrix(0.26458333,0,0,0.26458333,139.9985,17.880375)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 9.99992,0.833252 2.83248,5.738338 6.3342,0.92583 -4.5833,4.46418 1.0816,6.3067 -5.66498,-2.9792 -5.665,2.9792 L 5.41659,11.9616 0.833252,7.49742 7.16742,6.57159 Z"
fill="#ffffff"
id="path10612-9-2" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.91279px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0978204"
x="146.39545"
y="21.809692"
id="text13642-0-6-2"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffffff;fill-opacity:1;stroke-width:0.0978204"
x="146.39545"
y="21.809692"
id="tspan3647-4-8-6">LEADER</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="86.593102"
y="113.20019"
id="text13642-4-5-7-6-9"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="86.593102"
y="113.20019"
id="tspan3647-7-9-8-1-9">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="94.360672"
y="119.28332"
id="text13642-4-5-7-6-0-27-2"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="94.360672"
y="119.28332"
id="tspan3647-7-9-8-0-3-0-9">8303</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="100.90926"
y="125.3839"
id="text13642-4-5-7-6-0-2-7-0"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="100.90926"
y="125.3839"
id="tspan3647-7-9-8-0-3-6-6-7">8304</tspan></text>
<g
id="g51357-1-1"
transform="matrix(0.75411024,0,0,0.75411024,-78.023773,-13.412435)">
<g
id="g10468-1-1-8"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-7-9"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-6-9"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-3-6"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-4-0"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-9-6"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-4-2"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-7-1"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-9-15"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-6-4"
style="stroke-width:0.446569" />
</g>
</g>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-9-7-3"
width="31.143223"
height="30.383631"
x="179.19159"
y="16.653198"
rx="0.94948852"
ry="0.94948852" />
<g
id="g51357-1-5-0"
transform="matrix(0.75411024,0,0,0.75411024,-34.517713,-1.7302552)">
<g
id="g10468-1-1-3-0"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-7-4-6"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-6-6-7"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-3-9-6"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-4-6-0"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-9-8-4"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-4-5-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-7-4-8"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-9-1-4"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-6-7-2"
style="stroke-width:0.446569" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="113.62766"
y="149.61034"
id="text13642-4-5-7-2-1"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="113.62766"
y="149.61034"
id="tspan3647-7-9-8-6-4">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="121.3952"
y="155.69353"
id="text13642-4-5-7-6-0-1-2"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffefd6;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="121.3952"
y="155.69353"
id="tspan3647-7-9-8-0-3-8-7">8303</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="127.94379"
y="161.79411"
id="text13642-4-5-7-6-0-2-6-2"
transform="rotate(-38.712751)"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#bccaff;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="127.94379"
y="161.79411"
id="tspan3647-7-9-8-0-3-6-2-9">8304</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-4-6-5"
width="31.143223"
height="30.383631"
x="215.44345"
y="71.82019"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-87-2-2"
cx="222.82635"
cy="93.806183"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#7a95ff;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="217.08047"
y="100.77832"
id="text13642-4-8-6-8-3-7-4-7"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#7a95ff;fill-opacity:1;stroke-width:0.109038"
x="217.08047"
y="100.77832"
id="tspan3647-7-99-1-2-8-1-5-7">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-4-0-2-5"
width="31.143223"
height="30.383631"
x="215.44345"
y="119.39196"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-5-1-9-1"
cx="222.82635"
cy="141.37796"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#7a95ff;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="217.08047"
y="124.5455"
id="text13642-4-8-6-8-3-1-2"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#7a95ff;fill-opacity:1;stroke-width:0.109038"
x="217.08047"
y="124.5455"
id="tspan3647-7-99-1-2-8-4-4">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffc05b;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="163.50357"
y="155.80975"
id="text13642-4-8-6-8-0-6"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffc05b;fill-opacity:1;stroke-width:0.109038"
x="163.50357"
y="155.80975"
id="tspan3647-7-99-1-2-3-4">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffc05b;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="128.0542"
y="156.20465"
id="text13642-4-8-6-2-1"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffc05b;fill-opacity:1;stroke-width:0.109038"
x="128.0542"
y="156.20465"
id="tspan3647-7-99-1-4-0">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-42-9"
width="31.143223"
height="30.383631"
x="53.772823"
y="119.39196"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-1-7"
cx="61.155697"
cy="141.37796"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="73.671631"
y="124.5455"
id="text13642-4-8-9-2"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="73.671631"
y="124.5455"
id="tspan3647-7-99-3-7">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-2-2"
width="31.143223"
height="30.383631"
x="53.772823"
y="71.82019"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-4-8"
cx="61.155697"
cy="93.806183"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="73.143982"
y="100.30142"
id="text13642-4-0-6"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="73.143982"
y="100.30142"
id="tspan3647-7-3-7">8301</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

View File

@ -0,0 +1,673 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="280.90906mm"
height="186.34019mm"
viewBox="0 0 280.90906 186.34019"
version="1.1"
id="svg86623"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs86620" />
<g
id="layer1"
transform="translate(2.5887995,11.893881)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#d2d4db;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
id="rect79523"
width="279.90906"
height="185.34019"
x="-2.0887995"
y="-11.393881"
rx="0.75959074"
ry="0.75959074" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,89.78079 119.34239,34.61381"
id="path2951-75" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,106.96894 119.34239,34.61381"
id="path2951-87-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,89.78079 147.2478,22.98692"
id="path2951-8-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,89.78079 176.01693,34.61381"
id="path2951-8-9-02" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,106.96894 176.01693,34.61381"
id="path2951-8-9-6-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 81.74137,89.78079 H 212.2688"
id="path2951-8-9-0-0" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 81.74137,89.78079 129.99032,17.18815"
id="path2951-8-9-0-2-5" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 81.74137,89.78079 76.81624,48.88482"
id="path2951-8-9-0-2-7-0" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 119.34239,34.61381 39.21522,104.0518"
id="path2951-8-9-0-2-7-5-3" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 147.2478,22.98692 11.30981,115.67869"
id="path2951-8-9-0-2-7-5-7-85" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 176.01693,34.61381 -17.45932,104.0518"
id="path2951-8-9-0-2-7-5-7-8-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 211.73169,106.96894 -53.17408,31.69657"
id="path2951-8-9-0-2-7-5-7-8-0-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 81.74137,89.78079 54.2483,48.88482"
id="path2951-8-9-0-2-7-2-66" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 119.34239,34.61381 16.64727,104.0517"
id="path2951-8-9-0-2-7-2-7-3" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 147.2478,22.98692 135.98966,138.66551"
id="path2951-8-9-0-2-7-2-7-9-55" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 176.01693,34.61381 -40.02727,104.0517"
id="path2951-8-9-0-2-7-2-7-9-4-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 211.73169,106.96894 -75.74203,31.69657"
id="path2951-8-9-0-2-7-2-7-9-4-7-6" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 158.55761,138.66561 H 135.98967"
id="path2951-8-9-0-2-7-2-7-9-4-7-3-9" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 212.08793,89.98114 -36.071,-55.36733"
id="path2951-7-18" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.2688,106.96894 V 89.78079"
id="path2951-7-4-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.08793,89.98114 147.2478,22.98692"
id="path2951-8-2-8" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 147.2478,22.98692 119.34239,34.61381"
id="path2951-8-2-4-1" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 176.01693,34.61381 H 119.34239"
id="path2951-8-2-4-5-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 176.01693,34.61381 147.2478,22.98692"
id="path2951-8-2-4-2-77" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.08793,89.98114 119.34239,34.61381"
id="path2951-8-9-9-30" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.2688,106.96894 176.01693,34.61381"
id="path2951-8-9-9-37-2" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.2688,106.96894 147.2478,22.98692"
id="path2951-8-9-9-37-8-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.2688,106.96894 119.34239,34.61381"
id="path2951-8-9-9-37-8-8-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.08793,89.98114 81.74137,106.96894"
id="path2951-8-9-0-2-2-4" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 212.2688,106.96894 H 81.741372"
id="path2951-8-9-0-2-2-6-9" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 158.55761,138.66561 81.74137,106.96894"
id="path2951-8-9-0-2-2-6-6-2" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 135.98966,138.66551 81.741372,106.96894"
id="path2951-8-9-0-2-2-6-6-8-7" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 212.08793,89.98114 -76.09827,48.68437"
id="path2951-8-9-0-2-7-8-0" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 212.08793,89.98114 -53.53032,48.68437"
id="path2951-8-9-0-2-7-2-64-3" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 81.74137,89.78079 v 17.18815"
id="path2951-8-9-0-2-7-2-6-66" />
<path
style="fill:none;stroke:#9194a0;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 147.2478,22.98692 81.74137,106.96894"
id="path2951-8-9-0-2-7-2-6-7-69" />
<path
style="opacity:0.5;fill:none;stroke:#ca2171;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1"
d="M -2.119385,45.66021 H 277.59992"
id="path12070-8" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#eb88b7;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="10.169486"
y="41.304272"
id="text13642-2"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#eb88b7;fill-opacity:1;stroke-width:0.109038"
x="10.169486"
y="41.304272"
id="tspan3647-1">SERVER AGENTS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#b6b8c2;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="12.424808"
y="-0.82979363"
id="text13642-2-8"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#b6b8c2;fill-opacity:1;stroke-width:0.109038"
x="12.424808"
y="-0.82979363"
id="tspan3647-1-2">DATACENTER 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#eb88b7;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="10.278636"
y="53.145428"
id="text13642-6-9"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#eb88b7;fill-opacity:1;stroke-width:0.109038"
x="10.278636"
y="53.145428"
id="tspan3647-3-8">CLIENT AGENTS</tspan></text>
<rect
style="opacity:0.85;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.877;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect64860-9"
width="33.355167"
height="13.036117"
x="129.60806"
y="91.852638" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="146.19716"
y="97.507668"
id="text13642-47-6"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke-width:0.109038"
x="146.19716"
y="97.507668"
id="tspan3647-47-7">&lt;DEFAULT&gt;</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:center;text-anchor:middle;fill:#464851;fill-opacity:1;stroke-width:0.109038"
x="146.19716"
y="102.95954"
id="tspan59522-6">SEGMENT</tspan></text>
<g
style="fill:none"
id="g80108"
transform="matrix(0.26458333,0,0,0.26458333,0.048985,-4.27068)">
<path
d="m 36.335395,-0.44087498 -8.3684,-4.25171002 c -0.4336,-0.218042 -0.9109,-0.33148 -1.3947,-0.33148 -0.4838,0 -0.9611,0.113438 -1.3947,0.33148 l -8.36839,4.25171002 c -0.5215,0.2636 -0.960296,0.66974 -1.267112,1.17282 C 15.235276,1.235035 15.072672,1.815115 15.072448,2.406975 v 10.10786 c -0.0075,0.5953 0.150256,1.1807 0.455109,1.6891 0.304852,0.5084 0.744508,0.9192 1.268558,1.1855 l 8.36828,4.2517 c 0.4354,0.2202 0.915,0.3348 1.4013,0.3348 0.4863,0 0.966,-0.1146 1.4013,-0.3348 l 8.3684,-4.2517 c 0.5215,-0.2636 0.9603,-0.6698 1.2671,-1.1729 0.3068,-0.503 0.4695,-1.0831 0.4697,-1.675 V 2.406975 c -2e-4,-0.59186 -0.1629,-1.17194 -0.4697,-1.67502998 -0.3068,-0.50308 -0.7456,-0.90922 -1.2671,-1.17282 z M 26.098595,-2.740555 c 0.1412,-0.0784 0.2996,-0.11951 0.4606,-0.11951 0.1609,0 0.3192,0.04111 0.4604,0.11951 l 7.6447,3.87735 -2.8816,1.47072 -8.1051,-4.11799 z m 0.4606,8.02209 -8.10527,-4.11798 2.88155,-1.47071998 8.11842,4.13137998 z m -8.82893,8.2762 c -0.17618,-0.0885 -0.32405,-0.2258 -0.42652,-0.3962 -0.10247,-0.1704 -0.15534,-0.3668 -0.15243,-0.5665 v -9.70675 l 8.36838,4.23835 v 10.3886 z m 17.65773,0 -7.7894,3.9442 v -10.3753 l 8.3683,-4.23835 v 9.72015 c -0.0127,0.1855 -0.0727,0.3645 -0.1742,0.5192 -0.1015,0.1548 -0.241,0.28 -0.4047,0.3632 z"
fill="#b3b6c3"
id="path80099" />
</g>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-4-1"
width="31.143223"
height="30.383631"
x="212.26878"
y="59.397167"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-87-1"
cx="219.65167"
cy="81.383156"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="213.86339"
y="88.31266"
id="text13642-4-8-6-8-3-7-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="213.86339"
y="88.31266"
id="tspan3647-7-99-1-2-8-1-8">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-4-0-6"
width="31.143223"
height="30.383631"
x="212.26878"
y="106.96897"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-5-1-7"
cx="219.65167"
cy="128.95494"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="213.86339"
y="112.07981"
id="text13642-4-8-6-8-3-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="213.86339"
y="112.07981"
id="tspan3647-7-99-1-2-8-6">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-4-4"
width="31.143223"
height="30.383631"
x="158.5576"
y="138.66551"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-5-8"
cx="165.94046"
cy="160.65144"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="160.2865"
y="143.3441"
id="text13642-4-8-6-8-2"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="160.2865"
y="143.3441"
id="tspan3647-7-99-1-2-4">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-4-7"
width="31.143223"
height="30.383631"
x="104.84644"
y="138.66551"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-2-9"
cx="112.22933"
cy="160.65144"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="124.83712"
y="143.739"
id="text13642-4-8-6-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="124.83712"
y="143.739"
id="tspan3647-7-99-1-3">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-8-6"
width="31.143223"
height="30.383631"
x="50.598148"
y="106.96897"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-8-20"
cx="57.981041"
cy="128.95494"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="70.454552"
y="112.07981"
id="text13642-4-8-7"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="70.454552"
y="112.07981"
id="tspan3647-7-99-5">8301</tspan></text>
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ca2171;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect53-8-1"
width="31.143223"
height="30.383631"
x="50.598148"
y="59.397167"
rx="0.94948852"
ry="0.94948852" />
<circle
style="fill:#ca2171;fill-opacity:1;stroke:none;stroke-width:0.826087;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path1524-2"
cx="57.981041"
cy="81.383156"
r="2.551281" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#9194a0;fill-opacity:1;stroke:none;stroke-width:0.109038"
x="69.926926"
y="87.835732"
id="text13642-4-4"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#9194a0;fill-opacity:1;stroke-width:0.109038"
x="69.926926"
y="87.835732"
id="tspan3647-7-1">8301</tspan></text>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-3-24"
width="31.143223"
height="30.383631"
x="88.199158"
y="4.2302041"
rx="0.94948852"
ry="0.94948852" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="108.05689"
y="32.638592"
id="text13642-4-5-1"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="108.05689"
y="32.638592"
id="tspan3647-7-9-53">8301</tspan></text>
<g
id="g51357-6-0"
transform="matrix(0.75411024,0,0,0.75411024,-125.21777,-13.87572)">
<g
id="g10468-1-5-02"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-6-0"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-8-7"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-5-5"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-5-6"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-0-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-46-55"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-8-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-5-95"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-4-4"
style="stroke-width:0.446569" />
</g>
</g>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-2"
width="31.143223"
height="30.383631"
x="132.10803"
y="-7.411489"
rx="0.94948852"
ry="0.94948852" />
<g
style="fill:none"
id="g10621-1"
transform="matrix(0.26458333,0,0,0.26458333,136.82381,5.98651)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 9.99992,0.833252 2.83248,5.738338 6.3342,0.92583 -4.5833,4.46418 1.0816,6.3067 -5.66498,-2.9792 -5.665,2.9792 L 5.41659,11.9616 0.833252,7.49742 7.16742,6.57159 Z"
fill="#ffffff"
id="path10612-0" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="142.42754"
y="21.173655"
id="text13642-4-5-2-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="142.42754"
y="21.173655"
id="tspan3647-7-9-5-5">8301</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.91279px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0978204"
x="143.22075"
y="9.9158421"
id="text13642-0-68"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#ffffff;fill-opacity:1;stroke-width:0.0978204"
x="143.22075"
y="9.9158421"
id="tspan3647-4-5">LEADER</tspan></text>
<g
id="g51357-6-3-9"
transform="matrix(0.75411024,0,0,0.75411024,-81.308881,-25.51739)">
<g
id="g10468-1-5-0-69"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-6-2-64"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-8-4-5"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-5-8-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-5-8-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-0-5-75"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-46-5-5"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-8-8-8"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-5-9-4"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-4-5-0"
style="stroke-width:0.446569" />
</g>
</g>
<rect
style="fill:#ca2171;fill-opacity:1;fill-rule:evenodd;stroke-width:0.264583"
id="rect53-2-9-74"
width="31.143223"
height="30.383631"
x="176.01692"
y="4.2302041"
rx="0.94948852"
ry="0.94948852" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.3615px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="177.87691"
y="32.318737"
id="text13642-4-5-2-9-3"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';fill:#e3e4e7;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
x="177.87691"
y="32.318737"
id="tspan3647-7-9-5-7-5">8301</tspan></text>
<g
id="g51357-6-3-6-1"
transform="matrix(0.75411024,0,0,0.75411024,-37.399986,-13.87572)">
<g
id="g10468-1-5-0-6-7"
transform="translate(255.49561,0.52274421)">
<path
opacity="0.7"
fill-rule="evenodd"
clip-rule="evenodd"
d="m 60.894465,32.634214 c -0.210334,7.14e-4 -0.416158,-0.06114 -0.591257,-0.17769 -0.1751,-0.116554 -0.311616,-0.282544 -0.392087,-0.476891 -0.08047,-0.194346 -0.101371,-0.408253 -0.05993,-0.614478 0.0414,-0.206225 0.143215,-0.395481 0.292503,-0.543697 0.149287,-0.148216 0.339302,-0.24865 0.545796,-0.288573 0.206538,-0.03992 0.42031,-0.0175 0.614032,0.0644 0.193766,0.0819 0.358773,0.219623 0.474077,0.395571 0.115259,0.175948 0.175591,0.382218 0.173313,0.592552 5.36e-4,0.13924 -0.02639,0.277185 -0.07922,0.40602 -0.05283,0.128835 -0.130488,0.246014 -0.228599,0.34484 -0.09811,0.09878 -0.21471,0.177332 -0.343143,0.231055 -0.128478,0.05377 -0.266244,0.08168 -0.405484,0.08217"
fill="#ffffff"
id="path1013-1-9-2-6-2-6-4"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 62.957478,32.063678 c -0.0974,-4.5e-5 -0.192561,-0.02907 -0.27339,-0.08342 -0.08078,-0.05439 -0.143571,-0.131604 -0.180279,-0.221766 -0.03671,-0.09021 -0.04573,-0.189301 -0.02586,-0.284643 0.01983,-0.09534 0.06766,-0.182602 0.13732,-0.250659 0.06967,-0.06801 0.158041,-0.113786 0.25383,-0.131336 0.09579,-0.0176 0.194659,-0.0063 0.283928,0.0326 0.08931,0.03885 0.165007,0.103426 0.217434,0.185505 0.05243,0.08208 0.07922,0.177913 0.07694,0.275265 0,0.129951 -0.05162,0.254544 -0.143482,0.346448 -0.0919,0.09186 -0.216541,0.143482 -0.346448,0.143482"
fill="#ffffff"
id="path1015-4-5-7-8-4-3-0"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.744511,32.523241 c -0.005,0.118028 -0.05604,0.229403 -0.142187,0.310232 -0.08614,0.08083 -0.200509,0.124682 -0.318627,0.122181 -0.118117,-0.0025 -0.230563,-0.05118 -0.313178,-0.135578 -0.08266,-0.0844 -0.128925,-0.19783 -0.128925,-0.315992 0,-0.118118 0.04626,-0.231546 0.128925,-0.315992 0.08261,-0.0844 0.195061,-0.133078 0.313178,-0.135579 0.118118,-0.0025 0.232484,0.04135 0.318627,0.122226 0.08614,0.08083 0.137186,0.192203 0.142187,0.310231 0.0012,0.01273 0.0012,0.02554 0,0.03827 z"
fill="#ffffff"
id="path1017-9-5-43-5-8-5-5"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 64.40043,31.263918 c -0.09449,0.01867 -0.192381,0.0091 -0.281427,-0.0276 -0.08905,-0.03666 -0.16532,-0.09874 -0.21931,-0.178494 -0.05395,-0.07976 -0.08324,-0.173625 -0.08413,-0.269906 -9.37e-4,-0.09632 0.02657,-0.190729 0.079,-0.271513 0.05247,-0.08074 0.12754,-0.144287 0.215872,-0.182602 0.08833,-0.03836 0.185995,-0.04979 0.280847,-0.03296 0.09481,0.01688 0.182557,0.06131 0.252222,0.127719 0.06971,0.06645 0.118296,0.151967 0.139686,0.24588 0.01143,0.06328 0.01143,0.128076 0,0.191355 -0.01666,0.09543 -0.06234,0.183406 -0.130844,0.251909 -0.0685,0.0685 -0.156478,0.114233 -0.25191,0.13089"
fill="#ffffff"
id="path1019-7-1-0-5-8-6-5"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 66.138699,32.470278 c -0.02233,0.127406 -0.09436,0.240745 -0.200242,0.31501 -0.105881,0.07431 -0.236949,0.103514 -0.364355,0.08119 -0.127406,-0.02233 -0.240701,-0.09436 -0.31501,-0.200241 -0.07431,-0.105882 -0.103514,-0.23695 -0.08114,-0.364356 0.01192,-0.06243 0.03604,-0.121824 0.071,-0.174876 0.03497,-0.05305 0.08003,-0.09869 0.132676,-0.134239 0.05265,-0.03559 0.111776,-0.06038 0.174072,-0.07301 0.06225,-0.01264 0.126379,-0.01286 0.18872,-6.7e-4 0.12035,0.02063 0.228643,0.08543 0.303667,0.181708 0.07507,0.09633 0.111463,0.217167 0.102085,0.338857 -0.0022,0.01527 -0.0022,0.03072 0,0.04595"
fill="#ffffff"
id="path1021-1-7-8-0-5-7-3"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.744334,31.241232 c -0.09485,0.01916 -0.19323,0.0096 -0.282589,-0.02746 -0.08936,-0.03707 -0.165632,-0.09999 -0.219042,-0.180637 -0.05345,-0.0807 -0.08154,-0.175457 -0.08078,-0.272183 7.59e-4,-0.09677 0.03037,-0.191087 0.08503,-0.270889 0.05466,-0.07985 0.131916,-0.141518 0.221855,-0.177198 0.08994,-0.03568 0.188452,-0.04368 0.282991,-0.02304 0.09449,0.02068 0.180726,0.06908 0.247577,0.138972 0.06685,0.06993 0.11133,0.158264 0.127719,0.253606 0.0039,0.04202 0.0039,0.08427 0,0.12629 -0.01041,0.106774 -0.05587,0.207074 -0.129282,0.285312 -0.07337,0.07824 -0.170589,0.129997 -0.276426,0.147234"
fill="#ffffff"
id="path1023-5-7-9-46-5-7-4"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.399672,34.161657 c -0.05926,0.105301 -0.155406,0.185013 -0.269906,0.223775 -0.1145,0.03872 -0.239271,0.03381 -0.350378,-0.01389 -0.111061,-0.04769 -0.200554,-0.134774 -0.251328,-0.244496 -0.05078,-0.109677 -0.05917,-0.23427 -0.02362,-0.349797 0.03555,-0.115528 0.112535,-0.213862 0.216184,-0.276069 0.103649,-0.06216 0.226634,-0.08387 0.345331,-0.06087 0.118654,0.023 0.224625,0.08904 0.297549,0.18546 0.07292,0.09641 0.107623,0.216362 0.09744,0.336846 -0.0017,0.07069 -0.02286,0.139598 -0.06127,0.199036 z"
fill="#ffffff"
id="path1025-5-86-6-8-8-3-1"
style="stroke-width:0.446569" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="m 65.22301,29.671454 c -0.112804,0.06355 -0.246149,0.07994 -0.37092,0.0455 -0.124816,-0.03443 -0.230876,-0.116822 -0.295137,-0.229223 -0.03166,-0.05609 -0.05198,-0.117805 -0.0598,-0.181709 -0.0078,-0.0639 -0.0029,-0.128701 0.01429,-0.190729 0.01724,-0.06203 0.04653,-0.120038 0.08619,-0.170768 0.03965,-0.05069 0.08891,-0.09311 0.145001,-0.124772 0.05604,-0.03166 0.11776,-0.05198 0.181664,-0.0598 0.0639,-0.0078 0.128701,-0.0029 0.190729,0.01429 0.06203,0.01724 0.120038,0.04653 0.170768,0.08619 0.05069,0.03965 0.09311,0.08891 0.124771,0.144956 0.04966,0.08565 0.07109,0.184745 0.06123,0.283259 -0.0073,0.07922 -0.03376,0.15545 -0.07708,0.222167 -0.04336,0.06667 -0.102309,0.121824 -0.171705,0.160631 z"
fill="#ffffff"
id="path1027-5-2-34-5-9-8-4"
style="stroke-width:0.446569" />
<path
d="m 60.913533,36.500917 c -0.782745,0.0037 -1.555041,-0.179565 -2.252626,-0.534632 -0.697585,-0.355022 -1.300274,-0.871523 -1.757917,-1.506543 -0.457644,-0.634976 -0.757023,-1.370118 -0.873176,-2.1442 -0.116152,-0.774037 -0.04577,-1.564642 0.205332,-2.306035 0.251106,-0.741349 0.675614,-1.412006 1.23829,-1.956194 0.562632,-0.544144 1.247088,-0.946056 1.99643,-1.172243 0.749342,-0.226232 1.541868,-0.270174 2.311618,-0.12821 0.76975,0.14192 1.494486,0.465682 2.113833,0.94427 l -0.597107,0.765552 c -0.582326,-0.445765 -1.277723,-0.719734 -2.00755,-0.790962 -0.729871,-0.07127 -1.465147,0.06305 -2.12263,0.3878 -0.657527,0.324745 -1.211094,0.826911 -1.598179,1.449785 -0.387086,0.622829 -0.592195,1.341537 -0.592195,2.074892 0,0.73331 0.205109,1.452062 0.592195,2.074892 0.387085,0.622874 0.940652,1.12504 1.598179,1.449785 0.657483,0.3247 1.392759,0.459028 2.12263,0.3878 0.729827,-0.07123 1.425224,-0.345198 2.00755,-0.790962 l 0.597107,0.784665 c -0.854018,0.658823 -1.903187,1.014381 -2.981784,1.01054 z"
fill="#ffffff"
id="path1029-6-6-2-4-5-4-8"
style="stroke-width:0.446569" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 49 KiB